Vue.js 意外数据和方法行为 [英] Vue.js unexpected data and method behaviour

查看:17
本文介绍了Vue.js 意外数据和方法行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有简单模板的 Vue.js 组件

文本

和脚本文件是

出口默认{name: '测试',数据() {返回 {目标:[],};},方法: {创建目标(目标计数){this.targets = [];var emptyTarget = {id:空,};for (var i = 0; i < targetCount; i++) {var targetToPush = emptyTarget;targetToPush.id = i;console.log(targetToPush.id);this.targets.push(targetToPush);控制台日志(this.targets);}返回 {};},},}

当我点击text时,我得到输出

<代码>0[{id":1},{id":1}]1[{id":1},{id":1}]

我不明白为什么会这样.

我希望

<代码>0[{id":0}]1[{id":0},{id":1}]

有什么想法吗?

解决方案

答案其实很简单,一个对象只被初始化一次,当它被赋值给一个变量时.如果将此变量分配给新变量,则将相同的对象引用分配给新变量.更新 Object1 将更新 Object2,反之亦然.

为了避免这种行为,您可以在使用新的扩展运算符初始化 Object2 时创建对象的副本:

const targets = [];const common = { commonProp: 'test' };for (let i = 1; i <= count; i++) {const target = { ...common, id: i };目标.推(目标);}this.targets = 目标;

请注意,您应该避免在循环中改变组件的状态.尽管渲染循环已经过优化并且实际上不会渲染 count 次,但还是按照示例只对属性进行一次变异.

还要注意嵌套对象的行为方式相同.上面的解决方案叫做浅拷贝,相比之下,深拷贝会递归地爬取你的对象来复制子对象/数组.

const common = {commonProp: { a: 1, b: 2 }};const object1 = { ...common, id: 1 };const object2 = { ...common, id: 2 };object1.commonProp.a = 2;控制台日志(对象1);//{ commonProp: { a: 2, b: 2 } }控制台日志(对象2);//{ commonProp: { a: 2, b: 2 } }

为了避免这个问题,你可以使用库来深度复制一个对象/数组,或者创建一个每次调用都会返回一个新对象的类或工厂函数.

//工厂const createTarget = id =>({commonProp: { a: 1, b: 2 },ID,});//班级类目标{构造函数(ID){this.id = id;this.commonProp = { a: 1, b: 2 };}}for (让 i = 1; i <= 计数; i++) {const target = createTarget(i);//或新目标(i);目标.推(目标);}

我希望这个解释能帮助你更好地理解这个概念.

祝你好运;)

I have a Vue.js component with simple template

<div @click="createTargets(2)">
text
</div>

and script file is

export default {
  name: 'test',
  data() {
    return {
      targets: [],
    };
  },
  methods: {
    createTargets(targetCount) {
      this.targets = [];
      var emptyTarget = {
          id: null,
      };
      for (var i = 0; i < targetCount; i++) {
        var targetToPush = emptyTarget;
        targetToPush.id = i;
        console.log(targetToPush.id);
        this.targets.push(targetToPush);
        console.log(this.targets);
      }
      return {};
    },
  },
}

When I click text, I get output

0
[{"id":1},{"id":1}]
1
[{"id":1},{"id":1}]

I cannot figure out why this is happening.

I would expect

0
[{"id":0}]
1
[{"id":0},{"id":1}]

Any ideas?

解决方案

The answer is quite simple really, an object is initialized only once, when it is assigned to a variable. If you assign this variable to a new variable, you are assigning the same object reference to a new variable. Updating Object1 will update Object2 and vice versa.

To circumvent this behavior, you can create a copy of the object when initializing Object2 using the new spread operator:

const targets = [];
const common = { commonProp: 'test' };

for (let i = 1; i <= count; i++) {
  const target = { ...common, id: i };
  targets.push(target);
}

this.targets = targets;

Note that you should avoid mutating your component's state in a loop. Even though the render loop is optimized and won't actually render count times, it's still better to mutate your property only once as per example.

Also note that nested objects behave the same way. The solution above is called a shallow copy, in contrast, a deep copy will recursively crawl your object to copy sub objects/arrays.

const common = {
  commonProp: { a: 1, b: 2 }
};
const object1 = { ...common, id: 1 };
const object2 = { ...common, id: 2 };
object1.commonProp.a = 2;
console.log(object1); // { commonProp: { a: 2, b: 2 } }
console.log(object2); // { commonProp: { a: 2, b: 2 } }

To avoid this issue, you can use a library to deep copy an object/array or create a class or factory function that will return a new object every time it is called.

// factory
const createTarget = id => ({
  commonProp: { a: 1, b: 2 },
  id,
});

// class
class Target {
  constructor(id) {
    this.id = id;
    this.commonProp = { a: 1, b: 2 };
  }
}

for (let i = 1; i <= count; i++) {
  const target = createTarget(i); // or new Target(i);
  targets.push(target);
}

I hope this explanation helped you understand this concept a bit better.

Good luck ;)

这篇关于Vue.js 意外数据和方法行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆