You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue 3 setup()渲染vnode数组无响应原因及可行性问询

问题原因

你没有遗漏任何配置项,Vue 3 渲染函数完全支持传入预定义的vnode数组,失效是写法不符合响应式触发逻辑导致的:

  1. setup() 函数仅会在组件初始化阶段执行一次,你预先声明的 let buttons = [base_offset.value] 是普通数组,在初始化时就取了当时 base_offset 的静态值写入,后续响应式状态更新不会自动触发这个数组重新取值。
  2. 直接将数组写在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 23:36:03