これは、私が少し立ち往生した問題でした。残念ながら、私はここで答えを見つけることができませんでした(尋ねても助けにならなかった)。そこで、いくつかの調査を行って、あちこちで尋ねたところ、この問題の解決策を得たようです。
すでに答えを知っている質問があり、他の人(自分を含む)が後でそれを見つけられるように、その知識を公に文書化したい場合。
もちろん、私の答えは理想的なものではないかもしれませんし、そうではないことを知っています。それが私が投稿している重要なポイントです-それを改善するために。
例ではアクションを使用していないことに注意してください。考え方は同じです。
問題の統計から始めましょう:
Hello
という名前のローカルコンポーネントを動的に生成するApp.vue
があるとします。
<template>
<div id="app">
<div>
<hello v-for="i in jobs" :key="i" :id="i"></hello>
<button @click="addJob">New</button>
</div>
</div>
</template>
<script>
import Hello from './components/Hello'
export default {
components: {
Hello
}...
store.js
export const store = new Vuex.Store({
state: {
jobs: []
}
})
v-for
ディレクティブを使用して、配列jobs
を反復処理してコンポーネントを生成しています。現在のstore
は、空の配列を持つstate
のみで構成されています。ボタンNew
は2つのことを行う必要があります。
1)新しいコンポーネントHello
を作成します。つまり、jobs
に要素を追加します(数値にします)。 <hello>
のkey
およびid
として割り当てられ、props
としてローカルコンポーネントに渡されます。
2)ローカルストアを生成-modules-データのスコープを維持する新しく作成されたコンポーネント。
Hello.vue
<template>
<div>
<input type="number" :value="count">
<button @click="updateCountPlus">+1</button>
</div>
</template>
export default {
props: ['id']
}
単純なコンポーネント-1を追加するボタンを使用した入力。
NEW
ボタンの最初の操作では、-コンポーネントの生成-store.js
にmutation
を追加します
mutations: {
addJob (state) {
state.jobs.Push(state.jobs.length + 1)
...
}
第二に、ローカルモジュールの作成。ここでは、reusableModule
を使用してモジュールの複数のインスタンスを生成します。このモジュールは、利便性のために別のファイルに保存されています。また、モジュールの状態を宣言するための関数の使用に注意してください。
const state = () => {
return {
count: 0
}
}
const getters = {
count: (state) => state.count
}
const mutations = {
updateCountPlus (state) {
state.count++
}
}
export default {
state,
getters,
mutations
}
reusableModule
を使用するには、それをインポートし、動的モジュール登録を適用します。
store.js
import module from './reusableModule'
const {state: stateModule, getters, mutations} = module
export const store = new Vuex.Store({
state: {
jobs: []
},
mutations: {
addJob (state) {
state.jobs.Push(state.jobs.length + 1)
store.registerModule(`module${state.jobs.length}`, {
state: stateModule,
getters,
mutations,
namespaced: true // making our module reusable
})
}
}
})
その後、Hello.vue
をそのストレージにリンクします。 state
からgetters
、mutations
、actions
、vuex
が必要になる場合があります。ストレージにアクセスするには、getters
を作成する必要があります。 mutations
と同じです。
Home.vue
<script>
export default {
props: ['id'],
computed: {
count () {
return this.$store.getters[`module${this.id}/count`]
}
},
methods: {
updateCountPlus () {
this.$store.commit(`module${this.id}/updateCountPlus`)
}
}
}
</script>
getters
、mutations
、actions
がたくさんあると想像してください。なぜ{mapGetters}
または{mapMutations}
を使用しないのですか?複数のモジュールがあり、必要なモジュールへのパスがわかっている場合は、それを実行できます。残念ながら、モジュール名にはアクセスできません。
コードは、コンポーネントの作成時ではなく、コンポーネントのモジュールの実行時(アプリの起動時)に実行されます。したがって、これらのヘルパーは、事前にモジュール名を知っている場合にのみ使用できます。
ここにはほとんど助けがありません。 getters
とmutations
を分離し、それらをオブジェクトとしてインポートして、きれいに保つことができます。
<script>
import computed from '../store/moduleGetters'
import methods from '../store/moduleMutations'
export default {
props: ['id'],
computed,
methods
}
</script>
App
コンポーネントに戻ります。 mutation
をコミットする必要があります。また、getter
用にいくつかのApp
を作成しましょう。モジュールにあるデータにアクセスする方法を示すため。
store.js
export const store = new Vuex.Store({
state: {
jobs: []
},
getters: {
jobs: state => state.jobs,
sumAll (state, getters) {
let s = 0
for (let i = 1; i <= state.jobs.length; i++) {
s += getters[`module${i}/count`]
}
return s
}
}
...
App
コンポーネントの仕上げコード
<script>
import Hello from './components/Hello'
import {mapMutations, mapGetters} from 'vuex'
export default {
components: {
Hello
},
computed: {
...mapGetters([
'jobs',
'sumAll'
])
},
methods: {
...mapMutations([
'addJob'
])
}
}
</script>
こんにちは、質問と解決策を投稿していただきありがとうございます。
私は数日前にVuexを学び始め、同様の問題に遭遇しました。私はあなたのソリューションをチェックし、新しいモジュールを登録する必要のない私のものを思いつきました。私はそれがかなりやり過ぎだと思うし、正直に言うと、なぜあなたがそれをするのか理解していない。私が問題を誤解した可能性は常にあります。
マークアップのコピーを作成しましたが、わかりやすくするためにいくつかの違いがあります。
私が持っている:
JobList.vue(ジョブリストアイテムのラッピングを担当)
<template>
<div>
<job v-for="(job, index) in jobs" :data="job" :key="job.id"></job>
<h3>Create New Job</h3>
<form @submit.prevent="addJob">
<input type="text" v-model="newJobName" required>
<button type="submit">Add Job</button>
</form>
</div>
</template>
<script>
import store from '../store/index'
import job from './job';
export default {
components: { job },
data() {
return {
newJobName: ''
};
},
computed: {
jobs() {
return store.state.jobs.jobs;
}
},
methods: {
addJob() {
store.dispatch('newJob', this.newJobName);
}
}
}
</script>
仕事
<template>
<div>
<h5>Id: {{ data.id }}</h5>
<h4>{{ data.name }}</h4>
<p>{{ data.active}}</p>
<button type="button" @click="toggleJobState">Toggle</button>
<hr>
</div>
</template>
<script>
import store from '../store/index'
export default {
props: ['data'],
methods: {
toggleJobState() {
store.dispatch('toggleJobState', this.data.id);
}
}
}
</script>
最後に、jobs.js Vuexモジュールファイル:
export default {
state: {
jobs: [
{
id: 1,
name: 'light',
active: false
},
{
id: 2,
name: 'medium',
active: false
},
{
id: 3,
name: 'heavy',
active: false
}
]
},
actions: { //methods
newJob(context, jobName) {
context.state.jobs.Push({
id: context.getters.newJobId,
name: jobName,
active: false
});
},
toggleJobState(context, id) {
context.state.jobs.forEach((job) => {
if(job.id === id) { job.active = !job.active; }
})
}
},
getters: { //computed properties
newJobId(state) { return state.jobs.length + 1; }
}
}
ストアに新しいジョブを追加することができます。「アクティブ」プロパティが示すように、新しいカスタムvuexモジュールを必要とせずに個々のジョブをすべて制御できます。