10個(gè)簡(jiǎn)單的技巧讓你的 vue.js 代碼更優(yōu)雅

來(lái)源 | https://juejin.im/post/6854573215969181703
前言
作為深度代碼潔癖,我們都希望能寫出簡(jiǎn)單高效的代碼,讓我們的代碼看起來(lái)更加優(yōu)雅,讓我們拋棄繁雜的代碼,一起開啟簡(jiǎn)單的旅程~~
01、slots 新語(yǔ)法向 3.0 看齊
使用帶有“#”的新命名插槽縮寫語(yǔ)法,在Vue 2.6.0+中可用
舉個(gè)例子:構(gòu)建插槽時(shí),最好規(guī)劃一下布局。這就是我的文章布局。
構(gòu)建插槽與構(gòu)建組件沒有什么不同。本質(zhì)上,插槽是具有超強(qiáng)功能的組件,讓我們細(xì)分一下上面的布局,組件的外觀如下:
I am the header
I am the content
I am the banner
02、動(dòng)態(tài)指令參數(shù)
指令參數(shù)現(xiàn)在可以接受動(dòng)態(tài)JavaScript表達(dá)式 動(dòng)態(tài)參數(shù)值應(yīng)該是字符串,但允許null作為一個(gè)明確指示應(yīng)該刪除綁定的特殊值,那將會(huì)很方便。任何其他非字符串值都可能出錯(cuò),并會(huì)觸發(fā)警告。(僅適用于v-bind和v-on)
//簡(jiǎn)寫
這里的 attributeName 會(huì)被作為一個(gè)JavaScript表達(dá)式進(jìn)行動(dòng)態(tài)求值,求得的值將會(huì)作為最終的參數(shù)來(lái)使用。例如,如果你的 Vue 實(shí)例有一個(gè) data 屬性 attributeName,其值為 href,那么這個(gè)綁定將等價(jià)于 v-bind:href
同樣地,你可以使用動(dòng)態(tài)參數(shù)為一個(gè)動(dòng)態(tài)的事件名綁定處理函數(shù):
//簡(jiǎn)寫
當(dāng) eventName 的值為 focus 時(shí),v-on:[eventName] 將等價(jià)于 v-on:focus。
同樣可以適用于插槽綁定:
Dynamic slot name//簡(jiǎn)寫Default slot
動(dòng)態(tài)參數(shù)預(yù)期會(huì)求出一個(gè)字符串,異常情況下值為 null。這個(gè)特殊的 null 值可以被顯性地用于移除綁定。任何其它非字符串類型的值都將會(huì)觸發(fā)一個(gè)警告。
...
變通的辦法是使用沒有空格或引號(hào)的表達(dá)式,或用計(jì)算屬性替代這種復(fù)雜表達(dá)式。
03、@hook那些事
處理組件內(nèi)定時(shí)器的步驟。通常我們一般都是這樣操作的:
但是其實(shí)更好的做法是:
設(shè)想一個(gè)場(chǎng)景 如果我們需要在數(shù)據(jù)渲染到頁(yè)面的之前讓頁(yè)面 loading。mounted 之后停止 loading。beforeUpdata 時(shí)開始 loading。updatad 之后停止 loading。
最簡(jiǎn)單的方法就是改寫組件的生命周期函數(shù),使其在 mounted/beforeUpdata /updatad 時(shí)通知父組件顯示或者隱藏 loading。
這樣做顯示不好,因?yàn)榍秩肓俗越M件的邏輯,增加的邏輯也和組件本身的功能好不關(guān)聯(lián)。最好的辦法就是使用 v-on="hook:xxx" 的方式:
@hook:mounted="loading = false"@hook:beforeUpdated="loading = true"@hook:updated="loading = false":data="data"/>
04、vue中的$props、$attrs和$listeners(可用來(lái)二次封裝組件)
//good//bad//而不是下面這樣,如果很多的屬性就特別繁瑣
v-bind="$attrs":value="value"@focus=$emit('focus', $event)"@input="$emit('input', $event.target.value)">
$listeners:包含了父作用域中的 (不含 .native修飾器的) v-on 事件監(jiān)聽器。它可以通過(guò) v-on="$listeners" 傳入內(nèi)部組件——在創(chuàng)建更高層次的組件時(shí)非常有用。
如果子組件不在父組件的根目錄下,則可以將所有事件偵聽器從父組件傳遞到子組件,如下所示:
......
05、響應(yīng)式數(shù)據(jù)(2.6.0新增)
我們習(xí)慣于用Vuex去解決狀態(tài)的共享問題,但是在小項(xiàng)目中使用就會(huì)有增大代碼體積和將代碼復(fù)雜化的煩惱,所以在后來(lái)的版本中Vue新增
Vue.observable( object )讓一個(gè)對(duì)象可響應(yīng),Vue 內(nèi)部會(huì)用它來(lái)處理 data 函數(shù)返回的對(duì)象。
返回的對(duì)象可以直接用于渲染函數(shù)和 計(jì)算屬性 內(nèi),并且會(huì)在發(fā)生改變時(shí)觸發(fā)相應(yīng)的更新。也可以作為最小化的跨組件狀態(tài)存儲(chǔ)器,用于簡(jiǎn)單的場(chǎng)景:
官方示例:
const state = Vue.observable({ count: 0 })const Demo = {render(h) {return h('button', {on: { click: () => { state.count++ }}}, `count is: ${state.count}`)}}
06、jsx模板組件
以下面的一組狀態(tài)判斷按鈕為例,我們很容易就下意識(shí)地在模板內(nèi)寫下這種代碼
但是如果我們利用渲染函數(shù)可以將上面的代碼抽取成優(yōu)雅的使用組件
我們將所有的邏輯封裝進(jìn)渲染函數(shù)內(nèi),外部只需要傳遞一個(gè)狀態(tài)參數(shù)即可改變
07、動(dòng)態(tài)組件
通過(guò) Vue 的 ?元素加一個(gè)特殊的 is attribute 可以實(shí)現(xiàn)動(dòng)態(tài)組件的效果
如圖,這是一個(gè)v-for渲染的列表(只是目前這個(gè)版塊才剛開始做,目前只有一個(gè)),圓圈內(nèi)的就是一個(gè)組件,也就是要v-for動(dòng)態(tài)組件。

實(shí)際使用
一開始就是基本的組件引入了
import ColorIn from '@/components/Magic/ColorIn.vue'import LineIn from "@/components/Magic/LineIn.vue";import Header from "@/components/Magic/Header.vue";import Footer from "@/components/Magic/Footer.vue";export default{components:{ColorIn,LineIn,Header,Footer}}
接下來(lái)就是動(dòng)態(tài)v-for動(dòng)態(tài)組件的使用,componentList:['ColorIn','LineIn','Header','Footer']使用下面的代碼即可將代碼依次循環(huán)
編譯以后的效果就是
08、Vue.filter
簡(jiǎn)單介紹一下過(guò)濾器,顧名思義,過(guò)濾就是一個(gè)數(shù)據(jù)經(jīng)過(guò)了這個(gè)過(guò)濾之后出來(lái)另一樣?xùn)|西,可以是從中取得你想要的,或者給那個(gè)數(shù)據(jù)添加點(diǎn)什么裝飾,那么過(guò)濾器則是過(guò)濾的工具。例如,從['abc','abd','ade']數(shù)組中取得包含‘a(chǎn)b’的值,那么可通過(guò)過(guò)濾器篩選出來(lái)‘a(chǎn)bc’和‘a(chǎn)bd’;把‘Hello’變成‘Hello World’,那么可用過(guò)濾器給值‘Hello’后面添加上‘ World’;或者把時(shí)間節(jié)點(diǎn)改為時(shí)間戳等等都可以使用過(guò)濾器。
場(chǎng)景:時(shí)間戳轉(zhuǎn)化成年月日這是一個(gè)公共方法,所以可以抽離成過(guò)濾器使用
// 使用// 在雙花括號(hào)中{{ message | capitalize }}// 在 `v-bind` 中// 全局注冊(cè)Vue.filter('stampToYYMMDD', (value) =>{// 處理邏輯})// 局部注冊(cè)filters: {stampToYYMMDD: (value)=> {// 處理邏輯}}// 多個(gè)過(guò)濾器全局注冊(cè)// /src/common/filters.jslet dateServer = value => value.replace(/(\d{4})(\d{2})(\d{2})/g, '$1-$2-$3')export { dateServer }// /src/main.jsimport * as custom from './common/filters/custom'Object.keys(custom).forEach(key => Vue.filter(key, custom[key]))
09、sync 語(yǔ)法糖
sync 就是為了實(shí)現(xiàn)prop 進(jìn)行“雙向綁定”僅此而已(父對(duì)子,子對(duì)父,來(lái)回傳)
當(dāng)你有需要在子組件修改父組件值的時(shí)候這個(gè)方法很好用,它的實(shí)現(xiàn)機(jī)制和v-model是一樣的。

10、利用 object.freeze 提升性能
Object.freeze() 方法可以凍結(jié)一個(gè)對(duì)象。一個(gè)被凍結(jié)的對(duì)象再也不能被修改;凍結(jié)了一個(gè)對(duì)象則不能向這個(gè)對(duì)象添加新的屬性,不能刪除已有屬性,不能修改該對(duì)象已有屬性的可枚舉性、可配置性、可寫性,以及不能修改已有屬性的值。此外,凍結(jié)一個(gè)對(duì)象后該對(duì)象的原型也不能被修改。freeze() 返回和傳入的參數(shù)相同的對(duì)象。
比方我們需要渲染一個(gè)非常大的數(shù)組對(duì)象,例如用戶列表,對(duì)象列表,文章列表等等。
export default {data: () => ({users: {}}),async created() {const users = await axios.get("/api/users");this.users = users;}};
vue 會(huì)將 data 對(duì)象中的所有的屬性加入到 vue 的響應(yīng)式系統(tǒng)中,當(dāng)這些屬性的值發(fā)生改變時(shí),視圖將會(huì)產(chǎn)生 響應(yīng),若對(duì)象的體積比較大,會(huì)消耗很多瀏覽器解析時(shí)間。
所以我們可以通過(guò)減少數(shù)據(jù)的響應(yīng)式轉(zhuǎn)換來(lái)提供前端的性能。
export default {data: () => ({users: {}}),async created() {const users = await axios.get("/api/users");this.users = Object.freeze(users);}};
本文完~

