今天有这样一个需求,在一个列表上有个按钮,点击按钮后显示提示框,框内展示二维码,如果此时直接在表格上二维码按钮处这样写:
eqrFun(row){
//展示对话框
this.showEqr = true
//获取二维码实例
this.$refs['qrcode'].innerHTML = ''
}
此时就会发现通过ref拿到的二维码实例居然是一个undefined,经过检查核实没有书写错误,此时忽然想到应该就是渲染顺序的问题,对话框的显示隐藏实质上类似于v-if,控制了页面上元素的显示隐藏。此时如果直接获取ref页面还没有来得及渲染获取的实例,因此只能拿到undefined。
解决方法:
vue中有一个非常nice的语法糖:this.$nextTick
这个语法糖可以在下次DOM更新循环结束之后执行延迟回调,可以在修改数据之后立即使用这个方法获取更新后的DOM。
因此可以直接这样写:
eqrFun(row){
//展示对话框
this.showEqr = true
this.$nextTick(()=>{
//获取二维码实例
this.$refs['qrcode'].innerHTML = ''
})
}
这样子就可以在点击对话框的函数中拿到二维码的实例啦!!!
有这样几个扩展,拿不到实例大概就是这两种情况:
- 元素是在组件
mounted
生命周期钩子中动态生成的 - 使用
v-if
或v-show
条件渲染的元素
如果元素是在mounted中动态生成的可以这样用:
export default {
mounted() {
this.$nextTick(() => {
// 在页面渲染完毕后执行
// 此时可以获取到元素的引用
});
}
}
如果是使用v-if或v-show条件渲染的元素
export default {
methods: {
showElement() {
this.show = true;
this.$nextTick(() => {
// 元素显示后执行
// 此时可以获取到元素的引用
});
}
}
}