vue3项目实践心得-多次渲染同一svg + 理解v-if、transition、dom加载之间的顺序
🧡🧡需求🧡🧡
未点击查看答案按钮时,步骤3面板未展示内容(v-if控制)
点击查看答案按钮后,通过graphviz绘制并展示状态转换图,渲染在步骤2中,同时步骤3的v-if变为true,渲染出内容并且也渲染展示这张图
🧡🧡遇到的问题🧡🧡
- 渲染重复性:前端通过vue-graphviz库 使用svg渲染 后端传来的dot_str,从而绘制出这张svg状态转换图,问题出现在项目中需要展示两个同样svg,由于它们的id相同,根据共享原则,导致只渲染了一个
- 渲染时机:涉及v-if、transition、添加dom节点的操作,时机不对导致步骤3的svg图渲染不出来
🧡🧡解决思路🧡🧡
- 对于渲染重复性问题:利用cloneNode函数,复制一个新的svg,从而添加dom节点
const svg = viz.renderSVGElement(draw_dot['NFA'][0])
const svgClone = svg.cloneNode(true)
NFAs.value[0].appendChild(svg)
NFAs.value[1].appendChild(svgClone)
- 对于渲染时机:掌握vue3 transition文档中描述的enter钩子,应当确保v-if渲染后的dom生成后,再调用渲染函数(添加svg dom),之后再开始进行transiton过渡
const handleStep3_TransEnter = (el:Element, done:()=>void) => {
// console.log(NFAs.value)
// console.log('step333333333333333333')
if(!step3_open.value) return done()
// console.log(222)
// 此时元素已插入 DOM
nextTick().then(() => {
// console.log(NFAs.value)
// 确保 ref 已收集
if (NFAs.value.length >= 2) {
instance().then(viz => {
const svg = viz.renderSVGElement(draw_dot['NFA'][0])
const svgClone = svg.cloneNode(true)
NFAs.value[0].appendChild(svg)
NFAs.value[1].appendChild(svgClone)
draw_dot['NFA'][1] = true
})
}
})
}