VueJS设置子组件Props后调用其函数的竞态条件解决方案
问题场景
我有一个用于Canvas绘制的Child.vue组件,希望在Parent.vue中修改Child.vue的各类Props后,调用其render()方法完成重绘。
遇到的问题:在Parent.vue中执行handleClick()时,Child.vue的Props尚未完成传递就调用了render()方法,导致重绘不生效,第二次点击才能正常重绘。目前用延时的临时方案可以解决:
// 基于延时的临时修复方案 const delay = (ms:number) => new Promise(res => setTimeout(res, ms)) const handleClick = async () => { color.value = 'blue' size.value = 50 await delay(10) childRef.value?.render() }
实际项目中,每次调用render()前需要修改的Props数量不固定,有时1个,有时多个,无规律可循,想找合适的方法解决这个竞态条件。
已解决方案
通过nextTick()方法解决了该问题,代码如下:
import { ref, useTemplateRef, nextTick } from 'vue' // ...其他代码 const handleClick = () => { color.value = 'blue' size.value = 50 nextTick(() => { childRef.value?.render() }) }
组件代码
Child.vue
<script setup lang="ts"> import { onMounted, useTemplateRef } from 'vue' interface Props { color?: string size?: number } const { color = 'red', size = 10, } = defineProps<Props>() const canvasRef = useTemplateRef('canvas-ref') let canvas:HTMLCanvasElement let ctx:CanvasRenderingContext2D onMounted(() => { canvas = canvasRef.value as HTMLCanvasElement ctx = canvas.getContext("2d") as CanvasRenderingContext2D render() }) const render = () => { ctx.clearRect(0, 0, 100, 100) ctx.fillStyle = color ctx.fillRect(0, 0, size, size) } defineExpose({ render }) </script> <template> <canvas ref="canvas-ref" :width="100" :height="100"></canvas> </template>
Parent.vue
<script setup lang="ts"> import Child from './Child.vue' import { ref, useTemplateRef } from 'vue' const childRef = useTemplateRef('child-ref') const color = ref() const size = ref() const handleClick = () => { color.value = 'blue' size.value = 50 childRef.value?.render() } </script> <template> <Child :color=color :size=size ref="child-ref" /> <button @click=handleClick>button</button> </template>
内容的提问来源于stack exchange,提问作者pelevesque
相关产品推荐
相关产品推荐

