始めに
本記事はこちらの記事の内容を発展させたものです。
良ければご覧ください。
見なくても理解には問題ないです。
開発環境
MacBook Air (M1, 2020)
npm 8.18.0
本記事の内容
- 前提
- モジュール分割
- vueファイルへの変更の反映
前提
以下の単純なアプリケーションをVuexでモジュール分割して、管理します。
あるのは、配列への要素の追加と、draggableのメソッドのみです。
TodoListView.vue(モジュール化前)
<script setup lang="ts">
import { computed, reactive } from 'vue';
import { useStore } from '../store'
import draggable from 'vuedraggable';
type TodoList = {
id?: number;
description: string;
};
const list = reactive({
description:''
})
const clearForm = () => {
list.description = ""
};
const store = useStore()
const addList = () =>{
store.dispatch('addList', {
id: Math.floor(Math.random() * 100000),
description: list.description
});
clearForm();
}
const todoLists = computed<TodoList[]>({
get: () => store.getters['todoLists']
set: val=> {
store.dispatch('dragList', val)
}
})
</script>
<template>
<div>
<h2>タスク管理</h2>
<form @submit.prevent="addList">
<input type="text" id="description" v-model="list.description" /><br>
<input type="submit" value="submit"/>
</form>
<hr />
<draggable v-model="todoLists" group="list" item-key="id" class="list-index" >
<template #item="{element}">
<div class="list">
<p>{{element.description}}</p>
</div>
</template>
</draggable>
</div>
</template>
モジュール分割
モジュールで分割をするためには、二つのことが必要です。
モジュール化したファイルとモジュール化したファイルの呼び込み先です。
その2つのファイルを作成していきます。
以下手順を記載します。
①ストアファイルをモジュール化
②モジュール化したファイルの呼び込み
順に解説していきます。
①モジュール化
モジュール化したファイルの変更点としては、一つだけです。
- Module,
- ActionTree,
- MutationTree,
- GetterTree
上記4つのオブジェクトの作成です。
src/store/todo-list/index.ts
import { Module, ActionTree, MutationTree, GetterTree } from "vuex";
//型定義
type RootState={
version: string
}
type TodoListsState = {
todoLists: TodoList[];
};
type TodoList = {
id?: number;
description: string;
};
//ローカルストレージから情報を取得
const savedLists = localStorage.getItem('todo-lists')
export const state: TodoListsState = {
todoLists: savedLists ? JSON.parse(savedLists): []
};
//GetterTreeのオブジェクトを用意
const getters: GetterTree<TodoListsState, RootState> = {
getTodoLists: state => state.todoLists,
getTodoListById: state => (list_id: number) =>state.todoLists.find(list=>list.id === list_id)!
};
//MutationTreeのオブジェクトを用意
const mutations: MutationTree<TodoListsState> = {
addList(state, payload: TodoList){
state.todoLists.push(payload)
},
dragList(state, payload: TodoList[]) {
state.todoLists = payload
},
};
//ActionTreeのオブジェクトを用意
const actions: ActionTree<TodoListsState, RootState> = {
addList({commit}, payload: TodoList) {
commit('addList', payload)
},
dragList({commit}, payload: TodoList[]) {
commit('dragList', payload)
},
}
export const TodoListsModule: Module<TodoListsState, RootState> = {
namespaced: true,
state,
getters,
actions,
mutations,
};
②作成したモジュールの呼び込み
src/store/todoList
import { InjectionKey } from 'vue';
import { createStore, Store, useStore as baseUseStore } from "vuex";
import { TodoListsModule } from '../store/TodoList'
//型定義
type RootState={
version: string
}
export const store = createStore<RootState>({
state: {
version: '1.0.0' //超単純なプロパティを設定。
},
modules: {
//importをしたモジュールを記載
todoLists: TodoListsModule
},
});
export const key: InjectionKey<Store<RootState>> = Symbol();
export const useStore = () => {
return baseUseStore(key);
}
//ローカルストレージ。モジュール化したstateを呼び込みたいときは、"state.モジュール名.配列名"となる。
store.subscribe((mutation, state: any) => {
localStorage.setItem('todo-lists', JSON.stringify(state.todoLists.todoLists))
Vueファイルへの反映
モジュール名を設定したら、以下のようにコードを変更してください。
TodoListView.vue(変更後)
<script setup lang="ts">
import { computed, reactive } from 'vue';
import { useStore } from '../store'
import draggable from 'vuedraggable';
type TodoList = {
id?: number;
description: string;
};
const list = reactive({
description:''
})
const clearForm = () => {
list.description = ""
};
const store = useStore()
const addList = () =>{
//モジュール化した場合、呼び込みたいものの前にモジュール名/をつける。
store.dispatch('todoLists/addList', {
id: Math.floor(Math.random() * 100000),
description: list.description
});
clearForm();
}
const todoLists = computed<TodoList[]>({
//こちらも同様
get: () => store.getters['todoLists/getTodoLists']
set: val=> {
//こちらも同様
store.dispatch('todoLists/dragList', val)
}
})
</script>
<template>
<div>
<h2>タスク管理</h2>
<form @submit.prevent="addList">
<input type="text" id="description" v-model="list.description" /><br>
<input type="submit" value="submit"/>
</form>
<hr />
<draggable v-model="todoLists" group="list" item-key="id" class="list-index" >
<template #item="{element}">
<div class="list">
<p>{{element.description}}</p>
</div>
</template>
</draggable>
</div>
</template>