JS每日一題: Vue中mixin怎麼理解?
20190122
Vue中mixin怎麼理解?
mixin是為了讓可複用的功能靈活的混入到當前元件中,混合的物件可以包含任意元件選項(生命週期,指令之類等等), mixin翻譯過來叫混合,高階的詞彙可以叫外掛入侵
簡單使用
// 定義一個混合物件 const myMixin = { created: function () { this.hello() }, methods: { hello: function () { console.log('JS 每日一題') } } } // 定義一個使用混合物件的元件 const Component = Vue.extend({ mixins: [myMixin] }) var component = new Component() // JS 每日一題
選項合併(優先順序)
當元件和混合物件含有同名選項時,選項會按照規則進行合併
程式碼理解
const mixin = { created: function () { console.log('混合物件的鉤子被呼叫') } } new Vue({ mixins: [mixin], created: function () { console.log('元件鉤子被呼叫') } }) // => "混合物件的鉤子被呼叫" // => "元件鉤子被呼叫" // 從上面的程式碼我們可以看出來混合物件的生命週期會被先呼叫
值為物件的選項,例如 methods, components 和 directives,將被混合為同一個物件。兩個物件鍵名衝突時,取元件物件的鍵值對,Vue.extend() 也使用同樣的策略進行合併。
程式碼理解
const mixin = { methods: { foo: function () { console.log('foo') }, conflicting: function () { console.log('from mixin') } } } const vm = new Vue({ mixins: [mixin], methods: { bar: function () { console.log('bar') }, conflicting: function () { console.log('from self') } } }) vm.foo() // => "foo" vm.bar() // => "bar" vm.conflicting() // => "from self"
全域性混合
也可以全域性註冊混合物件。注意使用! 一旦使用全域性混合物件,將會影響到 所有 之後建立的 Vue 例項
// 為自定義的選項 'myOption' 注入一個處理器。 Vue.mixin({ created: function () { var myOption = this.$options.myOption if (myOption) { console.log(myOption) } } }) new Vue({ myOption: 'hello!' }) // => "hello!"
再瞭解了基本用法後再簡單過一遍原始碼加深印象
// 原始碼地址 https://github.com/vuejs/vue/blob/52719ccab8fccffbdf497b96d3731dc86f04c1ce/src/core/util/options.js#L365 export function mergeOptions ( parent: Object, child: Object, vm?: Component ): Object { // flow語法,表明返回的是一個物件 if (process.env.NODE_ENV !== 'production') { checkComponents(child) } if (typeof child === 'function') { child = child.options } normalizeProps(child, vm) normalizeInject(child, vm) normalizeDirectives(child) const extendsFrom = child.extends //若存在extends,則將其內容合併到父物件parent中儲存,最後再和自身child合併 if (extendsFrom) { parent = mergeOptions(parent, extendsFrom, vm) } // 若存在mixins,則將其內容合併到父物件parent中儲存,最後再和自身child合併 if (child.mixins) { for (let i = 0, l = child.mixins.length; i < l; i++) { parent = mergeOptions(parent, child.mixins[i], vm) } } //初始化一個物件,用於儲存parent和child合併後的內容,並作為mergeOptions函式的結果返回 const options = {} let key for (key in parent) { mergeField(key) } for (key in child) { if (!hasOwn(parent, key)) { mergeField(key) } } //使用策略物件對parent和child進行合併 function mergeField (key) { const strat = strats[key] || defaultStrat options[key] = strat(parent[key], child[key], vm, key) } return options } export function initMixin (Vue: GlobalAPI) { Vue.mixin = function (mixin: Object) { this.options = mergeOptions(this.options, mixin) return this } }
總結
mixin就是採取一定規則將一個功能(元件)的屬性混合到另一個元件或者全域性當中,優點就是靈活度高,耦合度低,便於維護
關於JS每日一題
JS每日一題可以看成是一個語音答題社群
每天利用碎片時間採用60秒內的語音形式來完成當天的考題
群主在次日0點推送當天的參考答案
- 注 絕不僅限於完成當天任務,更多是查漏補缺,學習群內其它同學優秀的答題思路
搜尋微信公眾號:JS每日一題