Vue.js 3 如何等指定模板渲染完成后再渲染其余部分内容?
问题根因
Vue的$refs是非响应式的,初始渲染阶段v-for遍历生成的some组件还未完成挂载,$refs中对应的组件实例还未被赋值,此时直接在connection组件的属性中读取$refs下的方法就会抛出未定义异常。
可行解决方案
核心思路是增加渲染状态控制,等到所有some组件完成挂载、$refs全部赋值后,再渲染connection组件:
- 在data中新增状态位
isComponentsReady,初始值设为false,用于控制连接组件的渲染时机 - 在父组件
mounted钩子中调用$nextTick,确保所有子组件挂载完成后将isComponentsReady设为true - 给
connection组件增加v-if="isComponentsReady"判断,仅在组件准备完成后才渲染连接路径
如果项目中存在多层嵌套组件,单次$nextTick无法保证子组件全部挂载完成,可以叠加两层$nextTick确保渲染时序正确。
修改后的完整代码
<template> <div> <some v-for="(i, id) in items" :key="id" :ref="id"/> <connection v-if="isComponentsReady" v-for="(c, id) in cons" :key="id" :x0="items[c.src].x + $refs[c.src].width() / 2" :y0="items[c.src].y + $refs[c.src].height() / 2" :x1="items[c.dst].x + $refs[c.dst].width() / 2" :y1="items[c.dst].y + $refs[c.dst].height() / 2" /> </div> </template> <script> export default { data() { return { items: { "i1": {x: 100, y: 100}, "i2": {x: 820, y: 200}, }, cons: { "c1": {src: "i1", dst: "i2"} }, isComponentsReady: false } }, mounted() { // 等待所有子组件挂载完成后再开启连接组件渲染 this.$nextTick(() => { // 校验所有item对应的ref都已初始化 const allRefReady = Object.keys(this.items).every(id => this.$refs[id]) if (allRefReady) { this.isComponentsReady = true } }) } } </script>
动态场景适配
如果你的items会动态增减,只需在items变更的逻辑后手动调用一次上述的$nextTick校验逻辑,更新isComponentsReady状态即可。
内容的提问来源于stack exchange,提问作者Anton Ovsyannikov
相关产品推荐
相关产品推荐

