Vue的學習成本和難度不高,這除了和框架自己的設計理念有關以外,還和Vue完善的官方文檔有着密不可分的關係,相信有不少的開發者和我同樣,很長時間沒有仔細去看過官方文檔了,最近花時間仔細看了一下官方文檔,將裏面一些容易忽視的點整理出來和你們分享。html
ES6的普及使得箭頭函數的使用更加頻繁,可是在Vue中不要在選項屬性或者回調上使用箭頭函數,舉個例子:vue
new Vue({ el: '#app', data: { show: true }, created: () => { console.log(this.show) }, })
將created鉤子寫成箭頭函數,這裏的this將再也不指向Vue對象,在瀏覽器中將會指向window對象,這是由於箭頭函數並無this,this會做爲變量一直向上級詞法做用域查找,直到找到爲止數組
Vue從2.6.0開始,能夠用方括號括起來的JavaScript表達式做爲一個指令參數,舉個例子:瀏覽器
<div id="app"> <input v-on:[event] = "doSomething"> <button v-on:click="event = 'focus'">change</button> </div>
new Vue({ el: '#app', data() { return { event: 'input' } }, methods: { doSomething () { console.log('sss') } }, })
這裏將input的事件監聽設置爲一個動態的參數event,默認是監聽點擊事件,當點擊change的時候,改成監聽focus事件,動態參數預期會求出一個字符串,異常狀況下值爲null,null值能夠用於移除綁定,任何其餘非字符串類型的值都會觸發一個警告緩存
methods中提供的方法大多數時候都是用來給其餘方法調用的,可是它其實也能夠像computed計算屬性同樣直接寫在模版裏,舉個例子:app
<div id="app">{{reversedMessage('hello')}}</div>
var app = new Vue({ el: '#app', methods: { reversedMessage: function (message) { return message.split('').reverse().join('') } }, })
有了computed計算屬性,爲何還要用methods呢?計算屬性是基於響應式依賴進行緩存的,只在相關依賴發生改變時纔會從新求值,而methods每次調用都會從新計算,調用methods時能夠傳參,進行指定計算,可是computed不行,這在遍歷數組時十分有用框架
Vue會盡量高效地渲染元素,一般會複用已有元素而不是從頭開始渲染。這麼作會使 Vue變得很是快,舉個例子:函數
<div id="app"> <template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address"> </template> <button @click="change">change</button> </div>
var app = new Vue({ el: '#app', data() { return { loginType: 'username' } }, methods: { change () { this.loginType = this.loginType === 'username' ? 'email' : 'username' } } })
上面代碼中切換loginType將不會清除用戶已經輸入的內容,由於兩個模版使用了相同的元素,若是不想複用也很簡單,只須要添加一個具備惟一值的key屬性便可:性能
<template v-if="loginType === 'username'"> <label>Username</label> <input key="username" placeholder="Enter your username"> </template> <template v-else> <label>Email</label> <input key="email" placeholder="Enter your email address"> </template> <button @click="change">change</button>
如今切換,每次都會從新渲染,可是label元素仍是會被複用,由於它沒有加惟一key值學習
Vue的風格指南不推薦同時使用v-if與v-for,當項目中的eslint繼承了@vue/standard時,同時使用就會編譯報錯,可是能夠經過在模版上加<!-- eslint-disable -->進行忽略,同時當它們處於同一節點,v-for的優先級比v-if更高,這意味着v-if 將分別重複運行於每一個v-for循環中
在Vue中對於已經建立的實例,不容許動態添加根級別的響應式屬性,可是咱們知道能夠經過Vue.set(object, propertyName, value)方法向嵌套對象添加響應式屬性,那若是須要爲已有對象賦值多個新屬性呢?舉個例子:
<div id="app">{{user.name}}-{{user.age}}-{{user.sex}}</div>
var app = new Vue({ el: '#app', data() { return { user: { name: 'xxx' } } }, created() { this.user = Object.assign({}, this.user, { age: 18, sex: 'name' }) }, })
能夠用Object.assign爲這個對象從新賦值,這樣就能添加多個新的響應式屬性
有時在模版中調用方法時,咱們須要向方法中傳參數,可是同時又要傳遞原始的DOM事件,怎麼處理呢?舉個例子:
<div id="app"> <button @click="share('share info', $event)">share</button> </div>
var app = new Vue({ el: '#app', data() { return { user: { name: 'xxx' } } }, methods: { share (info, event) { console.log(info, event) } }, })
如例子所示,能夠用特殊變量$event把它傳入方法
Vue中提供了多個事件修飾符, once、passive是後面新增的兩個,once用於限定事件只觸發一次,passive用於修飾的事件發生後當即觸發,用於提高移動端性能
在默認狀況下,v-model在每次input事件觸發後將輸入框的值與數據進行同步,能夠添加lazy修飾符,從而轉變爲使用change事件進行同步,舉個例子:
<input placeholder="lazy" v-model.lazy="msg" @input="input" @change="change">
若是想自動將用戶的輸入值轉爲數值類型,能夠給v-model添加number修飾符,這一般頗有用,由於即便在type="number"時,HTML輸入元素的值也總會返回字符串。若是這個值沒法被 parseFloat()解析,則會返回原始的值,舉個例子:
<input placeholder="number" v-model.number="age" @input="input">
若是要自動過濾用戶輸入的首尾空白字符,能夠給v-model添加trim修飾符,舉個例子:
<input placeholder="trim" v-model.trim="trim" @input="input">
在Vue中對於絕大多數特性來講,從外部提供給組件的值會替換掉組件內部設置好的值。因此若是傳入type="text"就會替換掉 type="date"並把它破壞!慶幸的是,class和 style特性會稍微智能一些,即兩邊的值會被合併起來,從而獲得最終的值,舉個例子:
<div id="app"> <base-input type="text" class="out"></base-input> </div>
Vue.component('base-input', { template: `<input type="date" placeholder="replace" class="default">` }) new Vue({ el: '#app', })
在上例中input的type值爲date,class爲deafault,在使用子組件時,向子組件中傳入type="text" class="out",此時input的type值會被替換爲text,class值會被合併爲"default out",那麼若是想要禁用屬性繼承怎麼辦呢?能夠在組件的選項中設置inheritAttrs:false,舉個例子:
Vue.component('base-input', { inheritAttrs: false, template: `<input type="date" placeholder="replace" class="default">` })
可是inheritAttrs:false選項不會影響style和class的綁定,所以style和class仍是會合並
在有些狀況下,可能須要對一個 prop進行「雙向綁定」。不幸的是,真正的雙向綁定會帶來維護上的問題,由於子組件能夠修改父組件,且在父組件和子組件都沒有明顯的改動來源,所以Vue提供了sync修飾符,舉個例子:
<div id="app"> <span>{{title}}</span> <text-document v-bind:title.sync="title"></text-document> </div>
Vue.component('text-document', { props: ['title'], template: `<button @click="change">change</button>`, methods: { change () { this.$emit('update:title', 'change') } }, }) new Vue({ el: '#app', data() { return { title: 'default' } } })
當調用this.$emit('update:title', 'change'),父組件中的title就會改變
這篇文章對Vue中一些容易忽視的點進行了簡單的總結,但願看完以後能對你們有所幫助。若是有錯誤或不嚴謹的地方,歡迎批評指正,若是喜歡,歡迎點贊