Vue.js 内联编辑组件在保存前按 lodash 排序

Posted

技术标签:

【中文标题】Vue.js 内联编辑组件在保存前按 lodash 排序【英文标题】:Vue.js inline edit component is sorted by lodash before save 【发布时间】:2018-12-15 21:38:03 【问题描述】:

我有一个显示一些项目的 Vue.js 组件。当按下“编辑”按钮时,会显示一个内联编辑器。我还使用 lodash 按名称对项目进行排序。问题是,在每次 keyup lodash 对数组进行排序后,会立即产生奇怪的位置变化。排序逻辑在计算方法中。

<div id="app">
  <div class="container">
     <single-item v-for="item in orderedItems" :item="item" :key="item.id"></single-item>
  </div>
</div>

[...]

computed: 
  orderedItems: function() 
    return _.sortBy(this.items, 'name')
  

JSFiddle Link

正如您在初始化时看到的那样,lodash 按名称对项目进行排序,生成 2,1,3 顺序。但是当用户将“aaa”值编辑为“daaa”之类的东西时,就会发生这种奇怪的位置变化。有什么想法吗?

【问题讨论】:

这里只是一个猜测:每次 vue.js 检测到正在监视的数据发生变化时都会调用计算。尝试将方法绑定到事件处理程序,可能是在保存文本值时 发生这种情况是因为您正在编辑子模型中的模型,并且计算对象正在执行计算属性所做的事情;模型更改时更新。相反,您应该在编辑完成后从子级发出更改。 【参考方案1】:

您需要避免子组件内的项目的直接突变。而是在按下“保存”按钮后通知父母数据实际发生了变化。 我已经更新了你的小提琴: https://jsfiddle.net/uqbvLy4x/

要点:

为项目的更改设置一个观察者,以便您为子组件内的本地更改克隆它:

  watch: 
    item: 
       handler: function (item) 
            this.mutableItem = _.clone(item)
       ,
       immediate: true
    
  

让父级知道在保存函数内的子组件中更新了一个项目:

save: function(item) 
    this.editMode = false     
    this.$emit('update:item', this.mutableItem)

捕获并处理有关父项内部更改项的信息:​​

<single-item v-for="item in orderedItems" :item="item" :key="item.id"
       @update:item="onItemUpdated"></single-item>

   onItemUpdated: function (mutableItem) 
     console.log(mutableItem)
     const itemIndex = _.findIndex(this.items, item => 
       return item.id === mutableItem.id
      )
      this.items.splice(itemIndex, 1, mutableItem)
   

我确信还有其他可能更好的解决方案,但我就是这样处理的。

编辑:更具体地说明观察者:如果你传递一个完整的对象,你只需要观察者和克隆!这是因为您基本上获得了对原始对象的引用。这在文档中也有说明:

请注意,javascript 中的对象和数组是通过引用传递的,所以 如果 prop 是数组或对象,则改变对象或数组本身 子组件内部会影响父状态。

https://vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow

【讨论】:

以上是关于Vue.js 内联编辑组件在保存前按 lodash 排序的主要内容,如果未能解决你的问题,请参考以下文章

制作 vue.js 组件库。避免在每次编辑后重建它

如何在 Vue.js 中使用第三方库

如何使用户的个人资料页面可编辑,我想在编辑后保存这些数据(vue.js + laravel)

Vue js 2 *私下*保存组件的数据

在sublime 编辑器中,安装插件 Vue Syntax Hightlight,高亮识别Vue.js 的单文件组件(*.vue)

Vue.js 中,7种定义组件模板的方法