vue中使用mixins/extends傳入參數的方式
使用mixins/extends傳入參數
最近做報表頁面,基本都是列表頁面,所以想用mixins。
但是接口的url不同,於是考慮怎麼才能傳入參數去適配各個頁面。
後來發現mixin文件可以寫個函數,接受傳遞過來的參數,然後return一個對象。
大概如下:
mixin.js
export default function(config) { let { listUrl="", exportUrl="" } = config; return { created() { console.log(listUrl); console.log(exportUrl); } } }
xxx.vue
import Mixin from './mixin'; let mixin = new Mixin({ listUrl: "www.baidu.com", exportUrl: "www.yahu.com" }) export default{ mixins:[mixin], }
extends也是差不多。
vue mixins的原理
以前一直以為mixins在vue裡面應該不是很重要,隻是提供瞭一個混入的api,慢慢的才知道mixin在vue裡面非常重要。生命周期、vuex等都有mixin的影子,在內部算是很重要的一個api。
先上精簡過後的源碼:
export const LIFECYCLE_HOOKS = [ 'beforeCreate', 'created', 'beforeMount', 'mounted', 'beforeUpdate', 'updated', 'beforeDestroy', 'destroyed', ] const strats = {}; function mergeHook(parentVal, childValue) { if (childValue) { if (parentVal) { return parentVal.concat(childValue); } else { return [childValue] } } else { return parentVal; } } LIFECYCLE_HOOKS.forEach(hook => { strats[hook] = mergeHook })
上面這部分很好理解,是生命周期的合並,下面判斷有這些生命周期的key的時候,直接調用strats[key](parent[key], child[key]),我們都知道生命周期的mixins是先執行mixins的再執行當前組件的,所以直接concat,後面執行循環調用的時候就是這個順序。
export function mergeOptions(parent, child) { const options = {} if (child.mixins) { for (var i = 0, l = child.mixins.length; i < l; i++) { var mixin = child.mixins[i]; parent = mergeOptions(parent, mixin); } } for (let key in parent) { mergeField(key) } for (let key in child) { if (!parent.hasOwnProperty(key)) { mergeField(key); } } function mergeField(key) { if (strats[key]) { options[key] = strats[key](parent[key], child[key]); } else { if (typeof parent[key] == 'object' && typeof child[key] == 'object') { options[key] = { ...parent[key], ...child[key] } }else{ options[key] = child[key]; } } } return options }
這邊生命周期是單獨判斷,其他熟悉方法則是一起的,比如方法methods,如果父和子都有,就結構合並在一起。因為mixins用法可以傳入一個數組,這邊還需要優先判斷是否有mixins字段,有就要遞歸合並。
核心有瞭其他都是調用瞭,比如把mixin方法掛載到vue上可以直接調用:
Vue.mixin = function (mixin) { // 將屬性合並到Vue.options上 this.options = mergeOptions(this.options,mixin); return this; }
初始化的時候先合並一次,生命周期也是,在狀態初始化之前先調用beforeCreate,初始化之後調用created,源碼搜索Vue.prototype._init這個方法裡面就能看見,包括其他生命周期,可以搜索callhook去看看:
vm.$options = mergeOptions(vm.constructor.options,options); callHook(vm,'beforeCreate');
// 初始化狀態
initState(vm); callHook(vm,'created');
callHook就是循環調用生命周期:
export function callHook(vm, hook) { const handlers = vm.$options[hook]; if (handlers) { for (let i = 0; i < handlers.length; i++) { handlers[i].call(vm); } } }
mixin方法核心就是合並實例的屬性,watch、methods、data等,也可以新增一開始沒有的屬性,比如vuex的$store。
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。