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

2022-05-07 16:08:36 +08:00
 shilianmlxg
 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 也能实现我的功能啊

2763 次点击
所在节点    Vue.js
16 条回复
shilianmlxg
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
2022-05-07 16:37:56 +08:00
有没有可能是 const 的问题呢
Vegetable
2022-05-07 16:45:45 +08:00
啊这,解构会丢失响应,这不是文档里说的吗
kamilic
2022-05-07 16:47:32 +08:00
用 ref 大法好
Vegetable
2022-05-07 16:48:19 +08:00
shilianmlxg
2022-05-07 16:57:40 +08:00
@Vegetable 谢谢大佬
gouflv
2022-05-07 16:58:09 +08:00
watch 似乎更符合直觉
4196
2022-05-07 17:00:09 +08:00
shilianmlxg
2022-05-07 17:00:48 +08:00
@kamilic 所以很疑惑,按理说 reactive 是定义引用类型数据,但是如果要 数组更新 dom 的话 必须要这样写
let state = reactive({
list:[]
})
state.list.push() 这样才能保持 dom 也更新

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

所以现在能用 ref 都用 ref 了
Vegetable
2022-05-07 17:01:22 +08:00
看错了...你这个写法,我本地复制下来你的代码,是可以响应的。
4196
2022-05-07 17:04:53 +08:00
@shilianmlxg
const list = reactive([])
list.push(1)
同样没问题,你要么环境有问题,要么写法有问题
kamilic
2022-05-07 17:29:07 +08:00
@shilianmlxg 始终觉得 ref 最保险,因为解构实在是用得太频繁,我都想自己搞个 eslint 规则禁止用 reactive 了。
shilianmlxg
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
2022-05-07 21:58:07 +08:00
@shilianmlxg
@vue/composition-api 你用的是 Vue2 吧。它的并不是 Proxy 。
4196
2022-05-09 18:28:24 +08:00
@shilianmlxg
@vue/composition-api 这个还是 vue2 ,只是包装了一层 vue3 的同名的方法,没有 proxy ,

你这里是数组要用变更方法,checkedCities.splice( 0, Infinity );
shilianmlxg
2022-05-10 09:20:01 +08:00
@4196 #15 谢谢大佬。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/851397

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX