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

Posted

技术标签:

【中文标题】Vue.js 是不是具有将持久对象的副本添加到重复数组的内置方法【英文标题】:Does Vue.js have a built in way to add a copy of a persistent object to a repeated arrayVue.js 是否具有将持久对象的副本添加到重复数组的内置方法 【发布时间】:2015-08-15 04:38:23 【问题描述】:

我有一个 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 数组的对象推送。问题是我只想要一个对象的副本,所以当输入改变时它不会再改变。请参阅此this fiddle。我知道我能做到:

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 works 但有很多重复。

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

【问题讨论】:

我知道数据中可能有一个列数组来生成列及其模型等。标签字段也没有作为数组保存。我从我正在启动的一个项目中复制了这个,并作为示例实现了一半。忽略这些。 【参考方案1】:

请参阅 GitHub 上的 this issue。

浅克隆

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

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

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

请参阅updated Fiddle。

深度克隆

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

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

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

【讨论】:

Evan 对该问题的评论指出这是一个浅层克隆。仅克隆***属性。【参考方案2】:

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

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

【讨论】:

我的意思是 DutGRIFF 的回答:this.items.push(Vue.util.extend(, this.newItem));【参考方案3】:

您可以将 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);

【讨论】:

Object.assign 创建一个浅拷贝。我假设对象传播也会创建一个浅拷贝,对吧?【参考方案4】:

上面的答案是错误的。 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 What is the most efficient way to deep clone an object in JavaScript?

【讨论】:

以上是关于Vue.js 是不是具有将持久对象的副本添加到重复数组的内置方法的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 将对象添加到现有数组

实体框架代码第一个值对象持久保存到数据库[重复]

无论当前上下文状态如何,如何获取 NSManagedObject 的持久存储副本

vue.js怎样解决按钮多次点击重复提交

如何将 PWA 添加到不是使用 Vue CLI 创建的 Vue.js 3 应用程序?

具有可互换持久层的应用程序