vue2.0移動端開發的相關外掛以及經驗總結
最近在用vue2.0做微信公眾號相關的前端開發,經過這次開發實踐,現將專案中用到的相關比較實用的外掛及遇到的相關問題進行整理,希望和大家共同交流…
- cssrem:一個CSS值轉REM的VSCode外掛;
- lib-flexible:移動端彈性佈局適配解決方案;
- vue-touch:移動端相關點選,滑動,拖動,多點觸控等事件封裝;
- vee-validate:適用於vue專案中表單驗證外掛;
- better-scroll :可能是目前最好用的移動端滾動外掛;
- fastclick:解決移動端click 300ms延遲
- vConsole:手機前端開發除錯利器
- webpack之proxyTable設定跨域
- vue元件之間通訊(父向子通訊,子向父通訊,非父子通訊)方法示例;
- ref特性的使用;
- vue中setTimeout,setInterval的使用;
- 監聽滑鼠滾動事件,實現頭部懸浮效果(this.$nextTick);
- new FormData()上傳影象;
- vue,@click=“event()”,新增()與不新增()的區別;
1、cssrem
介紹:
一個CSS值轉REM的VSCode外掛。我們在做移動端開發時,為了網頁適配,一般會將畫素單位px轉換為rem.在用vscode開發時,我們可以安裝cssrem這個外掛。
外掛效果如下:
預設配置:
“cssrem.rootFontSize”: root font-size (unit: px), 預設為: 16;
“cssrem.fixedDigits”: px轉rem小數點最大長度,預設:6;
“cssrem.autoRemovePrefixZero”:自動移除0開頭的字首,預設:true;
"css.remoteStyleSheets": []
專案中配置:
“cssrem.rootFontSize”:75, //px轉化為rem基準75px,由於我在專案中使用了淘寶彈性佈局方案lib-flexible,UI同事是按照iphone6尺寸(750px)進行設計的。專案在iphone6螢幕時,root,html的font-size:75px;所以,專案中配置rem基準為75px; "cssrem.fixedDigits:2", 即設定px轉rem最大小數點為2位數;
使用方法:
這裡是vsCode的配置方法:
檔案–>首選項–設定–>“搜尋cssrem”,將自己的設定放入右邊覆蓋“預設設定”,重啟編輯器,即可,如圖:
2、lib-flexible
介紹:
lib-flexible為移動端彈性佈局適配解決方案。很多的大公司,如網易,淘寶等,都在用它作為移動端佈局。
使用方法:
- 安裝lib-flexible:
npm install lib-flexible --save
- 引入lib-flexible,在專案入口檔案main.js 中引入lib-flexible
import 'lib-flexible'
- 去掉目標檔案的index.html頭裡的meta標籤。
<meta name="viewport" content="width=device-width, initial-scale=1.0">
不要寫上邊這行meta,flexible會為根據螢幕自動給我加上,如果你自己加了, 那麼flexible會根據你加的值來計算,也就會出現固定的值,安卓和蘋果都會一樣了。data-dpr有可能是固定的了
知識延伸:
px2rem-loader,在做畫素單位適配的時,你也可以不用安裝cssrem,直接 用px,我們可以通過安裝外掛:px2rem-loader並進行相應的配置,通過編譯之後,自動將px轉換為rem;
使用方法,可參考官網;但是其有一定的侷限性,即只能將.vue檔案style標籤中的px轉成rem,對外部引入css,px2rem能不能轉換rem問題;
對於引入了第三方框架,他們的樣式是另一套寫法,樣式會被flexible轉換,就會破壞框架的樣式。
如果在.vue檔案style中的某一行程式碼不希望被轉成rem,只要在後面寫上註釋 /* no*/就可以了。
3、vue-touch
官網:https://github.com/vuejs/vue-touch/tree/next
介紹:vue-touch其實封裝了 hammer.js的方法,針對觸屏的6大事件進行監聽。
使用方法:
- 安裝vue-touch:
npm install [email protected]
- 嵌入vue-touch:( 在vue入口檔案main.js中將其註冊為全域性元件:)
var VueTouch = require('vue-touch')
Vue.use(VueTouch, {name: 'v-touch'})
使用例項:
<v-touch v-on:swipeleft="onSwipeLeft(data)">Swipe me!</v-touch> //左劃 預設渲染為div data為引數
<v-touch tag="a" v-on:tap="onTap">Tap me!</v-touch> //點選 渲染為一個a標籤
<v-touch tag="p" v-on:tap="onTap">Tap me!</v-touch> //點選 渲染為p標籤
常用的事件有:
swiper(滑動事件)、tap(短時間內的點選事件)、press(事件大於tap的按壓事件)
api及相關的事件:
*事件說明:*https://blog.csdn.net/easyClub_hanjixin/article/details/78702738
(1)、pan,觸屏中的拖動事件,在指定的dom區域內,一個手指放下並移動事件
事件型別有:pan, panstart, panmove, panend, pancancel, panleft, panright, panup, pandown;
使用方法為:v-on:panstart=“callback”;
(2)、Swipe:滑動事件,在指定的dom區域內,一個手指快速的在觸屏上滑動。
事件型別有:swipe, swipeleft, swiperight, swipeup, swipedown
使用方法為:v-on:swipeleft=“callback”;
(3)、Tap:在指定的dom區域內,一個手指輕拍或點選時觸發該事件(類似PC端的click)。該事件最大點選時間為250毫秒,如果超過250毫秒則按Press事件進行處理。
事件型別:tap
使用方法:v-on:tap=“callback”
(4)、Press:在指定的dom區域內觸屏版本的點選事件,這個事件相當於PC端的Click事件,該不能包含任何的移動,最小按壓時間為500毫秒,常用於我們在手機上用的“複製、貼上”等功能。該事件分別對以下事件進行監聽並處理:
事件型別:press, pressup
使用方法:v-on:press = “callback”
(5)、Rotate事件:在指定的dom區域內,當兩個手指或更多手指成圓型旋轉時觸發(就像兩個手指擰螺絲一樣)。該事件分別對以下事件進行監聽並處理
事件型別:rotate, rotatestart, rotatemove, rotateend, rotatecancel,
使用方法:v-on:rotate = “callback”
(6)、Pinch:在指定的dom區域內,兩個手指(預設為兩個手指,多指觸控需要單獨設定)或多個手指相對(越來越近)移動或相向(越來越遠)移動時事件。該事件事以分別對以下事件進行監聽並處理:
Pinchstart:多點觸控開始、Pinchmove:多點觸控過程、Pinchend:多點觸控結束、Pinchcancel:多點觸控取消、Pinchin:多點觸控時兩手指距離越來越近、 Pinchout:多點觸控時兩手指距離越來越遠
注意事項:
(1)、注意:vue-touch 使用的是2.0.0版本 需要與vue2.0.0相容;
應用例項:
(2)、通過手勢滑動,進行頁面的切換,如:
swiperleft: function () {
this.$router.push({'path':'/queuehistory'});
},
4、vee-validate
vee-validate介紹:
vee-validate為適用於vue專案中表單驗證外掛.引入vee-validate,會更加方便我們進行表單驗證。 官方網址:https://baianat.github.io/vee-validate/
安裝vee-validate:
-npm install [email protected] --save
注意:@next,不然是Vue1.0版本
安裝時要注意安裝的版本,不同的版本使用的方式不一樣。
如果在安裝完成後,且在mian.js中進行了正確的引用,如果在控制檯,出現如下報錯資訊:
IMPORTED_MODULE_5_vee_validate__.a.addLocale is not a func
則說明,你安裝的版本過高,請重新解除安裝,安裝較低版本即可;我的專案中安裝的版本為:2.0.0-rc.25。
main.js裡引用vee-validate外掛
import Vue from 'vue'
import VeeValidate,{ Validator } from 'vee-validate'
import zh_CN from 'vee-validate/dist/locale/zh_CN' //引入中文包,提示資訊可以以中文形式顯示
Validator.addLocale(CN) // 設定提示資訊中文方式顯示
Vue.use(VeeValidate, { locale: 'zh_CN'})
擴充套件自定義驗證規則:
Validator.extend('phone',
{ messages:{
zh_CN: field => '請輸入正確手機號'
},
validate: value => {
return /^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/.test(value)
}
});
Validator.extend('isCard', {
messages: {
zh_CN: field => '請輸入正確身份證號'
},
validate: value => {
return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(value)
}
})
自帶規則的中文設定:
const dictionary = {
zh_CN: {
messages: {
required: (val) => {
let msg = ''
switch (val) {
case 'ownerPhone':
msg = '手機號'
break
}
msg = msg + '不能為空哦'
return msg
},
numeric: (val) => {
let msg = ''
switch (val) {
case 'houseShi':
msg = '居室'
break
}
msg = msg + '只能為數字'
return msg
}
}
}}
Validator.updateDictionary(dictionary)
- 元件中使用
外掛自帶規則和自定義規則,寫法:v-validate="‘required|ownerPhone’",設定name屬性,通過v-show="errors.has()"來進行name屬性的監聽,顯示和隱藏相關的提示資訊;
<form class="form" autocomplete="off" @submit.prevent="validateBeforeSubmit">
<div class="form-item">
<input type="number" placeholder="請輸入你的手機號" v-model="params.ownerPhone" v-validate="'required|ownerPhone'" name="ownerPhone">
<span v-show="errors.has('ownerPhone')" class="help is-danger">
{{ errors.first('ownerPhone') }}
</span>
</div>
<button class="form-btn bg-blue" type="submit">登入</button>
</form>
更詳細的語法學習,請參見vee-validate官網:https://baianat.github.io/vee-validate/;
5、better-scroll
- better-scroll介紹:
better-scroll,官方網址,better-scroll 是一款重點解決移動端(現已支援 PC 端)各種滾動場景需求的外掛。它的核心是借鑑的 iscroll 的實現,它的 API 設計基本相容 iscroll,在 iscroll 的基礎上又擴充套件了一些 feature 以及做了一些效能優化。
better-scroll 是基於原生 JS 實現的,不依賴任何框架。它編譯後的程式碼大小是 63kb,壓縮後是 35kb,gzip 後僅有 9kb,是一款非常輕量的 JS lib。
- 使用方法
安裝方法
npm install --save better-scroll;
起步
better-scroll 最常見的應用場景是列表滾動,我們來看一下它的 html 結構:
<div class="wrapper">
<ul class="content">
<li>...</li>
<li>...</li>
...
</ul>
<!-- 這裡可以放一些其它的 DOM,但不會影響滾動 -->
</div>
上面的程式碼中 better-scroll 是作用在外層 wrapper 容器上的,滾動的部分是 content 元素。這裡要注意的是,better-scroll 只處理容器(wrapper)的第一個子元素(content)的滾動,其它的元素都會被忽略。
最簡單的初始化程式碼如下:
import BScroll from 'better-scroll'
let wrapper = document.querySelector('.wrapper')
let scroll = new BScroll(wrapper)
結合介面下拉重新整理載入更多資料
export default {
methods:{
async getMyBillList() {
const res = await getMyBillList(reqData);
if (res.status.code == "200") {
this._houseScroll(); // 結合介面初始化scroll資料
}else{
console.log("介面呼叫失敗~");
}
},
_houseScroll(){
this.$nextTick(() => {
if (!this.houseScroll) {
let wrapper = document.querySelector('.wrapper'); // scroll容器
// new Bscroll(),初始化容器;
this.houseScroll = new Bscroll(wrapper,{
scrollY: true,
probeType: 3,
click: true,
pullUpLoad: {
threshold: -100 // 在上拉到超過底部 20px 時,觸發 pullingUp 事件
}
}
);
// 初始化上拉重新整理載入更多方法
this.houseScroll.on("pullingUp", () => {
this.pageNo++;
if (this.totalPage >= this.pageNo) {
this.pageNo++; // 通過pageNo增加,載入第二頁的資料
this.getMyBillList();
this.loading = true;
} else {
this.loading = false;
this.loadingOver = true;
}
});
} else {
this.houseScroll.finishPullUp();
this.houseScroll.refresh();
}
});
}
}
}
6、fastclick外掛:解決移動端click 300ms延遲
移動端專案中,在某些機型某些瀏覽器下,存在click事件300ms延遲的問題,影響使用者滿意度。原因是:從點選螢幕上的元素到觸發元素的 click 事件,移動瀏覽器會有大約 300 毫秒的等待時間,因為它想看看你是不是要進行雙擊(double tap)操作。
vue專案中,可以通過引入fastclick第三方依賴包來解決。
安裝方法:
npm install --save fastclick
使用方法:
在main.js中
import fastclick from 'fastclick'
fastclick.attach(document.body)
也可以直接下載fastclick.js,在相應頁面直接引用。
7、手機前端開發除錯利器 – vConsole
vConsole介紹:
一個輕量、可拓展、針對手機網頁的前端開發者除錯面板。
移動端專案,由於在移動端無法開啟控制檯,所以無法像pc端chrome控制檯那樣直觀檢視console資訊;不過我們可以使用vConsole外掛進行除錯。
使用方法如下:
安裝vConsole:
npm install vconsole --save-dev
在main.js中引用並例項化:
import VConsole from 'vconsole';
const vConsole = new VConsole(); // 不使用的時候,可以將這句遮蔽掉;
此時可以使用console.log
原理:改寫了console.log,重寫了實現,用vConsole代理
結果就會出現如圖 浮動的按鈕,點開之後,就可以看到裡面的console資訊了;
8、webpack之proxyTable設定跨域
在平時專案的開發環境中,經常會遇到跨域的問題,尤其是使用vue-cli這種腳手架工具開發時,由於專案本身啟動本地服務是需要佔用一個埠的,所以必然會產生跨域的問題。在使用webpack做構建工具的專案中,使用proxyTable代理實現跨域是一種比較方便的選擇。
proxyTable相關配置及使用說明:
當我們用vue-cli構建專案時,需要在config/index.js檔案中,找到dev物件下proxyTable物件進行跨域設定,配置如下:
dev: {
env: require('./dev.env'),
port: 8080,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
cssSourceMap: false,
proxyTable: {
'/api': {
target: 'http://www.abc.com', //目標介面域名
changeOrigin: true, //是否跨域
secure: false, // 允許https請求
pathRewrite: {
'^/api': '/api' //重寫介面
}
}
}
proxyTable配置的意思為:使用字串"/api"來代替目標介面域名;如果介面地址為"user/getUserInfo",我們可以在所有的介面地址前面加上"/api/"用於設定代理;如:
'http://localhost:8080/api/user/getUserInfo' ===>
'http://www.abc.com/api/user/getUserInfo'
如果你不想每次請求地址中都帶有"/api/",則可以設定
pathRewrite: {
'^/api': '' // 後面可以使重寫的新路徑,一般不做更改
}
表現結果為:
'http://localhost:8080/api/user/getUserInfo'
===> 'http://www.abc.com/user/getUserInfo'
另外一種情況是,我們不需要在每個介面地址前新增"/api/",只需要用介面本身的地址,不需要重新路徑即可。如果介面為:"/v2/cotton/get_app_list",使用"/v2"做代理;如下:
dev: {
proxyTable: {
'/v2': {
target: 'http://www.abc.com', //目標介面域名
changeOrigin: true, //是否跨域
secure: false, // 允許https請求
// 這裡去掉了重新設定新路徑,因為介面地址本身就是以"/v2/"開頭的;
}
}
'http://localhost:8080/v2/cotton/get_app_list'
===> 'http://www.abc.com/v2/cotton/get_app_list'
// http://localhost:8080/v2表示http://www.abc.com
預設情況下,不接受執行在 HTTPS 上,且使用了無效證書的後端伺服器。如果你想要接受,修改配置如下:
proxy: {
"/api": {
target: "https://www.abc.com",
secure: false
}
}
9、vue元件之間通訊
父向子傳遞資料通過props:
/**父元件程式碼:**/
<template>
<header-box :title="text"></header-box>
</template>
<script>
import HeaderBox from './header'
export default {
name: 'index',
components: {
HeaderBox
},
data () {
return {
text: '首頁'
}
}
}
</script>
/**子元件程式碼**/
<template>
<header>
{{thisTitleTxt}}
</header>
</template>
<script>
export default {
name: 'headerbox',
props: {
text: String
},
data () {
return {
thisTitleTxt: this.text
}
}
}
</script>
子向父傳遞資料:
子元件向父元件傳遞分為兩種型別。
1、子元件改變父元件傳遞的props(你會發現通過props中的Object型別引數傳輸資料,可以通過子元件改變資料內容。這種方式是可行的,但是不推薦使用,因為官方定義prop是單向繫結);
2、通過
emit;即子元件中通過$emit()來觸發事件;父元件中通過依附在組價元素上的:on方法來響應事件。
*通過$on,$emit*
**父元件程式碼**
<template>
<div id="counter-event-example">
<p>{{ total }}</p>
<!--父元件中通過v-on:key="function"來觸發方法的執行-->
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
</template>
<script>
import ButtonCounter from './buttonCounter'
export default {
name: 'index',
components: {
'button-conuter': ButtonCounter
},
data () {
return {
total: 0
}
},
methods: {
incrementTotal () {
this.total++
}
}
}
</script>
**子元件程式碼**
<template>
<button @click="incrementCounter">{{counter}}</button>
</template>
<script>
export default {
name: 'button-counter',
data () {
return {
counter: 0
}
},
metheds: {
incrementCounter () {
this.$emit('increment');// 子元件中通過this.$emit('key',value)觸發事件訊號
this.counter++
}
}
}
</script>
非父子元件傳遞資料;
通過使用一個空的Vue例項作為中央事件匯流排。
**main.js**
let bus = new Vue()
Vue.prototype.bus = bus;
相鄰元件1,通過$emit()傳遞資料
this.bus.$emit("toChangeTitle","首頁");
相鄰元件2,通過$on()接收資料
mounted(){
this.bus.$on('toChangeTitle', function (title) {
console.log(title)
})
}
10、ref特性的使用
ref 被用來給元素或子元件註冊引用資訊。引用資訊將會註冊在父元件的 $refs 物件上。
如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子元件上,引用就指向元件例項:
<div id="app">
<input type="text" ref="input1" v-model="name"/>
<button @click="add">新增</button>
<!-- `vm.$refs.child` will be the child component instance -->
<child-component ref="child"></child-component>
</div>
<script>
export default{
data(){
return {
name:"xiaoming"
}
},
created(){
this.$nextTick(()=>{
console.log(this.$refs.input1.value);
});
},
methods:{
add(){
this.$refs.input1.value = "22"; //this.$refs.input1 減少獲取dom節點的消耗
}
}
}
</script>
當 v-for 用於元素或元件的時候,引用資訊將是包含 DOM 節點或元件例項的陣列。
關於 ref 註冊時間的重要說明:因為 ref 本身是作為渲染結果被建立的,在初始渲染的時候你不能訪問它們 - 它們還不存在!$refs 也不是響應式的,因此你不應該試圖用它在模板中做資料繫結。
通過在引用的子元件上使用ref屬性實現父元件呼叫子元件的方法及屬性
在父元件中引用子元件並定義ref
<v-food ref="selectfood"></v-food>
呼叫定義在子元件中的方法show
this.$refs.selectfood.show();//同時也可以呼叫子元件中的屬性。
11、vue中setTimeout的使用
在vue中使用setTimeout或者setInterval,如果按照在原來js的中方法,如
setTimeout(function(){
this.isFlag = true;
},3000);
會發現data中定義的變數isFlag是獲取不到的;解決方法如下:
用setTimeout通過es6語法,setInterval也是一樣
import { setTimeout } from "timers";
<script>
export default{
data(){
return {
time:"",
isFlag:false
}
},
methods:{
add(){
clearTimeout(this.time);
this.time = setTimeout(() =>{
this.isFlag = true;
},2000)
}
}
}
</script>
定義外部self來代替全域性this
methods:{
add(){
let self = this;
clearTimeout(this.time);
this.time = setTimeout(function(){
self.isFlag = true;
},2000)
}
}
我們會發現利用例子的第一種方法,使用this來獲取變數,會報錯。這就是老生常談的javaScript 的this 的問題。
因為用的一個function(){} 這裡的 獨立的作用域 this指向了全域性(這裡是window)而且window裡沒有myFunc這個函式,所報了錯。
使用es6的->寫法,this繼承外部物件,this指向為vue例項,即(new Vue);
12、監聽滑鼠滾動事件,實現頭部懸浮效果
$nextTick 是在下次 DOM 更新迴圈結束之後執行延遲迴調,滑鼠滾動事件需要通過window.addEventListener(“scroll”,’’)
進行監聽。
<script>
mounted(){
// 監聽滾動事件
this.$nextTick(function () {
window.addEventListener('scroll', this.needToTop); //滾動事件監聽
});
},
methods:{
needToTop(){
let curHeight = document.documentElement.scrollTop || document.body.scrollTop; // 滾動條距離頂部的距離
let bgareaHeight = this.$refs["bgarea"].offsetHeight; // 背景總高度
let opacity = curHeight/bgareaHeight;
this.$refs["title"].style.background = "rgba(255, 255, 255, "+opacity+")";
this.$refs["title"].style.boxShadow = "0 0 .27rem rgba(204, 204, 204, "+opacity+")";
}
}
</script>
13、vue上傳影象
通過new FormData(),建立form物件,通過append向form物件新增資料。
html程式碼如下:
<div class="txarea">
<input type="file" class="txfile" name="file" id="upimg" accept="image/*" @change="fileChange($event)">
<p class="tx" @click="chooseType">點選上傳頭像</p>
</div>
<script>
export default{
methods:{
// 獲取使用者影象
chooseType() {
document.getElementById('upimg').click();
},
fileChange(e) {
let file = e.target.files[0];
let param = new FormData(); //建立form物件
param.append('file',file,file.name);//通過append向form物件新增資料
let config = {
headers:{'Content-Type':'multipart/form-data'} //新增請求頭
};
this.axios.post(uploadUrl,param,config)
.then(response=>{
// 已經獲取到圖片地址,再調介面,儲存到資料庫即可;
let reqData = {
phone: this.loginInfo.phone,
pic:response.data.url // 大圖地址
}
this.setUserInfo(reqData);
})
},
setUserInfo(){ // 儲存使用者影象
...
}
}
}
</script>
14、vue,@click=“event()”,新增()與不新增()的區別
應該是 Vue 對函式呼叫表示式額外用了一個函式做了層包裝。
加與不加括號的區別在於事件物件引數 event 的處理。
不加括號時,函式第一個引數預設為 event;加了括號後,需要手動傳入 $event 才能獲得事件物件。
<template>
<div class="btn-item">
<button class="btn btn-success" @click="sure($event)">確定</button>
<button class="btn btn-default" @click="quit">取消</button>
</div>
</template>
<script>
export default{
name:'test',
data(){
return {
}
},
methods:{
sure(e){
console.log(e.target);
},
quit(e){
console.log(e.target);
}
}
}
</script>
專案實踐:基於vue2.0 +vuex+ element-ui後臺管理系統
文章摘自:https://www.cnblogs.com/wdlhao/p/9393539.html
原作者部落格:http://www.cnblogs.com/wdlhao/
如有侵權行為,請告知即刪除