在 Vuex 中为同一组件实现双向数据绑定的不同方法
Posted
技术标签:
【中文标题】在 Vuex 中为同一组件实现双向数据绑定的不同方法【英文标题】:Different ways to implement two-way data binding for same component in Vuex 【发布时间】:2021-02-07 17:30:14 【问题描述】:我有一个 地址 组件,它具有基本的地址形式,其中包含 名称、街道、城市、州、国家/地区等详细信息。 我将它用于来源和目的地。
示例模板
<div class="row">
<div class="col-6" id="src">
<Address :address="src" />
</div>
<div class="col-6" id="dest">
<Address :address="dest" />
</div>
</div>
我正在使用 Vuex 操作(带模块) 从 API 获取数据(可能返回也可能不返回任何地址数据)并在我的商店状态中发生变异。
样本状态:
Address:
src:
name:'',
street:'',
city:'',
state:'',
country:'',
,
dest:
name:'',
street:'',
city:'',
state:'',
country:'',
我想通过突变实现状态和地址组件之间的双向数据绑定。
src 的地址组件应该改变 Address.src.(name, street, city, state, country) 在 state 和 Address 组件的 dest 应该改变 Address.dest.(name, street, city, state, country) 在州
我按照这个post 尝试使用props 和emit,vuex-map-fields,但没有成功。
我不知道实现它的正确方法是什么。
我将这个问题发布为菜鸟以获得帮助 正确的做法是什么?
【问题讨论】:
【参考方案1】:如果我正确理解了您的问题,我会遵循以下模式:
Make API Call --> data is updated in Vuex --> picked up by computed prop in component
基本上,在我的组件中,我可以创建一个从 Vuex 存储中获取数据的计算道具,如下所示:
computed:
sourceAddress()
return this.$store.state.Address.src;
,
destinationAddress()
return this.$store.state.Address.dest;
然后我可以像这样将这些计算出来的道具绑定到我的地址组件:
<div class="row">
<div class="col-6" id="src">
<Address :address="sourceAddress" />
</div>
<div class="col-6" id="dest">
<Address :address="destinationAddress" />
</div>
</div>
现在,只要在 Vuex 中更新 Address 对象(通过 API 调用),这些计算出来的 props 将分别选择更改并更新 Address 组件。
// sample pseudo code
mutations:
updateAddress(state, type,payload)
if(type==="destination")
// update destination address
else
//update source address
,
actions:
makeApiCall(context)
// lets say call succeeds and you have some data to update for destination address
context.commit('updateAddress',type:"destination", payload:"data-you-want-to-update);
【讨论】:
这解决了从 vuex 到 Address 组件的数据,如何将 Address 组件中的更改更新为 vuex 状态?我想实现双向数据绑定@nishkaush 首先定义一个mutation
,它在接收到数据时会更新状态。然后从你的Vuex Action
中调用这个突变(在 API 调用成功并且实际上包含一些要更新的数据之后)。
@AkashPreet,如果您对解决方案感到满意,您能否将其标记为未来读者的答案。谢谢【参考方案2】:
您可以使用vuex getters
获取您的商店数据。 Vue 使用 vuex 辅助函数处理更优雅的将数据(two way binding
)拉入组件的方式。你可以阅读更多关于 vuex 辅助函数here
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store =
Address:
src:
name:'',
street:'',
city:'',
state:'',
country:'',
,
dest:
name:'',
street:'',
city:'',
state:'',
country:'',
const getters =
src: state => state.Address.src,
desc: state => state.Address.desc
const mutations =
setSrc(state, srcObj) // You can play around this to optimize if you can
state.Address.src = srcObj
,
setDesc(state, descObj)
state.Address.desc = descObj
const actions =
makeApiCall( commit , type, params )
yourApiCall(params).then((res) =>
if (type === 'src') // You can play around this to optimize if you can
commit('setSrc', res)
else
commit('setDesc', res)
)
export default new Vuex.Store( state, getters, mutations, actions)
//main.js
// all other imports
import store from './store'
new Vue(
el: '#app',
store
)
In your component
<Address :address="src"/>
<Address :address="desc"/>
import mapGetters, mapActions from 'vuex'
computed:
...mapGetters(['src', 'desc']) // these are updated automatically when store changes and available on this.src/this.desc
,
methods:
...mapActions(['makeApiCall']) // you can directly call using this // this.makeApiCall( type: 'src', params: )
【讨论】:
感谢@Naren 的回答,但它仍然无法解决问题。如果我们更改地址组件的输入字段中的值,我想改变状态。例如:如果 API 返回 Address.src.name 作为 Naren(将存储在状态中),则页面将在 Address 的名称输入字段中加载 Naren。如果我将 Naren 更改为 Akash,那么它的状态应该会发生变异(Address.src.name 现在应该是 Akash)。 你不应该直接改变状态,你应该只使用突变。根据 Vuex 文档:The only way to actually change state in a Vuex store is by committing a mutation
,阅读this 了解更多信息
如果您想从输入字段更改状态,请在存储中添加突变并使用该突变更新状态。 const mutations = changeName(state, name) state.Address.name = name
以上是关于在 Vuex 中为同一组件实现双向数据绑定的不同方法的主要内容,如果未能解决你的问题,请参考以下文章