关于合并配置的一个问题(续)
来源:3-8 生命周期

FDirector
2019-06-27
老师,还是上一个问题,回复不能输入代码所以另开了一个,您看:
假如这样的一个情景:
let extendObj = {
updated:function(){
console.log("我是扩展的updated")
},
methods: {
add(){
console.log("我是扩展出来的ADD方法")
}
},
}
let app = new Vue({
el: '#app',
methods:{
add(){
console.log("我是原生的ADD方法");
}
},
updated() {
console.log("我是原生的updated");//
},
extends:extendObj
})
递归执行mergeOptions后得到的新的parent类似于这样:
parent: {
components: {},
directives: {},
filters: {},
_base: Vue,
// ......
updated:function(){
console.log("我是扩展的updated")
},
methods: {
add(){
console.log("我是扩展出来的ADD方法")
}
}
}
然后调用第一段for,结果是把parent混合在了一个空的{}上,这个{}就是options
for (key in parent) {
mergeField(key)
}
现在得到的结果类似这样:
options: {
components: {},
directives: {},
filters: {},
_base: Vue,
// ......
updated:function(){
console.log("我是扩展的updated")
},
methods: {
add(){
console.log("我是扩展出来的ADD方法")
}
}
}
然后调用第二段的for:
for (key in child) {
if (!hasOwn(parent, key)) {
mergeField(key)
}
}
此时child是这样的:
child: {
el: '#app',
methods:{
add(){
console.log("我是原生的ADD方法");
}
},
updated() {
console.log("我是原生的updated");
},
extends:extendObj
}
可是child的key——update已经存在于parent的key中,
所以 !hasOwn(parent, key) 返回 false,
mergeField(‘update’)被阻拦了,导致child.update没有得到执行mergeField,
因此无论mergeField对不同键的合并方法如何,child.update都没有获得和options合并的机会。
因此最终返回的options上的update不就是parent上的update,也就是extendObj上的update了么?
1回答
-
你再仔细看 mergeField 的代码
function mergeField (key) {
const strat = strats[key] || defaultStrat
options[key] = strat(parent[key], child[key], vm, key)
}
当执行
for (key in parent) {
mergeField(key)
}
的时候,如果 key 为 updated 的时候,执行 mergeField
进而执行 options[key] = strat(parent[key], child[key], vm, key),这不就已经合并了 child 了吗?212019-06-27
相似问题