Vue.js是否有内置方法将持久对象的副本添加到重复数组中

我有一个Vue.js应用程序,其中有一系列项目的v-repeat。我想将newItem添加到项目列表。当我尝试this.items.push(this.newItem)推入的对象仍然绑定到输入。考虑以下内容:

new Vue({
  el: '#demo',

  data: {
    items: [
      {
        start: '12:15',
        end: '13:15',
        name: 'Whatch Vue.js Laracast',
        description: 'Watched the Laracast series on Vue.js',
        tags: ['learning', 'Vue.js', 'Laracast', 'PHP'],
        note: "Vue.js is really awesome. Thanks Evan You!!!"
      },
      {
        start: '13:15',
        end: '13:30',
        name: "Rubik's Cube",
        description: "Play with my Rubik's Cube",
        tags: ['Logic', 'Puzzle', "Rubik's Cube"],
        note: "Learned a new algorithm."
      }
    ],
    newItem: {start: '', end: '', name: '', description: '', tags: '', note: ''}
  },

  methods: {
    addItem: function(e) {
      e.preventDefault();

      this.items.push(this.newItem);
    }
  }
});

如预期的那样,以上内容将把绑定到对象的对象推送到items数组中。问题是我只想要对象的副本,这样当输入更改时它将不再更改。看到这个小提琴我知道我可以做:

addItem: function(e) {
  e.preventDefault();
  this.items.push({
    name:        this.newItem.name,
    start:       this.newItem.start,
    end:         this.newItem.end,
    description: this.newItem.description,
    tags:        this.newItem.tags,
    notes:       this.newItem.notes
  })
}

这行得通,但很多重复。

问题:是否存在仅添加对象副本而非持久对象的内置方法。

村村阿飞2020/03/12 18:20:13

在GitHub上查看此问题

浅克隆

我一直在使用jQuery,$.extend直到Evan You指出有一个未记录的内置扩展函数Vue.util.extend可以进行浅表克隆。因此,您可以使用的是:

addItem: function(e) {
  e.preventDefault();

  this.items.push(Vue.util.extend({}, this.newItem));
}

请参阅更新的Fiddle

深克隆

在引用其他对象的对象上进行浅表克隆时,可以将引用复制到外部对象,而不是克隆它们。要完全克隆对象,请执行Deep Clone

对于深层克隆,按照第一个链接中Evan的建议,可以使用:JSON.parse(JSON.stringify(object))这在小提琴小提琴之间可见一斑

如果使用lodash,请检查lodash cloneDeep如果使用NPM,请检出clone-deep

逆天猿理查德2020/03/12 18:20:13

您可以将Vanilla JavaScript与Object.assign()结合使用:

addItem: function(e) {
  e.preventDefault();

  this.items.push(Object.assign({}, this.newItem));
}

更新:

您还可以使用对象传播:

addItem: function(e) {
  e.preventDefault();

  this.items.push({...this.newItem});
}
乐十三2020/03/12 18:20:13

最高答案是错误的。Vue.util.extend与jQuery的扩展无关。它总是一个浅表克隆。 https://github.com/vuejs/vue/issues/1849#issuecomment-158770874

Object.assign和Spread运算符也是浅表副本。看到这个https://scotch.io/bar-talk/copying-objects-in-javascript

只需使用Ramda.js的实现 https://github.com/ramda/ramda/blob/v0.26.1/source/internal/_clone.js

如果您不希望_curry,则不必使用它们。

或检查此MVA 在JavaScript中深度克隆对象的最有效方法是什么?

乐米亚2020/03/12 18:20:13

这对我不起作用(1.0.13版)。我使用以下命令创建了没有数据绑定的副本:

this.items.push( JSON.parse( JSON.stringify( newItem ) ) );