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

vue3 中 怎么解构 reactive 里的对象,并且还同步 dom 更新

  •  
  •   shilianmlxg · 2022-05-07 16:08:36 +08:00 · 3007 次点击
    这是一个创建于 929 天前的主题,其中的信息可能已经有所发展或是发生改变。
     let state = reactive({
          people:{
            age:18,
            sex:'male',
            name:'mafeifei',
            weapon:'kar98'
          },
          projectName:'wh1te'
       })
    

    就是我想取一个 reactive 里的people的某一个属性,比如people里的name,保持people改变之后,我定义的解构的变量 name 也能同步

    比如

    const {name} = toRefs(state.people)
    const {projectName} = toRefs(state)
    

    我想让people里的name改变之后 我解构出来的name也能跟着改变,我用这个name去页面里面渲染新的name的值.

    但是我const {name} = toRefs(state.people)这个如果在方法里写才会是最新的,如果是在setup里写的话,还是最初的初始值. 就是我声明这个 reactive 的时候的值

    现在我做的是

    let lastName = computed(() => return state.people.name)
    

    只有watch或者computed才能实现我的功能

    请问大佬我是哪里写的不对吗 ,按理说 toRefs 也能实现我的功能啊

    16 条回复    2022-05-10 09:20:01 +08:00
    shilianmlxg
        1
    shilianmlxg  
    OP
       2022-05-07 16:10:52 +08:00
    https://juejin.cn/post/6981701152786104350

    我看到里面的大佬提到
    1 、ref 是对元数据的拷贝,修改响应式数据时不会影响之前的数据,视图会更新
    2 、toRef 和 toRefs 是对元数据的引用,修改响应式数据时,元数据也会改变,但是视图不会更新,toRef 修改的是对象的某个属性,toRefs 修改的是整个对象
    3 、toRefs 的使用场景:如果想让响应式数据和原来的数据关联起来同步更新,并且不更新视图,那么就可以使用 toRefs

    toRefs 不能实现 解构对象里的值 保持同步更新 并且 dom 也跟着更新吗
    yaphets666
        2
    yaphets666  
       2022-05-07 16:37:56 +08:00
    有没有可能是 const 的问题呢
    Vegetable
        3
    Vegetable  
       2022-05-07 16:45:45 +08:00
    啊这,解构会丢失响应,这不是文档里说的吗
    kamilic
        4
    kamilic  
       2022-05-07 16:47:32 +08:00
    用 ref 大法好
    shilianmlxg
        6
    shilianmlxg  
    OP
       2022-05-07 16:57:40 +08:00
    @Vegetable 谢谢大佬
    gouflv
        7
    gouflv  
       2022-05-07 16:58:09 +08:00 via iPhone
    watch 似乎更符合直觉
    shilianmlxg
        9
    shilianmlxg  
    OP
       2022-05-07 17:00:48 +08:00
    @kamilic 所以很疑惑,按理说 reactive 是定义引用类型数据,但是如果要 数组更新 dom 的话 必须要这样写
    let state = reactive({
    list:[]
    })
    state.list.push() 这样才能保持 dom 也更新

    或者就用 ref([])来定义数组

    所以现在能用 ref 都用 ref 了
    Vegetable
        10
    Vegetable  
       2022-05-07 17:01:22 +08:00
    看错了...你这个写法,我本地复制下来你的代码,是可以响应的。
    4196
        11
    4196  
       2022-05-07 17:04:53 +08:00
    @shilianmlxg
    const list = reactive([])
    list.push(1)
    同样没问题,你要么环境有问题,要么写法有问题
    kamilic
        12
    kamilic  
       2022-05-07 17:29:07 +08:00
    @shilianmlxg 始终觉得 ref 最保险,因为解构实在是用得太频繁,我都想自己搞个 eslint 规则禁止用 reactive 了。
    shilianmlxg
        13
    shilianmlxg  
    OP
       2022-05-07 17:30:49 +08:00
    @4196 这样写是可以改变 list 的值 但是不会刷新 dom
    比如这个 reset 就不会清除 dom 上的数组
    <template>
    <div>

    <el-button size="small" @click="add">添加</el-button>
    <el-button size="small" @click="reset">重置</el-button>

    <div>checkedCities:{{checkedCities}}</div>
    </div>
    </template>

    <script>
    import {reactive, ref} from '@vue/composition-api'

    export default {
    name: "hello3",
    setup() {
    let checkedCities = reactive([])
    function add () {
    checkedCities.push((Math.random() * 1000).toFixed(0))
    }
    function reset () {
    checkedCities.length = 0
    console.log('checkedCities',checkedCities)
    }
    return {
    checkedCities,
    add,
    reset
    }
    }
    }
    </script>
    mosade
        14
    mosade  
       2022-05-07 21:58:07 +08:00
    @shilianmlxg
    @vue/composition-api 你用的是 Vue2 吧。它的并不是 Proxy 。
    4196
        15
    4196  
       2022-05-09 18:28:24 +08:00
    @shilianmlxg
    @vue/composition-api 这个还是 vue2 ,只是包装了一层 vue3 的同名的方法,没有 proxy ,

    你这里是数组要用变更方法,checkedCities.splice( 0, Infinity );
    shilianmlxg
        16
    shilianmlxg  
    OP
       2022-05-10 09:20:01 +08:00 via iPhone
    @4196 #15 谢谢大佬。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1364 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 23:51 · PVG 07:51 · LAX 15:51 · JFK 18:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.