Vue 3 setup()渲染vnode数组无响应原因及可行性问询
问题原因
你没有遗漏任何配置项,Vue 3 渲染函数完全支持传入预定义的vnode数组,失效是写法不符合响应式触发逻辑导致的:
setup()函数仅会在组件初始化阶段执行一次,你预先声明的let buttons = [base_offset.value]是普通数组,在初始化时就取了当时base_offset的静态值写入,后续响应式状态更新不会自动触发这个数组重新取值。- 直接将数组写在h函数子节点参数时能生效,是因为每次响应式状态变更触发组件重渲染时,h函数的所有参数都会重新求值,自然能拿到最新的
base_offset.value。
解决方案
推荐将渲染逻辑封装为动态取值的形式,常用有两种实现方式:
方式1:封装节点生成函数(更推荐)
把按钮列表的生成逻辑封装为函数,每次组件重渲染时自动执行函数拿到最新的节点数组:
import { ref, computed, h } from 'vue' setup(props, {emit, slots}) { const base_number = ref(1) const base_offset= computed(()=> { return base_number.value + 2 }) // 封装为取值函数,每次调用时获取最新状态生成数组 const getButtons = () => [base_offset.value] const pageClick = (event , pageNumber ) => { base_number.value = 3 } // setup返回渲染函数,每次响应式更新都会重新执行生成最新vnode return () => h("ul",{ class: "pagination", onClick: event => { pageClick(event, 1) } }, getButtons()) }
方式2:将数组声明为响应式对象
如果需要预先维护数组,可以用 ref 或 reactive 包裹数组,配合 watch 监听依赖状态变化手动更新数组:
import { ref, computed, watch, h } from 'vue' setup(props, {emit, slots}) { const base_number = ref(1) const base_offset= computed(()=> { return base_number.value + 2 }) // 声明为响应式数组 const buttons = ref([base_offset.value]) // 监听依赖变化更新数组 watch(base_offset, (newVal) => { buttons.value = [newVal] }, { immediate: true }) const pageClick = (event , pageNumber ) => { base_number.value = 3 } return () => h("ul",{ class: "pagination", onClick: event => { pageClick(event, 1) } }, buttons.value) }
如果是复杂的多节点列表,更推荐第一种方案,不需要手动维护响应式更新逻辑,代码更简洁。
内容的提问来源于stack exchange,提问作者MooCow
相关产品推荐
相关产品推荐

