前端小白,在学习Vue 3 响应式数据的时候,遇到了一个问题
<script lang="ts"> export default{ name:"test", }</script><script lang="ts" setup> import {toRefs,ref,reactive} from "vue"; let person = reactive({aa:"abc",bb:123}) function c(){ console.log(1) console.log(person) Object.assign(person,{aa:"121231",bb:12131}) person = {aa:"hhh",bb:13} person = {aa:"hh",bb:132} console.log(person) } </script><template> <span>姓名:{{person.aa}} </span> <br> <button @click="c">点击修改数据</button></template>
vue3官方文档中有如下说明
对于上面的代码和文档描述,按理说结果是姓名:121231
,但是实际运行结果是姓名:hh
如果Object.assign(person,{aa:"121231",bb:12131})
不存在,或者说不是先执行,确实是无法在页面上修改数据为hh,但是只要这一行代码存在并且先执行,就会修改为hh
根据上述现象,初步判断可能是Object.assign(person,{aa:"121231",bb:12131})
代码副作用,查了MDN,说该API会调用get/set方法。
虽然vue是通过监听set/get方法实现的响应式渲染,上述mdn内容只是说明了Object.assign(person,{aa:"121231",bb:12131})
为什么有效,但是还是不能解决我的疑惑
希望大佬说一下原因
你的问题主要在于理解Vue 3的响应式系统和Object.assign
如何交互。
Vue 3使用了一个新的响应式系统,该系统基于Proxy对象,而不是之前版本中的Object.defineProperty。当你在Vue组件中创建一个响应式对象时,Vue实际上会返回一个特殊的Proxy对象,该对象拦截了读取和设置属性的操作。当属性被设置时,Vue会知道该属性已经被修改,并重新渲染依赖于该属性的部分。
现在,让我们看看Object.assign
是如何工作的。这个函数会遍历源对象的所有可枚举属性,并将它们复制到目标对象中。如果目标对象已经有了同名属性,那么这些属性将被源属性覆盖。
在你的代码中,Object.assign(person,{aa:"121231",bb:12131})
会将{aa:"121231",bb:12131}
这个对象的所有属性复制到person
对象中。由于person
是一个Vue响应式对象,当它的属性被设置时,Vue会知道这些属性已经被修改,并重新渲染依赖于这些属性的部分。
然而,你需要注意的是,Object.assign
并不会返回一个新的对象,而是返回目标对象。在你的代码中,person
就是目标对象。因此,当你执行person = {aa:"hhh",bb:13}
和person = {aa:"hh",bb:132}
时,你实际上是在改变person
的引用,而不是它的属性。由于Vue不会检测到对象引用的改变(只有当一个响应式对象的引用被改变时,Vue才会标记它为“dirty”),因此Vue不会重新渲染依赖于person
的任何部分。
这就是为什么你看到的结果是“姓名:hh”,而不是“姓名:121231”。如果你希望在改变对象属性时能够触发Vue的重新渲染,你应该直接设置对象的属性,而不是改变对象的引用。例如,你可以使用解构赋值来更改对象的属性:
person = { ...person, aa: "hh", bb: 132 };
在这个例子中,由于我们没有改变person
的引用,只有它的属性被改变,因此Vue会检测到这个变化并重新渲染依赖于person
的任何部分。
例如我创建了一个dataHook main.ts中 页面有个按钮就执行v.value += 1,为什么console.log还是原值1呢?
本文向大家介绍Vue3 响应式侦听与计算的实现,包括了Vue3 响应式侦听与计算的实现的使用技巧和注意事项,需要的朋友参考一下 响应式侦听和计算 有时我们需要依赖于其他状态的状态——在 Vue 中,这是用组件 计算属性 处理的,以直接创建计算值,我们可以使用 computed 方法:它接受 getter 函数并为 getter 返回的值返回一个不可变的响应式 ref 对象。 我们先来看看一个简单的
如题,定义一个组件,设置 props 如下: 当我直接定义 的时候,会提示这样会失去响应性 所以想问下,如何可以将这样的定义,转为响应性
vue3 响应式无法更新 下面是最小复现代码 https://play.vuejs.org/#eNqVVs2O2zYQfhVWF2kBV27QnlzbaJIu2vTQD... 点击“修改值”这个按钮,最上层组件能够更新值, 但是最内层的组件无法监听到值被改变了
在vue3框架中,我使用ref定义了一个变量,但是发现在更新其数据之后,页面上并不会有响应式变化,具体表现是在更新数据之后不会出现表格最前面的选择框 数据定义 数据初始化,其中list是一个数组,具有唯一的id属性 组件A中定义了计算属性rowSelection 当点击一个按钮之后,触发BatchEdit函数,通过emit抛出新的rowSelection 在父组件中进行事件定义并更新内容 rowS
什么时候需要将vue2升级到vue3? 面试被问到什么场景需要使用vue3,应该如何回答