在vue2中,我们使用ref获取dom元素时是这样子的:
// 父组件
<template>
<div>
<button @click=handleClick>我装载了一个子组件!</button>
<son ref="dataList"></son>
</div>
</template>
<script>
import son from './data.vue'
export default {
components: {
son
},
methods:{
handleClick(){
console.log(this.$refs.dataList) //像这样!
}
}
}
</script>
在vue3中,我们使用ref获取dom元素时是这样子的:
// 父组件
<template>
<button @click=handleClick>我装载了一个子组件!</button>
<son ref="dataList"></son>
</template>
<script>
import {ref} from 'vue'
import son from './data.vue'
export default {
setup(){
const dataList=ref(null)
const handleClick=()=>{
console.log(dataList.value) //像这样!
}
return{
dataList //这里要抛出响应式数据才可使用。
}
}
}
</script>
下面来说说vue3中获取dom为空的原因:
setup的return中应该抛出ref封装的字段,否则ref的值只是定义了并不能响应式使用,事实上,所有ref或者reactive定义的值都应在return中抛出。
直接在setup()中打印。这就是生命周期的问题了,setup本质上相当于vue2中的created,在创建阶段,dom元素还未完全创建完成,此时获取dom自然为null了。上面的例子中我是在点击按钮中触发的,此时早已经过创建阶段,如果你想更早,可以手动定义onMented去打印,如下:
import {ref,onMented} from 'vue'
export default {
setup(){
const dataList=ref(null)
onMented(()=>{
console.log(dataList.value) //像这样!
})
return{
dataList
}
}
}
- 如果你在使用时出现ref.value取不到子组件里的值,或者报错ref.value对象为空的情况,那是因为子组件要把能够被负组件调用的方法暴露出来,在子组件里加上defineExpose就可以啦。
defineExpose({
onOpen //这是你要调用的方法名
});
版权归原作者 进击的potato 所有, 如有侵权,请联系我们删除。