文章目錄
- 一安裝Vue
- 二 做移動端應用注意
-
- 2.1 在index.html中修改mate設定
- 2.2 reset.css重新設定樣式,在入口檔案中引入
- 2.3 引入border.css 解決一像素邊框的問題
- 2.4 解決click延遲300ms的問題 fastclick插件
- 2.5 在style中引入其他樣式,需要這樣 ~@
- 2.6 對全局事件的解綁
- 2.7 解決麼面滑動影響其他頁面的問題
- 3 插件使用
-
- 3.1 stylus和stylus-loader
- 3.2 輪播圖元件 vue-awesome-swiper
-
- 3.2.1 使用vue代碼
- 3.2.2 swiper自定義圖檔輪播元件
- 3.3 資料請求 axios
- 3.4 頁面跳轉路由
- 3.5 Better-scroll 滾動插件
- 3.6 Vuex實作資料共享
- 3.6 本地存儲 localStorage
- 3.7 keep-alive優化網頁性能
- 3.8 遞歸元件的使用
- 4 樣例
-
- 4.1 頭部漸隐漸現的效果元件
- 4.2 漸影漸現的動畫元件
一安裝Vue
//全局安裝 vue-cli
npm install --global vue-cli
//建立一個基于 webpack 模闆的新項目
vue init webpack my-project
//安裝依賴
cd my-project
npm install
//運作
npm run dev
- 安裝過程中的問題解決
- npm建構儲存 code ELIFECYCLE解決辦法
進入工作目錄
rm -rf node_modules
rm -rf package-lock.json
npm cache clear --force
npm install
二 做移動端應用注意
2.1 在index.html中修改mate設定
<meta name="viewport" content="width=device-width,initial-scale=1.0,
minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
2.2 reset.css重新設定樣式,在入口檔案中引入
@charset "utf-8";html{background-color:#fff;color:#000;font-size:12px}
body,ul,ol,dl,dd,h1,h2,h3,h4,h5,h6,figure,form,fieldset,legend,input,textarea,button,p,blockquote,th,td,pre,xmp{margin:0;padding:0}
body,input,textarea,button,select,pre,xmp,tt,code,kbd,samp{line-height:1.5;font-family:tahoma,arial,"Hiragino Sans GB",simsun,sans-serif}
h1,h2,h3,h4,h5,h6,small,big,input,textarea,button,select{font-size:100%}
h1,h2,h3,h4,h5,h6{font-family:tahoma,arial,"Hiragino Sans GB","微軟雅黑",simsun,sans-serif}
h1,h2,h3,h4,h5,h6,b,strong{font-weight:normal}
address,cite,dfn,em,i,optgroup,var{font-style:normal}
table{border-collapse:collapse;border-spacing:0;text-align:left}
caption,th{text-align:inherit}
ul,ol,menu{list-style:none}
fieldset,img{border:0}
img,object,input,textarea,button,select{vertical-align:middle}
article,aside,footer,header,section,nav,figure,figcaption,hgroup,details,menu{display:block}
audio,canvas,video{display:inline-block;*display:inline;*zoom:1}
blockquote:before,blockquote:after,q:before,q:after{content:"\0020"}
textarea{overflow:auto;resize:vertical}
input,textarea,button,select,a{outline:0 none;border: none;}
button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}
mark{background-color:transparent}
a,ins,s,u,del{text-decoration:none}
sup,sub{vertical-align:baseline}
html {overflow-x: hidden;height: 100%;font-size: 50px;-webkit-tap-highlight-color: transparent;}
body {font-family: Arial, "Microsoft Yahei", "Helvetica Neue", Helvetica, sans-serif;color: #333;font-size: .28em;line-height: 1;-webkit-text-size-adjust: none;}
hr {height: .02rem;margin: .1rem 0;border: medium none;border-top: .02rem solid #cacaca;}
a {color: #25a4bb;text-decoration: none;}
2.3 引入border.css 解決一像素邊框的問題
在入口檔案中引入
@charset "utf-8";
.border,
.border-top,
.border-right,
.border-bottom,
.border-left,
.border-topbottom,
.border-rightleft,
.border-topleft,
.border-rightbottom,
.border-topright,
.border-bottomleft {
position: relative;
}
.border::before,
.border-top::before,
.border-right::before,
.border-bottom::before,
.border-left::before,
.border-topbottom::before,
.border-topbottom::after,
.border-rightleft::before,
.border-rightleft::after,
.border-topleft::before,
.border-topleft::after,
.border-rightbottom::before,
.border-rightbottom::after,
.border-topright::before,
.border-topright::after,
.border-bottomleft::before,
.border-bottomleft::after {
content: "\0020";
overflow: hidden;
position: absolute;
}
/* border
* 因,邊框是由僞元素區域遮蓋在父級
* 故,子級若有互動,需要對子級設定
* 定位 及 z軸
*/
.border::before {
box-sizing: border-box;
top: 0;
left: 0;
height: 100%;
width: 100%;
border: 1px solid #eaeaea;
transform-origin: 0 0;
}
.border-top::before,
.border-bottom::before,
.border-topbottom::before,
.border-topbottom::after,
.border-topleft::before,
.border-rightbottom::after,
.border-topright::before,
.border-bottomleft::before {
left: 0;
width: 100%;
height: 1px;
}
.border-right::before,
.border-left::before,
.border-rightleft::before,
.border-rightleft::after,
.border-topleft::after,
.border-rightbottom::before,
.border-topright::after,
.border-bottomleft::after {
top: 0;
width: 1px;
height: 100%;
}
.border-top::before,
.border-topbottom::before,
.border-topleft::before,
.border-topright::before {
border-top: 1px solid #eaeaea;
transform-origin: 0 0;
}
.border-right::before,
.border-rightbottom::before,
.border-rightleft::before,
.border-topright::after {
border-right: 1px solid #eaeaea;
transform-origin: 100% 0;
}
.border-bottom::before,
.border-topbottom::after,
.border-rightbottom::after,
.border-bottomleft::before {
border-bottom: 1px solid #eaeaea;
transform-origin: 0 100%;
}
.border-left::before,
.border-topleft::after,
.border-rightleft::after,
.border-bottomleft::after {
border-left: 1px solid #eaeaea;
transform-origin: 0 0;
}
.border-top::before,
.border-topbottom::before,
.border-topleft::before,
.border-topright::before {
top: 0;
}
.border-right::before,
.border-rightleft::after,
.border-rightbottom::before,
.border-topright::after {
right: 0;
}
.border-bottom::before,
.border-topbottom::after,
.border-rightbottom::after,
.border-bottomleft::after {
bottom: 0;
}
.border-left::before,
.border-rightleft::before,
.border-topleft::after,
.border-bottomleft::before {
left: 0;
}
@media (max--moz-device-pixel-ratio: 1.49), (-webkit-max-device-pixel-ratio: 1.49), (max-device-pixel-ratio: 1.49), (max-resolution: 143dpi), (max-resolution: 1.49dppx) {
/* 預設值,無需重置 */
}
@media (min--moz-device-pixel-ratio: 1.5) and (max--moz-device-pixel-ratio: 2.49), (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 2.49), (min-device-pixel-ratio: 1.5) and (max-device-pixel-ratio: 2.49), (min-resolution: 144dpi) and (max-resolution: 239dpi), (min-resolution: 1.5dppx) and (max-resolution: 2.49dppx) {
.border::before {
width: 200%;
height: 200%;
transform: scale(.5);
}
.border-top::before,
.border-bottom::before,
.border-topbottom::before,
.border-topbottom::after,
.border-topleft::before,
.border-rightbottom::after,
.border-topright::before,
.border-bottomleft::before {
transform: scaleY(.5);
}
.border-right::before,
.border-left::before,
.border-rightleft::before,
.border-rightleft::after,
.border-topleft::after,
.border-rightbottom::before,
.border-topright::after,
.border-bottomleft::after {
transform: scaleX(.5);
}
}
@media (min--moz-device-pixel-ratio: 2.5), (-webkit-min-device-pixel-ratio: 2.5), (min-device-pixel-ratio: 2.5), (min-resolution: 240dpi), (min-resolution: 2.5dppx) {
.border::before {
width: 300%;
height: 300%;
transform: scale(.33333);
}
.border-top::before,
.border-bottom::before,
.border-topbottom::before,
.border-topbottom::after,
.border-topleft::before,
.border-rightbottom::after,
.border-topright::before,
.border-bottomleft::before {
transform: scaleY(.33333);
}
.border-right::before,
.border-left::before,
.border-rightleft::before,
.border-rightleft::after,
.border-topleft::after,
.border-rightbottom::before,
.border-topright::after,
.border-bottomleft::after {
transform: scaleX(.33333);
}
}
修改裡面邊框顔色的方法可以在樣式中這樣寫
.border-topbottom
&:before
border-color #cccccc
&after
border-color #cccccc
.border-bottom
&:before
border-color #cccccc
2.4 解決click延遲300ms的問題 fastclick插件
引入fastclick
在項目目錄下,在終端中寫入 --save表示開發環境還是上線打包都需要,用–save
//表示将此插件安裝到項目中
npm install fastclick --save
使用
在main.js中
//引入
import fastClick from 'fastclick'
//使用
fastClick.attach(document.body)
2.5 在style中引入其他樣式,需要這樣 ~@
@import '~@/assets/styles/varibles.styl';
2.6 對全局事件的解綁
//綁定,作用于全局,不用時一定要解綁
window.addEventListener('scroll', this.handleScroll)
//解綁
// 使用keep-alive後出現的方法,頁面即将被影藏時會執行
deactivated() {
window.removeEventListener('scroll', this.handleScroll)
}
2.7 解決麼面滑動影響其他頁面的問題
在路由裡面添加這句就解決了
// 解決頁面滑動影響其他頁面效果的問題
scrollBehavior (to, from, savedPosition) {
return {x:0 ,y:0}
}
3 插件使用
3.1 stylus和stylus-loader
可以快速幫助編寫css代碼
npm install stylus --save
3.2 輪播圖元件 vue-awesome-swiper
官網位址:https://www.swiper.com.cn/
github位址:https://github.com/surmon-china/vue-awesome-swiper
安裝:npm install [email protected] --save,使用2.6.7這個版本
//使用
import Vue from 'vue'
import VueAwesomeSwiper from 'vue-awesome-swiper'
// require styles
import 'swiper/dist/css/swiper.css'
Vue.use(VueAwesomeSwiper, /* { default global options } */)
3.2.1 使用vue代碼
<template>
<div class="wrapper">
<swiper :options="swiperOption">
<!-- slides -->
<swiper-slide v-for="item of swiperList" :key="item.id" data-swiper-autoplay="1500">
<img class="swiper-img" :src="item.imgUrl">
</swiper-slide>
<div class="swiper-pagination" slot="pagination"></div>
</swiper>
</div>
</template>
<script>
export default {
name: 'HomeSwiper',
data () {
return {
swiperOption: {
pagination: '.swiper-pagination',
// 支援循環輪播
loop: true,
// 自動播放
autoplay: true
},
swiperList: [{
id: '0001',
imgUrl: 'http://img1.qunarzz.com/piao/fusion/1609/b5/43a1ba885cbdd802.jpg_750x200_d70aa046.jpg'
}, {
id: '0002',
imgUrl: 'http://img1.qunarzz.com/piao/fusion/1805/f2/503916bba911f502.jpg_750x200_b12d0184.jpg'
}, {
id: '0003',
imgUrl: 'http://img1.qunarzz.com/piao/fusion/1809/fc/5e4ea3c336a86b02.jpg_750x200_62bf515a.jpg'
}, {
id: '0004',
imgUrl: 'http://mp-piao-admincp.qunarzz.com/mp_piao_admin_mp_piao_admin/admin/20196/818f6cc784ae6669b74bbbb255414a53.jpg_750x200_66ca5873.jpg'
}, {
id: '0005',
imgUrl: 'http://mp-piao-admincp.qunarzz.com/mp_piao_admin_mp_piao_admin/admin/20193/87a224d0349d94a11e97f31aa1aba4f5.jpg_750x200_1f78af87.jpg'
}]
}
}
}
</script>
<style scoped>
// 樣式進行穿透
.wrapper >>> .swiper-pagination-bullet-active
background #ffffff
.wrapper
overflow hidden
width 100%
height 0
padding-bottom 26.5%
background #cccccc
.swiper-img
width 100%
</style>
3.2.2 swiper自定義圖檔輪播元件
<template>
<div class="container" @click="handlerGallarlyClick">
<div class="wrapper">
<swiper :options="swiperOption">
<!-- slides -->
<swiper-slide v-for="(item, index) in imgs" :key="index">
<img class="gallarly-img" :src="item">
</swiper-slide>
<div class="swiper-pagination" slot="pagination"></div>
</swiper>
</div>
</div>
</template>
<script>
export default {
name: 'CommonGallary',
props: {
imgs: {
type: Array,
default () {
return []
}
}
},
data () {
return {
swiperOption: {
pagination: '.swiper-pagination',
paginationType: 'fraction',
// 元件有變化時,輪播會自動加載一遍
observer:true,
observeParents:true
}
}
},
methods: {
handlerGallarlyClick () {
this.$emit('close')
}
},
}
</script>
<style scoped>
.container >>> .swiper-container
overflow inherit
.container
display flex
flex-direction column
justify-content center
z-index 99
position fixed
left 0
right 0
top 0
bottom 0
background #000
.wrapper
width 100%
height 0
padding-bottom 100%
.gallarly-img
width 100%
.swiper-pagination
color #ffffff
bottom -1rem
</style>
3.3 資料請求 axios
1 安裝
npm install axios --save
2 使用
//導入
import axios from 'axios'
//請求
axios.get('/api/index.json').then(this.getHomeInfoSucc)
//接收傳回值的方法
getHomeInfoSucc (res) {
console.log(res)
}
3 注意 配置位址代理
在 config - index.js裡面這麼配置
// 代理配置
proxyTable: {
'/api': {
target: 'http://localhost:8080',
pathRewrite: {
// 将API 替換為 /static/mock
'^/api': '/static/mock'
}
}
},
3.4 頁面跳轉路由
1 路由配置
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/pages/home/Home'
import City from '@/pages/city/City'
Vue.use(Router)
// 導出去的内容 是一個路由
// 當使用者通路根路徑時,我給使用者展示HelloWorld這個元件
export default new Router({
// 路由配置
routes: [
{
path: '/',
name: 'Home',
component: Home
}, {
path: '/city',
name: 'City',
component: City
}
]
})
2 路由跳轉
<router-link to="/city">
<div class="header-right">
{{ this.city }}
<span class="iconfont arrow-icon"></span>
</div>
</router-link>
3 跳轉 router
this.$router.push('/')
3.5 Better-scroll 滾動插件
github位址:https://github.com/ustbhuangyi/better-scroll
1 安裝
npm install better-scroll --save
2 使用
//代碼結構要符合要求
<div class="wrapper">
<ul class="content">
<li>...</li>
<li>...</li>
...
</ul>
<!-- you can put some other DOMs here, it won't affect the scrolling
</div>
樣例代買
<template>
<div class="list" ref="wrapper">
<div>
<div class="area">
<div class="title border-topbottom">目前城市</div>
<div class="button-list">
<div class="button-wraper"><div class="button">北京</div></div>
</div>
</div>
<div class="area">
<div class="title border-topbottom">熱門城市</div>
<div class="button-list">
<div class="button-wraper"><div class="button">北京</div></div>
<div class="button-wraper"><div class="button">北京</div></div>
<div class="button-wraper"><div class="button">北京</div></div>
<div class="button-wraper"><div class="button">北京</div></div>
<div class="button-wraper"><div class="button">北京</div></div>
</div>
</div>
<div class="area">
<div class="title border-topbottom">A</div>
<div class="item-list">
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉爾</div>
</div>
<div class="title border-topbottom">A</div>
<div class="item-list">
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉爾</div>
</div>
<div class="title border-topbottom">A</div>
<div class="item-list">
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉爾</div>
</div>
</div>
</div>
</div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
name: 'CityList',
mounted () {
this.scroll = new BScroll(this.$refs.wrapper)
}
}
</script>
<style scoped>
@import '~styles/varibles.styl';
.list
overflow hidden
position absolute
top 1.58rem
left 0
right 0
bottom 0
.border-topbottom
&:before
border-color #cccccc
&after
border-color #cccccc
.border-bottom
&:before
border-color #cccccc
.title
line-height .44rem
background #eee
padding-left .2rem
color #666
font-size .26rem
.button-list
overflow hidden
padding .1rem .6rem .1rem .1rem
.button-wraper
float left
width 33.33%
.button
margin .1rem .1rem
padding .1rem 0
text-align center
border .02rem solid #cccccc
border-radius .06rem
.item-list
.item
line-height .76rem
color #666
padding-left .2rem
</style>
3 滾動到某一個元素處
this.scroll.scrollToElement(element)
3.6 Vuex實作資料共享
官方推薦
安裝:
npm install vuex --save
使用:
//1 建立store 存儲值的檔案index.js
import Vue from 'vue'
import Vuex from 'vuex'
// 使用插件
Vue.use(Vuex)
// 導出vuex 建立的倉庫
export default new Vuex.Store({
state: {
city: '北京'
},
//這個可以被跳過,直接調用commit
actions: {
//接收修改值的請求
changeCity (ctx, city) {
// 執行mutations,來修改需要修改的值
ctx.commit('changeCity', city)
}
},
mutations: {
//修改值
changeCity (state, city) {
state.city = city
}
}
})
//2 在main.js中引入
import store from './store'
new Vue({
el: '#app',
//資料共享
store,
})
// 3 在用的地方直接調用
{{ this.$store.state.city }}
//4 改變裡面值的方法,發送請求
handleCityClick (city) {
this.$store.dispatch('changeCity', city)
}
vuex映射值,簡單使用
import { mapState } from 'vuex'
//将值映射到計算屬性中
computed: {
// ... 展開屬性
...mapState(['city'])
}
然後直接 this.city 就可以了
3.6 本地存儲 localStorage
使用
//存值
localStorage.city = city
//取用
localStorage.city || '預設值'
3.7 keep-alive優化網頁性能
//用這個包裹了以後,就會有緩存,不在重新加載資料,Detail元件不被緩存
<keep-alive exclude="Detail">
<!-- 顯示的是目前路由位址所對應的内容 -->
<router-view/>
</keep-alive>
使用了 keep-alive後,會多出一個生命周期函數,可以用來做一些操作
// 使用了 keep-alive後,會多出一個生命周期函數,可以用來做一些操作
activated() {
},
3.8 遞歸元件的使用
資料
list: [{
title: '成人票',
children: [{
title: '成人三館聯票',
children: [{
title: '成人三館聯票-某一連鎖店銷售'
}]
}, {
title: '成人五館聯票'
}]
}, {
title: '學生票'
}, {
title: '兒童票'
}, {
title: '特惠票'
}]
元件的自身去調用元件自身
<template>
<div>
<router-link tag="div" to="/" class="header-abs" v-show="showAbs">
<div class="iconfont header-abs-back"></div>
</router-link>
<div
class="header-fixed"
v-show="!showAbs"
:style="opacityStyle"
>
景點詳情
<router-link to="/"><div class="iconfont header-fixed-back"></div></router-link>
</div>
</div>
</template>
<script>
export default {
name: 'DetailHeader',
data () {
return {
showAbs: true,
opacityStyle: {
opacity: 0
}
}
},
methods: {
// 滾動監聽事件
handleScroll () {
const top = document.documentElement.scrollTop
if (top > 60) {
let opacity = top / 140
opacity = opacity > 1 ? 1 : opacity
this.opacityStyle = { opacity }
this.showAbs = false
} else {
this.showAbs = true
}
}
},
activated () {
window.addEventListener('scroll', this.handleScroll)
},
// 使用keep-alive後出現的方法,頁面即将被影藏時會執行
deactivated () {
window.removeEventListener('scroll', this.handleScroll)
}
}
</script>
<style scoped>
@import '~styles/varibles.styl';
.header-abs
position absolute
left .2rem
top .2rem
width .8rem
height .8rem
line-height .8rem
border-radius .4rem
text-align center
background rgba(0, 0, 0, .8)
.header-abs-back
color #ffffff
font-size .4rem
.header-fixed
z-index 2
position fixed
top 0
left 0
right 0
height $headerHeight
line-height $headerHeight
text-align center
color #ffffff
background $bgColor
font-size .32rem
.header-fixed-back
position absolute
top 0
left 0
width .64rem
text-align center
font-size .4rem
color #ffffff
</style>
4 樣例
4.1 頭部漸隐漸現的效果元件
<template>
<div>
<router-link tag="div" to="/" class="header-abs" v-show="showAbs">
<div class="iconfont header-abs-back"></div>
</router-link>
<div
class="header-fixed"
v-show="!showAbs"
:style="opacityStyle"
>
景點詳情
<router-link to="/"><div class="iconfont header-fixed-back"></div></router-link>
</div>
</div>
</template>
<script>
export default {
name: 'DetailHeader',
data () {
return {
showAbs: true,
opacityStyle: {
opacity: 0
}
}
},
methods: {
// 滾動監聽事件
handleScroll () {
const top = document.documentElement.scrollTop
if (top > 60) {
let opacity = top / 140
opacity = opacity > 1 ? 1 : opacity
this.opacityStyle = { opacity }
this.showAbs = false
} else {
this.showAbs = true
}
}
},
activated () {
window.addEventListener('scroll', this.handleScroll)
}
}
</script>
<style scoped>
@import '~styles/varibles.styl';
.header-abs
position absolute
left .2rem
top .2rem
width .8rem
height .8rem
line-height .8rem
border-radius .4rem
text-align center
background rgba(0, 0, 0, .8)
.header-abs-back
color #ffffff
font-size .4rem
.header-fixed
position fixed
top 0
left 0
right 0
height $headerHeight
line-height $headerHeight
text-align center
color #ffffff
background $bgColor
font-size .32rem
.header-fixed-back
position absolute
top 0
left 0
width .64rem
text-align center
font-size .4rem
color #ffffff
</style>
4.2 漸影漸現的動畫元件
<template>
<transition>
<slot></slot>
</transition>
</template>
<script>
export default {
name: 'FadeAnimation'
}
</script>
<style scoped>
.v-enter, .v-leave-to
opacity 0
.v-enter-active, .v-leave-active
transition opacity .5s
</style>
使用
//在使用的地方用它包裹即可
<fade-animation>
<common-gallary
:imgs="bannerImgs"
v-show="showGallarly"
@close="handlerGallaryClose"
></common-gallary>
</fade-animation>