V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
sunorg
V2EX  ›  Vue.js

组件持久化的问题请教

  •  
  •   sunorg · 31 天前 · 1549 次点击
    有一个需求,高了快 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 里的子父节点交换时,组件会被重新渲染初始化,丢失了状态。 使用过,因为没有共享数据的需求,也尝试过直接存组件状态的,但该丢失还是丢失。


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


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

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

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

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

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

    <div v-for>
    <KeepAlive>
    <component :is=ref />
    </KeepAlive>
    </div>
    sunorg
        15
    sunorg  
    OP
       30 天前
    @zhhbstudio
    @wangtian2020
    @arnotong

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


    最终使用了 css 的 grid 类来中间实现,多了很多计算高度偏移的工作,但大体解决了问题,
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3480 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 00:50 · PVG 08:50 · LAX 17:50 · JFK 20:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.