sunorg
V2EX  ›  Vue.js

组件持久化的问题请教

  •  
  •   sunorg · Mar 6, 2025 · 3532 views
    This topic created in 617 days ago, the information mentioned may be changed or developed.
    有一个需求,高了快 2 天,没搞定,请教下达人。

    需求:
    const data=ref({
    id:xxx,ref:关联某个组件,children:[
    id:xxx,ref:关联某个组件,children:[]
    id:xxx,ref:关联某个组件,children:[]
    ]
    })

    ------------
    尝试 1: 动态渲染:
    <KeepAlive>
    <component :is="某 item.ref" />
    </KeepAlive>

    尝试 2:全局注册一个组件池,存储先实例化的组件,然后通过索引方式来挂载
    <KeepAlive>
    <DirectiveWrapper
    :component-id="某 item.componentId"
    :component="getComponentById(某 item.componentId)"
    />
    </KeepAlive>



    问题:
    当 ref 可以在 data 里的子父节点交换时,组件会被重新渲染初始化,丢失了状态。 使用过,因为没有共享数据的需求,也尝试过直接存组件状态的,但该丢失还是丢失。


    需要大家给点思路方向,需要解决指定组件不被重新渲染。
    Supplement 1  ·  Mar 7, 2025
    验证过了,基于 data 这个结构来动态渲染组件,因为 component 在节点树上来回变化,会导致 dom 重新渲染,即使使用可 keepalive ,加 nanme 加 key 或者组合 v-show ,都会导致全新渲染。


    最终使用了 css 的 grid 类来中间实现,多了很多计算高度偏移的工作,但大体解决了问题,组件不在被重新渲染。
    15 replies  •  2025-03-07 10:13:17 +08:00
    0xbe
    0xbe
    Mar 6, 2025
    1
    KeepAlive
    sunorg
    sunorg
    OP
    Mar 6, 2025
    2
    @acoo 已经使用过了,当 data 里的某个组件变更位置后,重新渲染了。
    sundev
    sundev
    Mar 6, 2025
    3
    KeepAlive 的组件必须要有 Name ,是不是这个问题?
    sunorg
    sunorg
    OP
    Mar 6, 2025
    4
    @sundev 应该也不是这个。

    KeepAlive 似乎只能在同一个挂载点保留组件实例, ,整个 DOM 结构发生了变化,挂在点变了。
    zhhbstudio
    zhhbstudio
    Mar 6, 2025
    5
    <zujian1 v-show="id==1">
    <zujian2 v-show="id==2">
    <zujian3 v-show="id==3">
    magicflower
    magicflower
    Mar 6, 2025 via Android
    6
    keepalive + v-show ?
    sunorg
    sunorg
    OP
    Mar 6, 2025
    7
    @zhhbstudio
    @magicflower

    里面的 websocket 链接信息会丢失重连。

    估计放弃,用其他法子
    lisongeee
    lisongeee
    Mar 6, 2025
    8
    store 状态提升到全局/组件外部,组件只保留纯渲染函数
    jardel
    jardel
    Mar 6, 2025
    9
    组件开发需要”变量提升“ store 或者父级组件里
    lanced
    lanced
    Mar 6, 2025
    10
    试试给组件加个 key ,不需要重新渲染的组件,不改变它的 key
    <KeepAlive>
    <component :is="item.ref" :key="item.id"/>
    </KeepAlive>
    really28
    really28
    Mar 6, 2025
    11
    <KeepAlive :include="cacheKeys">
    <component
    :is="item.ref"
    :key="item.uid" // 使用全局唯一的 ID
    v-show="item.visible"
    />
    </KeepAlive>

    关键点是 key 参数,确保每一个是唯一的
    zhhbstudio
    zhhbstudio
    Mar 6, 2025
    12
    v-show 不会丢啊,v-show 值为 false 时就是 style="display:none;"
    wangtian2020
    wangtian2020
    Mar 6, 2025
    13
    大不了不分组件了写在一个文件里不行吗
    arnotong
    arnotong
    Mar 6, 2025
    14
    可以试试这样:

    <div v-for>
    <KeepAlive>
    <component :is=ref />
    </KeepAlive>
    </div>
    sunorg
    sunorg
    OP
    Mar 7, 2025
    15
    @zhhbstudio
    @wangtian2020
    @arnotong

    验证过了,基于 data 这个结构来动态渲染组件,因为 component 在节点树上来回变化,会导致 dom 重新渲染,即使使用可 keepalive ,加 nanme 加 key 或者组合 v-show ,都会导致全新渲染。


    最终使用了 css 的 grid 类来中间实现,多了很多计算高度偏移的工作,但大体解决了问题,
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   4461 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 51ms · UTC 06:44 · PVG 14:44 · LAX 22:44 · JFK 01:44
    ♥ Do have faith in what you're doing.