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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30578254/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 05:25:05  来源:igfitidea点击:

Does Vue.js have a built in way to add a copy of a persistent object to a repeated array

javascriptvue.js

提问by DutGRIFF

I have a Vue.js app where I have a v-repeat on an array of items. I want to add a newItem to the list of items. When I try this.items.push(this.newItem)the object pushed is still bound to the input. Consider the below:

我有一个 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);
    }
  }
});

The above will, as expected, push the object that is bound onto the items array. The problem is I want just a copy of the object so it will no longer change when the input changes. See this this fiddle. I know I can do:

正如预期的那样,上面的内容将推送绑定到 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
  })
}

This worksbut is a lot of repetition.

这有效,但重复很多。

The question:Is there a built in way to add just a copy of the object instead of the persistent object.

问题:是否有一种内置的方法来添加对象的副本而不是持久对象。

回答by DutGRIFF

See this issueon GitHub.

在 GitHub 上查看此问题

Shallow Clone

浅克隆

I was using jQuery's $.extenduntil Evan Youpointed out there is an undocumented built it extend function Vue.util.extendthat does a shallow clone. So what you could use is:

我一直在使用 jQuery,$.extend直到Evan You指出有一个未记录的构建它的扩展函数Vue.util.extend可以进行浅层克隆。所以你可以使用的是:

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

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

See the updated Fiddle.

请参阅更新的 Fiddle

Deep Clone

深层克隆

When doing a shallow clone on an object that references other objects you copy the references to the external objects instead of cloning them. To clone the object completely do a Deep Clone.

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

For the deep clone, per Evan's suggestion in the first link, one could use: JSON.parse(JSON.stringify(object)). This can be seen between this fiddleand this fiddle.

对于深层克隆,根据 Evan 在第一个链接中的建议,可以使用:JSON.parse(JSON.stringify(object)). 这可以在this fiddlethis fiddle之间看到。

If using lodash check out lodash cloneDeep. If using NPM check out clone-deep.

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

回答by user3698965

This didn't work for me (vue 1.0.13). I used the following to create a copy without the data bindings:

这对我不起作用(vue 1.0.13)。我使用以下内容创建了一个没有数据绑定的副本:

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

回答by Arthur Araújo

You can use Vanilla JavaScript with Object.assign():

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

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

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

UPDATE:

更新:

You can also use Object Spread:

您还可以使用对象传播:

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

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

回答by Alvin Smith

The top answer is wrong. Vue.util.extend has nothing to do with jQuery's extend. It's always a shallow clone. https://github.com/vuejs/vue/issues/1849#issuecomment-158770874

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

Object.assign and Spread operator are also shallow copy. see this https://scotch.io/bar-talk/copying-objects-in-javascript

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

Simply use the implementation of Ramda.js https://github.com/ramda/ramda/blob/v0.26.1/source/internal/_clone.js

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

_curry is not necessary if you don't want them.

如果您不想要它们,则不需要 _curry。

Or check this MVA What is the most efficient way to deep clone an object in JavaScript?

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