今天发现一个奇怪的问题,在 Vue2
中 动态组件上使用 ref
获取子组件方法会出现一个奇怪的问题:
代码很简单,一个动态组件,点击按钮切换 Home1
和 Home2
,他们两个中都有一个叫 test
的方法。
父组件:
<template>
<div id="app">
<components ref="com" :is="component" />
<button @click="change">change</button>
</div>
</template>
<script>
import Home1 from './home1'
import Home2 from './home2'
export default {
name: 'App',
components: {
Home1,
Home2
},
data() {
return {
component: 'Home1'
}
},
methods: {
change() {
this.component = this.component === 'Home1' ? 'Home2' : 'Home1'
this.$nextTick(() => {
console.log(this.$refs.com.test)
})
}
}
}
</script>
Home1:
<template>
<div>home1</div>
</template>
<script>
export default {
name: "home1",
methods: {
test(val) {
console.log('Home1 --' + val)
}
}
}
</script>
Home2:
<template>
<div>home2</div>
</template>
<script>
export default {
name: "home2",
methods: {
test(val1, val2) {
console.log('Home2 --' + val1 + val2)
}
}
}
</script>
按照预期,在切换动态组件 $nextTick
之后去输出 test
方法,应该是分别输出两个组件内的 test
方法,但我测试下来(Chrome浏览器),每次输出的都是 Home2
组件中的 test
方法:
当然如果把 父组件 中的代码改为,就都没问题:
change() {
this.component = this.component === 'Home1' ? 'Home2' : 'Home1'
this.$nextTick(() => {
this.$refs.com.test(1, 2) // 直接去执行,结果没问题
// Home2 -- 12
// Home1 -- 1
// Home2 -- 12
// Home1 -- 1
// ...
// console.log(this.$refs.com.test.length) // 或者输出参数长度,没问题
// 2
// 1
// 2
// 1
// ...
})
}
最让我不解的是,只要在方法中随便哪里加个 console.log
,他也正常了!
change() {
this.component = this.component === 'Home1' ? 'Home2' : 'Home1'
this.$nextTick(() => {
console.log(1) // 加在方法里哪都行
console.log(this.$refs.com.test)
})
}
碰到过类似问题,估计是console.log是异步的,并非总是准确。这种情况,最好直接在页面节点中输出你想debug的值,很有可能实际组件中的值是对的,而只是console.log出来不对。