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

兄弟们,问个 Vue3 reactive 的问题

  •  
  •   Goalonez · 2023-09-28 11:55:24 +08:00 · 1954 次点击
    这是一个创建于 425 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我不太懂前端,但是最近因为工作需要,所以尝试了一下 Vue3 + TS. 想问下 reactive 正确的更新数据做法应该是怎么样的?

    下面是我的疑惑,比如我定义了一个 interface

    export interface Demo {
      id: number;
      demoNumber: number;
      demoPrice: number;
      demoText: string;
      demoStatus: string;
      demoTime: number;
    }
    

    然后我创建了一个变量(不指定 Demo 类型,似乎编辑器上就没法对字段进行提示,并且我只希望在 interface 写一次属性而不用在其他地方重复写,所以加了 as Demo)

    const demo = reactive({}) as Demo;
    

    这时候我通过后端接口拿到了数据之后,我要怎么更新到这个用 reactive 响应式的 demo 对象里?我试了没办法直接 demo = 后端数据,或者 demo.value = 后端数据之类的赋值. 我看官方文档 ref 是用来定义基础数据类型的,可以直接.value 进行赋值,但是 reactive 不行,我搜了下只找到对象合并或者定义变量的时候多套一层数据结构,例如

    const demo = reactive({ data: {} as Demo });
    

    这样的话我确实可以对 demo.data = 后端数据进行赋值,但是这样我在取数据的时候都需要 demo.data.xxxxx,而无法直接用 demo.xxx 获取,就总感觉写起来怪怪的.

    15 条回复    2023-09-30 10:16:55 +08:00
    zzlit
        1
    zzlit  
       2023-09-28 13:43:33 +08:00
    reactive 接收一个泛型定义类型,但是这样就要给初始值了,如下:
    const demo = reactive<Demo>({
    id: xxx,
    demoNumber: xxx,
    demoPrice: xxx,
    demoText: xxx,
    demoStatus: xxx,
    demoTime: xxx
    });

    更新的话只能 demo.id = xxx 这样,或者直接 Object.assign(demo, xxx)更新整个。
    MAGA2022
        2
    MAGA2022  
       2023-09-28 13:48:32 +08:00
    用 ref
    yaodao
        3
    yaodao  
       2023-09-28 13:54:37 +08:00
    如果要更新整个响应式对象,应该使用 ref ,reactive 一般适用于 data.a = xxx, data.b = xxx 这种对象中的单个属性更新的方式。
    zglw2012
        4
    zglw2012  
       2023-09-28 13:55:27 +08:00
    ref 其实就是 reactive({value:_}),把 interface 直接换成 class 会简单的多,const demo = reactive(new Demo()),此时 demo 还是有代码提示的,修改的时候直接在 class 里用 method 就行了。模板绑定的时候,直接绑定 demo.id ,调用方法就在模板里写 demo.method()
    smthok
        5
    smthok  
       2023-09-28 14:01:33 +08:00   ❤️ 1
    import { ref, Ref } from 'vue'

    interface Demo {
    id: number;
    demoNumber: number;
    demoPrice: number;
    demoText: string;
    demoStatus: string;
    demoTime: number;
    }

    const demo = ref({}) as Ref<Demo>

    demo.value.id = 1
    demo.value.demoNumber = 2
    qb20150806
        6
    qb20150806  
       2023-09-28 14:19:28 +08:00
    interface Demo {
    id: number;
    demoNumber: number;
    demoPrice: number;
    demoText: string;
    demoStatus: string;
    demoTime: number;
    }
    const groundData=ref<Demo[]>([]);
    groundData.value=[];
    Curtion
        7
    Curtion  
       2023-09-28 14:32:08 +08:00
    使用 ref, 需要.value, 就是这么奇怪
    Goalonez
        8
    Goalonez  
    OP
       2023-09-28 15:34:07 +08:00
    感谢各位,目前已经改成了 ref 的方式,模板上可以做到不需要.value 直接绑定,函数里只能用.value 了.
    Daotin
        9
    Daotin  
       2023-09-28 16:40:44 +08:00
    建议使用 ref 取代 reactive 。

    顺便,这个写错了:const demo = reactive({}) as Demo;

    应该是:const demo = reactive({} as Demo); 或者 const demo = reactive<Demo>({})
    jspatrick
        10
    jspatrick  
       2023-09-28 17:11:56 +08:00
    我的看法是全都 reactive 一把梭,这种情况 #1 提的 Object.assign 就很适合,除了获取 template 里的用 ref ,别的都能用 reactive 替代
    lDqe4OE6iOEUQNM7
        11
    lDqe4OE6iOEUQNM7  
       2023-09-28 18:02:05 +08:00
    import { reactive } from 'vue';

    export interface Demo {
    id: number;
    demoNumber: number;
    demoPrice: number;
    demoText: string;
    demoStatus: string;
    demoTime: number;
    }

    const demo = reactive({} as Demo);

    // 假设 newData 是从后端接口获取的新数据
    const newData: Demo = {
    id: 1,
    demoNumber: 10,
    demoPrice: 100,
    demoText: 'Hello',
    demoStatus: 'Active',
    demoTime: 1632736800
    };

    // 用 Object.assign 更新 reactive 对象的数据
    Object.assign(demo, newData);
    ljsh093
        12
    ljsh093  
       2023-09-28 20:30:17 +08:00
    @smthok #5 ref<Demo>({})
    ljsh093
        13
    ljsh093  
       2023-09-28 20:30:37 +08:00
    @ljsh093 #12 `ref<Demo>({})`
    ipcjs
        14
    ipcjs  
       2023-09-29 00:40:02 +08:00
    对前端不熟,还是 JS 一把梭吧,Vue3 对 TS 的支持贼蛋比🤪
    yrj
        15
    yrj  
       2023-09-30 10:16:55 +08:00
    还是看你业务需求吧,
    只需要全量更新 :ref
    只需要个别属性更新:reactive
    都需要更新:参考一楼的方法
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3557 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 10:49 · PVG 18:49 · LAX 02:49 · JFK 05:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.