如何为Vue JS计算属性的getter/setter传递参数?
问题描述
我想通过计算属性将输入字段与Vuex Store绑定。系统中有数据流(Data Streams),每个数据流对应特定的输入字段,这些字段并非固定值,由应用后台管理端维护。需要实现用户选择特定数据流后,展示从API获取的对应输入字段的功能。
目前遇到的阻碍:计算属性的getter无法接收参数,没办法告知Vuex getter应该返回哪些数据。
以下是我使用的代码,有没有其他方式可以实现相同功能?
使用版本
- vue - 2.6.1
- vuex - 3.6.2
- vuetify - 2.5.6
Vue组件 - 输入字段
<v-text-field :key="input_index" v-model="data_stream_inputs[ds_index][input_index]" :label="input.name" :placeholder="input.placeholder" ></v-text-field>
无法正常工作的计算属性
computed: { data_stream_inputs: { get() { return this.$store.getters['ActivateAudienceStore/getDataStreamInputByIndex'], set(value) { this.$store.commit('ActivateAudienceStore/SET_DATASTREAM_INPUT_BY_INDEX', value) } } }
Vuex Getter
export const getDataStreamInputByIndex = (state) => (payload) => { return state.data_delivery.datastreams[payload.data_stream].inputs[payload.index] }
解决方案
因为计算属性本身不支持传参,但可以通过以下几种方式实现需求:
方案1:拆分v-model为:value和@input
直接在模板中调用带参数的Vuex getter获取值,通过事件触发更新逻辑:
<v-text-field :key="input_index" :value="$store.getters['ActivateAudienceStore/getDataStreamInputByIndex']({ data_stream: ds_index, index: input_index })" @input="updateDataStreamInput(ds_index, input_index, $event)" :label="input.name" :placeholder="input.placeholder" ></v-text-field>
在组件的methods中定义更新方法:
methods: { updateDataStreamInput(dataStreamIndex, inputIndex, value) { this.$store.commit('ActivateAudienceStore/SET_DATASTREAM_INPUT_BY_INDEX', { data_stream: dataStreamIndex, index: inputIndex, value }) } }
同时修改Vuex的mutation,适配包含索引和值的payload:
export const SET_DATASTREAM_INPUT_BY_INDEX = (state, payload) => { state.data_delivery.datastreams[payload.data_stream].inputs[payload.index] = payload.value }
方案2:让计算属性返回带参数的函数
如果想保留计算属性的形式,可以让它返回一个能接收参数的函数,以此传递索引信息:
computed: { data_stream_inputs() { return (dsIndex, inputIndex) => ({ get: () => this.$store.getters['ActivateAudienceStore/getDataStreamInputByIndex']({ data_stream: dsIndex, index: inputIndex }), set: (value) => this.$store.commit('ActivateAudienceStore/SET_DATASTREAM_INPUT_BY_INDEX', { data_stream: dsIndex, index: inputIndex, value }) }) } }
模板中修改v-model的调用方式:
<v-text-field :key="input_index" v-model="data_stream_inputs(ds_index, input_index)" :label="input.name" :placeholder="input.placeholder" ></v-text-field>
方案3:存储当前选中的数据流索引
如果用户每次只操作一个选中的数据流,可以把当前选中的数据流索引存在组件data或Vuex中,这样计算属性就不需要传参:
组件data中添加状态:
data() { return { selectedDsIndex: 0 // 默认选中第一个数据流 } }
计算属性调整为:
computed: { currentDataStreamInputs: { get() { return this.$store.state.ActivateAudienceStore.data_delivery.datastreams[this.selectedDsIndex].inputs }, set(inputs) { this.$store.commit('ActivateAudienceStore/SET_DATASTREAM_INPUTS', { data_stream: this.selectedDsIndex, inputs }) } } }
模板简化为:
<v-text-field :key="input_index" v-model="currentDataStreamInputs[input_index]" :label="input.name" :placeholder="input.placeholder" ></v-text-field>
对应的Vuex mutation:
export const SET_DATASTREAM_INPUTS = (state, payload) => { state.data_delivery.datastreams[payload.data_stream].inputs = payload.inputs }
内容的提问来源于stack exchange,提问作者Martin M
相关产品推荐
相关产品推荐

