用于本地编辑的 Vuex 克隆对象

Vuex clone object for local editing

我正在使用 Vue 和 Vuex 进行中央存储管理。 我在商店中有一个经常由 setTimeout 函数更新的对象列表。我想让用户 select 并用双向数据绑定形式编辑它。我的问题是,每当商店中的任何数据更新时,用户正在修改的 selected 对象也会重新呈现。这样用户就丢失了更改。

解决方案是将对象从 Vuex 存储克隆到本地数据对象并将其绑定到表单以防止在编辑时更新。我尝试了所有可能的方法来克隆 Vuex returns 的可观察对象,但没有成功。 特别是我尝试了以下方法:

JSON.parse(JSON.stringify(obj))

Object.assign({}, vueObj)

以及来自外部库的其他深度克隆方法,如 _ 和 jQuery。

这是我从 Vuex 商店获得的对象:

如果我将它字符串化,解析它并分配给本地 vue 数据对象,它会在 Vuex 中央存储更新时更新。

这是我的代码(仅组件,不是 Vuex 存储):

    <template>
  <div class="">

    <div v-if="localSelectedDataSource.id">
      {{localSelectedDataSource.name}}
    </div>
    <div v-if="localSelectedDataSource.id">
      <div><sui-input placeholder="Url" :value="localSelectedDataSource.url"/></div>
      <div>{{localSelectedDataSource.method}}</div>
      <div>{{localSelectedDataSource.pollingInterval}}</div>
    </div>

    <div class="datasource-list">
      <div
      v-bind:class="{ highlightdatasource: dataSource.view.highlighted }"
      v-for="dataSource in dataSources"
      v-on:mouseover="highlightDataSource(dataSource.id)"
      v-on:mouseout="highlightDataSource(-1)"
      v-on:click="editSelectedDataSourceLocal(dataSource.id)"
      >
        {{dataSource.name}} - {{dataSource.url}}
      </div>
    </div>
  </div>

    </template>

      <script>
      import {mapGetters} from 'vuex';
      import {mapActions} from 'vuex';

    export default {
      name: 'DataSourceList',
      data(){
            return{
              localSelectedDataSource: {}
            }
        },
      computed: {
            ...mapGetters([
                'dataSources',
                'selectedDataSource'
            ])
        },
      methods: {
          ...mapActions([
              'highlightDataSource',
              'editSelectedDataSource'
          ]),
          editSelectedDataSourceLocal: function(id){
            this.editSelectedDataSource(id)
            var t = JSON.parse(JSON.stringify(this.selectedDataSource))
            if(this.localSelectedDataSource.id != this.selectedDataSource.id){
              this.localSelectedDataSource = t
            }
          }
      }
    }
    </script>

谢谢

经过几个小时的调试,我和我的朋友发现了我的错误:

我使用了 v-bind shorthand :

<div><sui-input placeholder="Url" :value="localSelectedDataSource.url"/></div>

而不是双向绑定v-model

<div><sui-input placeholder="Url" v-model="localSelectedDataSource.url"/></div>

所以每次更新中央 vuex 存储时,我的组件数据绑定都会重新呈现,包括绑定到表单的本地副本。

感谢大家,

如果你想使用 v-model,你应该使用计算 属性。您会计算出 属性 returns 商店中的值,而不是在 v 模型中使用计算出的 属性。 顺便说一下,v-model 是语法糖:

:value="someData" @input="someData=$event.target.value"
它可能与 :value 一起使用,因为 @input 不存在。

经过多方搜索,这个link帮助了我:How can I clone data from Vuex state to local data?基本上使用beforeMount()方法,然后随意编辑:)