用于本地编辑的 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()
方法,然后随意编辑:)
我正在使用 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()
方法,然后随意编辑:)