簡述Vue中容易被忽視的知識點
前言
Vue的學(xué)習(xí)成本和難度不高,這除了和框架本身的設(shè)計理念有關(guān)之外,還和Vue完善的官方文檔有著密不可分的關(guān)系,相信有很多的開發(fā)者和我一樣,很長時間沒有仔細(xì)去看過官方文檔了,最近花時間仔細(xì)看了一下官方文檔,將里面一些容易忽視的點整理出來和大家分享。
容易忽視的點
箭頭函數(shù)的使用
ES6的普及使得箭頭函數(shù)的使用更加頻繁,但是在Vue中不要在選項屬性或者回調(diào)上使用箭頭函數(shù),舉個例子:
new Vue({ el: '#app', data: { show: true }, created: () => { console.log(this.show) }, })
將created鉤子寫成箭頭函數(shù),這里的this將不再指向Vue對象,在瀏覽器中將會指向window對象,這是因為箭頭函數(shù)并沒有this,this會作為變量一直向上級詞法作用域查找,直到找到為止
指令動態(tài)參數(shù)
Vue從2.6.0開始,可以用方括號括起來的JavaScript表達式作為一個指令參數(shù),舉個例子:
<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的事件監(jiān)聽設(shè)置為一個動態(tài)的參數(shù)event,默認(rèn)是監(jiān)聽點擊事件,當(dāng)點擊change的時候,改為監(jiān)聽focus事件,動態(tài)參數(shù)預(yù)期會求出一個字符串,異常情況下值為null,null值可以用于移除綁定,任何其他非字符串類型的值都會觸發(fā)一個警告
template中使用方法
methods中提供的方法大多數(shù)時候都是用來給其他方法調(diào)用的,但是它其實也可以像computed計算屬性一樣直接寫在模版里,舉個例子:
<div id="app">{{reversedMessage('hello')}}</div>
var app = new Vue({ el: '#app', methods: { reversedMessage: function (message) { return message.split('').reverse().join('') } }, })
有了computed計算屬性,為什么還要用methods呢?計算屬性是基于響應(yīng)式依賴進行緩存的,只在相關(guān)依賴發(fā)生改變時才會重新求值,而methods每次調(diào)用都會重新計算,調(diào)用methods時可以傳參,進行指定計算,但是computed不行,這在遍歷數(shù)組時十分有用
用key管理可復(fù)用元素
Vue會盡可能高效地渲染元素,通常會復(fù)用已有元素而不是從頭開始渲染。這么做會使 Vue變得非??欤e個例子:
<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將不會清除用戶已經(jīng)輸入的內(nèi)容,因為兩個模版使用了相同的元素,如果不想復(fù)用也很簡單,只需要添加一個具有唯一值的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>
現(xiàn)在切換,每次都會重新渲染,但是label元素還是會被復(fù)用,因為它沒有加唯一key值
v-if與v-for一起使用
Vue的風(fēng)格指南不推薦同時使用v-if與v-for,當(dāng)項目中的eslint繼承了@vue/standard時,同時使用就會編譯報錯,但是可以通過在模版上加<!-- eslint-disable -->進行忽略,同時當(dāng)它們處于同一節(jié)點,v-for的優(yōu)先級比v-if更高,這意味著v-if 將分別重復(fù)運行于每個v-for循環(huán)中
對象變更檢測
在Vue中對于已經(jīng)創(chuàng)建的實例,不允許動態(tài)添加根級別的響應(yīng)式屬性,但是我們知道可以通過Vue.set(object, propertyName, value)方法向嵌套對象添加響應(yīng)式屬性,那如果需要為已有對象賦值多個新屬性呢?舉個例子:
<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為這個對象重新賦值,這樣就能添加多個新的響應(yīng)式屬性
內(nèi)聯(lián)方法訪問原始DOM事件
有時在模版中調(diào)用方法時,我們需要向方法中傳參數(shù),但是同時又要傳遞原始的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把它傳入方法
once、passive事件修飾符
Vue中提供了多個事件修飾符, once、passive是后面新增的兩個,once用于限定事件只觸發(fā)一次,passive用于修飾的事件發(fā)生后立即觸發(fā),用于提升移動端性能
表單輸入修飾符
.lazy
在默認(rèn)情況下,v-model在每次input事件觸發(fā)后將輸入框的值與數(shù)據(jù)進行同步,可以添加lazy修飾符,從而轉(zhuǎn)變?yōu)槭褂胏hange事件進行同步,舉個例子:
<input placeholder="lazy" v-model.lazy="msg" @input="input" @change="change">
.number
如果想自動將用戶的輸入值轉(zhuǎn)為數(shù)值類型,可以給v-model添加number修飾符,這通常很有用,因為即使在type="number"時,HTML輸入元素的值也總會返回字符串。如果這個值無法被 parseFloat()解析,則會返回原始的值,舉個例子:
<input placeholder="number" v-model.number="age" @input="input">
.trim
如果要自動過濾用戶輸入的首尾空白字符,可以給v-model添加trim修飾符,舉個例子:
<input placeholder="trim" v-model.trim="trim" @input="input">
子組件替換/合并已有的特性
在Vue中對于絕大多數(shù)特性來說,從外部提供給組件的值會替換掉組件內(nèi)部設(shè)置好的值。所以如果傳入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",那么如果想要禁用屬性繼承怎么辦呢?可以在組件的選項中設(shè)置inheritAttrs:false,舉個例子:
Vue.component('base-input', { inheritAttrs: false, template: `<input type="date" placeholder="replace" class="default">` })
但是inheritAttrs:false選項不會影響style和class的綁定,因此style和class還是會合并
.sync修飾符
在有些情況下,可能需要對一個 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' } } })
當(dāng)調(diào)用this.$emit('update:title', 'change'),父組件中的title就會改變
總結(jié)
這篇文章對Vue中一些容易忽視的點進行了簡單的總結(jié),希望看完之后能對大家有所幫助。也希望大家多多支持腳本之家。
相關(guān)文章
如何使用vue slot創(chuàng)建一個模態(tài)框的實例代碼
這篇文章主要介紹了如何使用vue slot創(chuàng)建一個模態(tài)框,本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05vue使用iview的modal彈窗嵌套modal出現(xiàn)格式錯誤的解決
這篇文章主要介紹了vue使用iview的modal彈窗嵌套modal出現(xiàn)格式錯誤的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09Vue父子組件數(shù)據(jù)雙向綁定(父傳子、子傳父)及ref、$refs、is、:is的使用與區(qū)別
這篇文章主要介紹了Vue父子組件數(shù)據(jù)雙向綁定(父傳子、子傳父)及ref、$refs、is、:is的使用與區(qū)別,需要的朋友可以參考下2022-12-12Vue實現(xiàn)讓頁面加載時請求后臺接口數(shù)據(jù)
這篇文章主要介紹了Vue實現(xiàn)讓頁面加載時請求后臺接口數(shù)據(jù)2022-08-08