Vue:如何在 mapFields 中使用组件道具 [英] Vue: How to use component prop inside mapFields
问题描述
我有通用组件和 vuex 商店.为了简单的双向绑定,我使用 vuex-map-fields.在组件方面,它具有 mapFields
方法,该方法创建带有突变的 get&set.我想使用 props
从 vuex 模块传递 namespace
,但这似乎是不可能的.
//我的组件代码导出默认{道具:[命名空间"],计算:{...mapFields(??this.namespace??, ["attr1", "attr2"])}}
当然,没有办法以这种方式使用this
,所以我们无法访问道具.在这种情况下,如何将命名空间指定为 prop?
问题(正如您可能已经收集到的)是在 this
可用之前构造计算属性,但您可以通过将 this.namespace
属性的解析推迟到计算属性被调用(这在组件构建完成之前不会发生).
这个概念是基于这篇文章动态生成计算属性.
基本模式是使用 get()
和 set()
计算:{富:{get() { this.namespace...},set() { this.namespace...},}}
但不是在组件中全部输入,我们可以创建一个基于 vuex-map-fields mapFields()
函数的辅助函数(参见 此处 为原文).
vuex-map-fields 附带的 normalizeNamespace()
函数不支持我们想要做的事情,所以我们放弃它并假设命名空间总是被传入(并且 store 模块使用标准的 getField
和 updateField
函数).
我在此处改编了其中一个 vuex-map-fields Codesandbox 示例.
注意命名空间在 data
而不是 props
方便起见,但 props
也应该工作.
模板
<div id="应用程序"><div><label>foo </label><input v-model="foo"/><跨度>{{ foo }}</span>
<br/><div><label>bar </label><input v-model="bar"/><跨度>{{ bar }}</span>
</模板>
助手
商店
从vue"导入Vue;从vuex"导入 Vuex;import { getField, updateField } from "vuex-map-fields";从./App"导入应用程序;Vue.use(Vuex);Vue.config.productionTip = false;const store = new Vuex.Store({模块:{foo 模块:{命名空间:真,状态: {foo: "初始 foo 值",栏:初始栏值"},吸气剂:{获取字段},突变:{更新字段}}}});新的 Vue({el: "#app",组件:{应用},店铺,模板:<应用程序/>"});
I have general component and vuex store. For easy two-way binding I use vuex-map-fields. On component side it has mapFields
method which creates get&set with mutations.
I want to pass namespace
from vuex module with props
but it seems to be impossible.
<my-component namespace="ns1" />
// my-component code
export default {
props: ["namespace"],
computed: {
...mapFields(??this.namespace??, ["attr1", "attr2"])
}
}
Of course, there is no way to use this
in such way so we don't have access to props. How can I specify namespace as prop in such case?
The problem (as you probably gathered) is that computed properties are constructed before this
is available, but you can get around it by deferring resolution of the this.namespace
property until the computed property is called (which won't happen until component construction is finished).
The concept is based on this post Generating computed properties on the fly.
The basic pattern is to use a computed with get()
and set()
computed: {
foo: {
get() { this.namespace...},
set() { this.namespace...},
}
}
but rather than type it all out in the component we can create a helper function based on the vuex-map-fields mapFields()
function (see here for the original).
The normalizeNamespace()
function that comes with vuex-map-fields does not support what we want to do, so we drop it and assume the namespace is always passed in (and that the store module uses the standard getField
and updateField
functions).
I have adapted one of the vuex-map-fields Codesandbox examples here.
Note the namespace is in data
rather than props
for conveniance, but props
should work also.
Template
<template>
<div id="app">
<div>
<label>foo </label> <input v-model="foo" /> <span> {{ foo }}</span>
</div>
<br />
<div>
<label>bar </label> <input v-model="bar" /> <span> {{ bar }}</span>
</div>
</div>
</template>
Helper
<script>
const mapFields2 = (namespaceProp, fields) => {
return Object.keys(fields).reduce((prev, key) => {
const path = fields[key];
const field = {
get() {
const namespace = this[namespaceProp];
const getterPath = `${namespace}/getField`;
return this.$store.getters[getterPath](path);
},
set(value) {
const namespace = this[namespaceProp];
const mutationPath = `${namespace}/updateField`;
this.$store.commit(mutationPath, { path, value });
}
};
prev[key] = field;
return prev;
}, {});
};
export default {
name: "App",
data() {
return {
nsProp: "fooModule"
};
},
computed: {
...mapFields2("nsProp", { foo: "foo", bar: "bar" })
}
};
</script>
Store
import Vue from "vue";
import Vuex from "vuex";
import { getField, updateField } from "vuex-map-fields";
import App from "./App";
Vue.use(Vuex);
Vue.config.productionTip = false;
const store = new Vuex.Store({
modules: {
fooModule: {
namespaced: true,
state: {
foo: "initial foo value",
bar: "initail bar value"
},
getters: {
getField
},
mutations: {
updateField
}
}
}
});
new Vue({
el: "#app",
components: { App },
store,
template: "<App/>"
});
这篇关于Vue:如何在 mapFields 中使用组件道具的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!