如上图,报错提示hw2cO为undefined!而看vue教程中作用域插槽就是这么用的,很疑惑!
上代码:
子组件:
<template>
<div class="zs">
我是HelloWorld2的孩子,这是祖先给我的{{toZS}}
<slot></slot>
<slot name="slot1"></slot>
<slot name="slot2"></slot>
<slot :hw2c="hw2c" :hw2cO="hw2cO"></slot>
</div>
</template>
<script>
export default {
inject: ['toZS'],
data() {
return {
hw2c: 'hw2c',
hw2cO: {
a: 'I am a',
b: 'I am b'
}
};
}
};
</script>
<style>
.zs{
background-color: aqua;
}
</style>
父组件:
<template>
<div>
<p class="hw2-p" @click="$parent.$emit('foo', hw2)">我是HelloWorld2</p>
<p class="hw2-p" @click="$bus.$emit('sjzx', 1122)">我是HelloWorld2...</p>
<HelloWorld2C>
我的匿名插槽
<template name="slot1">
我是具名插槽1
</template>
<template name="slot2">
我是具名插槽2
</template>
<template v-slot="{hw2c, hw2cO}">
作用域插槽:
{{hw2c}}
{{hw2cO.a}}
</template>
</HelloWorld2C>
</div>
</template>
<script>
import HelloWorld2C from './HelloWorld2C.vue';
export default {
name: 'HelloWorld2',
components: {
HelloWorld2C
},
data() {
return {
hw2: 'hw2'
};
}
};
</script>
<style>
.hw2-p {
background-color: blue;
color: red;
width: 200px;
height: 60px;
display: inline-block;
padding-top: 5%;
}
</style>
将父组件中{{hw2cO.a}}改成{{hw2cO && hw2cO.a}}就不会报错!但是为什么呢?
于是在父组件中写出生命周期函数如下:
beforeCreate() {
console.log('----beforeCreate----');
console.log(this.$children && this.$children.length && this.$children[0] && this.$children[0].hw2cO);
},
created() {
console.log('----created----');
console.log(this.$children && this.$children.length && this.$children[0] && this.$children[0].hw2cO);
},
beforeMount() {
console.log('----beforeMount----');
console.log(this.$children && this.$children.length && this.$children[0] && this.$children[0].hw2cO);
},
mounted() {
console.log('----mounted----');
console.log(this.$children && this.$children.length && this.$children[0] && this.$children[0].hw2cO);
}
发现mounted之前都是获取不到hw2cO的,而报错也是出现在mounted之前。这样就能解释为什么会报错。
我的理解是:父组件mounted之前就执行到了插槽部分的template里面,只是子组件还没挂载上去,所以拿不到子组件的数据。而真正渲染要等到子组件挂载上去才会执行,所以改成hw2cO && hw2cO.a不会报错。那么用到作用域插槽的同学就要注意了,有以上用法的需要在前面加个判断兼容一下~
不知道我的理解是否正确,需要更熟悉的同学帮忙解答下!谢谢~