來源 | https://juejin.im/post/6854573215969181703
前言
做爲深度代碼潔癖,咱們都但願能寫出簡單高效的代碼,讓咱們的代碼看起來更加優雅,讓咱們拋棄繁雜的代碼,一塊兒開啓簡單的旅程~~javascript
0一、slots 新語法向 3.0 看齊
使用帶有「#」的新命名插槽縮寫語法,在Vue 2.6.0+中可用html
![](http://static.javashuo.com/static/loading.gif)
構建插槽時,最好規劃一下佈局。這就是個人文章佈局。構建插槽與構建組件沒有什麼不一樣。本質上,插槽是具備超強功能的組件,讓咱們細分一下上面的佈局,組件的外觀以下:前端
<!-- TidbitPage.vue --><template> <article-layout>
<template #articleHeader> <h1>I am the header</h1> </template>
<template #articleContent> <p>I am the content</p> </template>
<template #articleFooter> <footer>I am the footer</footer> </template>
<template #side> <aside>I am the side stuff</aside> </template>
<template #banner> <div>I am the banner</div> </template>
</article-layout><template>
0二、動態指令參數
指令參數如今能夠接受動態JavaScript表達式 動態參數值應該是字符串,但容許null做爲一個明確指示應該刪除綁定的特殊值,那將會很方便。任何其餘非字符串值均可能出錯,並會觸發警告。(僅適用於v-bind和v-on)vue
<div v-bind:[attr]="attributeName"></div>//簡寫<div :[attr]="attributeName"></div>
這裏的 attributeName 會被做爲一個JavaScript表達式進行動態求值,求得的值將會做爲最終的參數來使用。例如,若是你的 Vue 實例有一個 data 屬性 attributeName,其值爲 href,那麼這個綁定將等價於 v-bind:hrefjava
一樣地,你可使用動態參數爲一個動態的事件名綁定處理函數:ios
<button v-on:[eventName]="handler"></button>//簡寫<button @[eventName]="handler"></button>
當 eventName 的值爲 focus 時,v-on:[eventName] 將等價於 v-on:focus。web
一樣能夠適用於插槽綁定:apache
<my-component><template v-slot:[slotName]>Dynamic slot name</template></my-component>//簡寫<foo><template #[name]>Default slot</template></foo>
動態參數預期會求出一個字符串,異常狀況下值爲 null。這個特殊的 null 值能夠被顯性地用於移除綁定。任何其它非字符串類型的值都將會觸發一個警告。npm
<!-- 這會觸發一個編譯警告 且 無效 --><a v-bind:['foo' + bar]="value"> ... </a>
變通的辦法是使用沒有空格或引號的表達式,或用計算屬性替代這種複雜表達式。編程
0三、@hook那些事
處理組件內定時器的步驟。一般咱們通常都是這樣操做的:
<script> export default { mounted() { this.timer = setInterval(() => { ... }, 1000); }, beforeDestroy() { clearInterval(this.timer); } };</script>
可是其實更好的作法是:
<script> export default { mounted() { const timer = setInterval(() => { ... }, 1000); this.$once('hook:beforeDestroy', () => clearInterval(timer);) } };</script>
設想一個場景 若是咱們須要在數據渲染到頁面的以前讓頁面 loading。mounted 以後中止 loading。beforeUpdata 時開始 loading。updatad 以後中止 loading。
最簡單的方法就是改寫組件的生命週期函數,使其在 mounted/beforeUpdata /updatad 時通知父組件顯示或者隱藏 loading。
這樣作顯示很差,由於侵入了自組件的邏輯,增長的邏輯也和組件自己的功能好不關聯。最好的辦法就是使用 v-on="hook:xxx" 的方式:
<v-chart @hook:mounted="loading = false" @hook:beforeUpdated="loading = true" @hook:updated="loading = false" :data="data"/>
0四、vue中的$props、$attrs和$listeners(可用來二次封裝組件)
//good<input v-bind="$props">
//bad//而不是下面這樣,若是不少的屬性就特別繁瑣<input :name="name" :placeholder="placeholder" :disabled="disabled">
<input v-bind="$attrs" :value="value" @focus=$emit('focus', $event)" @input="$emit('input', $event.target.value)">
$listeners:包含了父做用域中的 (不含 .native修飾器的) v-on 事件監聽器。它能夠經過 v-on="$listeners" 傳入內部組件——在建立更高層次的組件時很是有用。
若是子組件不在父組件的根目錄下,則能夠將全部事件偵聽器從父組件傳遞到子組件,以下所示:
<template><div> ...<childComponent v-on="$listeners" />...</div></template>
0五、響應式數據(2.6.0新增)
咱們習慣於用Vuex去解決狀態的共享問題,可是在小項目中使用就會有增大代碼體積和將代碼複雜化的煩惱,因此在後來的版本中Vue新增
Vue.observable( object )讓一個對象可響應,Vue 內部會用它來處理 data 函數返回的對象。
返回的對象能夠直接用於渲染函數和 計算屬性 內,而且會在發生改變時觸發相應的更新。也能夠做爲最小化的跨組件狀態存儲器,用於簡單的場景:
官方示例:
const state = Vue.observable({ count: 0 })
const Demo = { render(h) { return h('button', { on: { click: () => { state.count++ }} }, `count is: ${state.count}`) }}
0六、jsx模板組件
如下面的一組狀態判斷按鈕爲例,咱們很容易就下意識地在模板內寫下這種代碼
<button v-if="status === 1" class="btn1" :class="status === 1" @click="">未開始</button><button v-if="status === 2" class="btn2" :class="status === 2" @click="">進行中</button><button v-if="status === 3" class="btn3" :class="status === 3" @click="">可領取</button><button v-if="status === 4" class="btn4" :class="status === 4" @click="">已領取</button>
可是若是咱們利用渲染函數能夠將上面的代碼抽取成優雅的使用組件
<!DOCTYPE html><html lang="en">
<body> <div id="app"> <child :status="status"></child> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> Vue.component('child', { props: { status: { type: Number, required: true } }, render(createElement) { const innerHTML = ['未開始', '進行中', '可領取', '已領取'][this.status] return createElement('button', { class: { active: this.status }, attrs: { id: 'btn' }, domProps: { innerHTML }, on: { click: () => console.log(this.status) } }) } }) var app = new Vue({ el: '#app', data: { status: 0 } })</script></body></html>
咱們將全部的邏輯封裝進渲染函數內,外部只須要傳遞一個狀態參數便可改變
<child :status="status"></child>
0七、動態組件
經過 Vue 的 元素加一個特殊的 is attribute 能夠實現動態組件的效果
如圖,這是一個v-for渲染的列表(只是目前這個版塊纔剛開始作,目前只有一個),圓圈內的就是一個組件,也就是要v-for動態組件。
![](http://static.javashuo.com/static/loading.gif)
實際使用
一開始就是基本的組件引入了
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 }}
接下來就是動態v-for動態組件的使用,componentList:['ColorIn','LineIn','Header','Footer']使用下面的代碼便可將代碼依次循環
<component v-for="(item,index) in componentList" :key="index" :is="item"></component>
編譯之後的效果就是
<ColorIn></ColorIn><LineIn></LineIn><Header></Header><Footer></Footer>
0八、Vue.filter
簡單介紹一下過濾器,顧名思義,過濾就是一個數據通過了這個過濾以後出來另外一樣東西,能夠是從中取得你想要的,或者給那個數據添加點什麼裝飾,那麼過濾器則是過濾的工具。例如,從['abc','abd','ade']數組中取得包含‘ab’的值,那麼可經過過濾器篩選出來‘abc’和‘abd’;把‘Hello’變成‘Hello World’,那麼可用過濾器給值‘Hello’後面添加上‘ World’;或者把時間節點改成時間戳等等均可以使用過濾器。
場景:時間戳轉化成年月日這是一個公共方法,因此能夠抽離成過濾器使用
// 使用// 在雙花括號中{{ message | capitalize }}
// 在 `v-bind` 中<div v-bind:id="rawId | formatId"></div>
// 全局註冊Vue.filter('stampToYYMMDD', (value) =>{ // 處理邏輯})
// 局部註冊filters: { stampToYYMMDD: (value)=> { // 處理邏輯 }}
// 多個過濾器全局註冊// /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]))
0九、sync 語法糖
sync 就是爲了實現prop 進行「雙向綁定」僅此而已(父對子,子對父,來回傳)
當你有須要在子組件修改父組件值的時候這個方法很好用,它的實現機制和v-model是同樣的。
![](http://static.javashuo.com/static/loading.gif)
十、利用 object.freeze 提高性能
Object.freeze() 方法能夠凍結一個對象。一個被凍結的對象不再能被修改;凍結了一個對象則不能向這個對象添加新的屬性,不能刪除已有屬性,不能修改該對象已有屬性的可枚舉性、可配置性、可寫性,以及不能修改已有屬性的值。此外,凍結一個對象後該對象的原型也不能被修改。freeze() 返回和傳入的參數相同的對象。
比方咱們須要渲染一個很是大的數組對象,例如用戶列表,對象列表,文章列表等等。
export default { data: () => ({ users: {} }), async created() { const users = await axios.get("/api/users"); this.users = users; }};
vue 會將 data 對象中的全部的屬性加入到 vue 的響應式系統中,當這些屬性的值發生改變時,視圖將會產生 響應,若對象的體積比較大,會消耗不少瀏覽器解析時間。
因此咱們能夠經過減小數據的響應式轉換來提供前端的性能。
export default { data: () => ({ users: {} }), async created() { const users = await axios.get("/api/users"); this.users = Object.freeze(users); }};
本文分享自微信公衆號 - 編程微刊(wangxiaoting678)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。