vue3 在点击事件中,怎么设置Proxy里[[target]]里的内容?

vue3的点击事件中,如果设置对象和数组类型的参数,会转成Proxy类型,比如@click="TestClick(item)",这个item是v-for中的item

通过import {toRaw} from '@vue/reactivity',使用var obj=toRaw(item)转换

然后问题来了,要在点击事件中给item添加设置属性值,或者添加新属性,调用toRaw转换。但是通过toRaw得到后的对象,修改属性或添加新属性失败了。

相关测试代码如下

<div v-for=(item,index) in testList >
<button @click="testClick(item)"></button>
</div>

import {toRaw} from '@vue/reactivity'

let testList=reactive([]);
const testClick=(item)=>{
var obj=toRow(item);
   if(obj.isRegist==false){
       console.log("组件未注册");
       obj.isRegist=true;
   }else{
       console.log("组件已注册");
    }
}

运行这段代码,多次点击同一个按钮,只会在控制台上,永远打印“组件未注册”,显然是没有设置Proxy里[[target]]里的属性成功,在点击事件中,有什么办法能直接设置Proxy里[[target]]里的属性吗

不要通过从testList去查找遍历设置,我想直接在Proxy里[[target]]里的设置属性值或添加新属性,怎么做?

阅读 2.4k
1 个回答

在Vue3中,如果在模板中传递一个对象或数组类型的参数,它会被自动转换为一个代理对象(Proxy),以便在属性值被更改时自动触发视图更新。而 toRaw 函数则可以将代理对象还原成原始对象。但是需要注意的是,如果对还原后的对象进行更改,那么这些更改不会触发视图更新,因为它们已经脱离了 Vue 的响应式系统。这就是你在点击事件中修改 toRaw 转换后的对象属性值或添加新属性失败的原因。

如果你想让更改后的对象属性能够触发视图更新,可以将代理对象传递给点击事件处理程序,然后在处理程序中修改代理对象的属性值或添加新属性。这样做可以确保更改后的对象仍然处于 Vue 的响应式系统中,从而可以正确地触发视图更新。

例如,在模板中使用 @click="TestClick(item)" 来调用点击事件处理程序 TestClick,你可以在 TestClick 中直接使用 item 对象,而不是使用 toRaw(item)。这样,对于 item 的任何更改都会触发视图更新。

<template>
  <div v-for="(item, index) in items" :key="index" @click="TestClick(item)">
    {{ item.name }}
  </div>
</template>

<script>
import { reactive } from 'vue';

export default {
  data() {
    return {
      items: reactive([
        { name: 'Apple', price: 1.5 },
        { name: 'Banana', price: 2.0 },
        { name: 'Orange', price: 1.0 }
      ])
    };
  },
  methods: {
    TestClick(item) {
      item.price += 0.1; // 触发视图更新
    }
  }
};
</script>

在上面的示例中,我们直接使用了 item 对象,而不是使用 toRaw(item)。这样,在 TestClick 方法中对 item 的任何更改都会触发视图更新。如果你想要添加新属性,也可以直接使用 item.newProperty = 'new value',这样也会触发视图更新。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题