始めに
前提条件のコードを添付すると冗長になってしまうため、こちらに書いてあります。
まずはこちらをご覧ください。
本記事の内容
本記事は編集用のモーダルの作成を目指したものです。
以下の手順で解説していきます。
- モーダルの作成
- 編集機能の追加
モーダル作成
①booleanの取得
②メソッドの定義
③モーダルファイルの作成
④buttonとemit
①booleanの取得
true,falseでモーダルの開閉を行うため、booleanを作成します。
src/components/todo-lists/editCard.vue
<script setup lang="ts">
import { computed } from 'vue'
import { useStore } from '../../store'
interface Props {
list_id: number;
card_id: number;
card_description: string;
}
const props = defineProps<Props>()
const store = useStore()
//booleanを取得
const isEditable = computed<boolean>(()=>{
return store.getters['todoLists/getTodoCardById'](props.list_id, props.card_id).isEditable
})
</script>
<template>
<div>
<p>{{props.card_description}}</p>
</div>
</template>
②メソッドの定義
- actionsを呼ぶ
- vuexにメソッドを定義
actionsを呼ぶ
src/components/todo-lists/editCard.vue
<script setup lang="ts">
import { useStore } from '../../store'
//省略
const store = useStore()
//モーダル開閉のメソッドを定義
const toggleModal = () => {
store.dispatch('todoLists/toggleEditModal', {
isEditable: isEditable.value,
list_id: props.list_id,
card_id: props.card_id
})
};
</script>
<template>
<div>
<p @click="toggleModal">{{props.card_description}}</p>
</div>
</template>
vuexにメソッドを定義
src/store/todo-lists/index.ts
import { Module, ActionTree, MutationTree, GetterTree } from "vuex";
//型定義
type RootState={
version: string
}
type TodoListsState = {
todoLists: TodoList[];
};
type TodoList = {
id?: number;
description: string;
};
type TodoCard ={
id: number;
pet_name?: string,
person_name: string,
description: string;
isEditable?: boolean;
}
//ローカルストレージ
const savedLists = localStorage.getItem('todo-lists')
export const state: TodoListsState = {
todoLists: savedLists ? JSON.parse(savedLists): []
};
const getters: GetterTree<TodoListsState, RootState> = {
getTodoCardById: state => (list_id: number, card_id: number) =>state.todoLists.find(list=>list.id === list_id)!.todoCards.find(card => card.id == card_id)!
const mutations: MutationTree<TodoListsState> = {
toggleEditModal(state, payload: { isEditable: boolean, list_id: number, card_id: number}){
const todoCard = state.todoLists.find(list=>list.id === payload.list_id)!.todoCards.find(card => card.id == payload.card_id)!
todoCard.isEditable = !payload.isEditable
},
};
const actions: ActionTree<TodoListsState, RootState> = {
toggleEditModal({commit}, payload: { isEditable: boolean, list_id: number, card_id: number}) {
commit('toggleEditModal', payload)
},
}
export const TodoListsModule: Module<TodoListsState, RootState> = {
namespaced: true,
state,
getters,
actions,
mutations,
};
③モーダルファイルの作成
モーダルのテンプレートを書くファイルを作成します。
src/components/todo-lists/EditCardModal.vue
<script setup lang="ts">
</script>
<template>
<div>
<teleport to="body">
<div class="modal" id="sample-modal" v-show="props.isEditable"></div>
<div class="modal-content" v-show="isEditable">
<p>編集用モーダルです。</p>
</div>
</teleport>
</div>
</template>
<style scoped>
.modal {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0,0,0,.5);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.modal-content {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(0,0,0,.5);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: white;
width: 600px;
height: auto;
border-radius: 20px;
padding: 20px;
}
</style>
作成したファイルをeditCardファイルで読み込む
src/components/todo-lists/editCard.vue
<script setup lang="ts">
import { computed } from 'vue'
import { useStore } from '../../store'
import EditCardModal from './EditCardModal.vue' //追記
//省略
</script>
<template>
<div>
<p @click="toggleModal">{{props.card_description}}</p>
<!--追記-->
<edit-card-modal :isEditable="isEditable" @close="toggleModal" />
</div>
</template>
④emit定義
src/components/todo-lists/EditCardModal.vue
<script setup lang="ts">
import { computed } from 'vue'
import { useStore } from '../../store'
interface Props {
isEditable: boolean;
}
const props = defineProps<Props>()
const emitTest = defineEmits(['close'])
</script>
<template>
<div>
<teleport to="body">
<div class="modal" id="sample-modal" v-show="props.isEditable" @click="emitTest('close')"></div>
<div class="modal-content" v-show="isEditable">
<p>編集用モーダルです</p>
</div>
</teleport>
</div>
</template>
<style scoped>
//省略
</style>
編集機能作成
以下の手順で作成します。
①todoCard情報の取得
②vuexにメソッド定義
①todoCard情報の取得
取得するために、editCardの方からlist_idとcard_idの情報を渡すことを忘れないでください。
src/components/editCardModal.vue
<script setup lang="ts">
import { computed } from 'vue'
import { useStore } from '../../store'
interface Props {
list_id: number;
card_id: number;
isEditable: boolean;
}
const props = defineProps<Props>()
type TodoCard ={
id: number;
pet_name?: string,
person_name: string,
description: string;
isEditable?: boolean;
}
const emitTest = defineEmits(['close'])
const store = useStore()
//取得したいカード情報を取得
const card = computed<TodoCard>(()=>{
return store.getters['TodoLists/getTodoCardById'](props.list_id, props.card_id)
})
//メソッド定義
const editCard = () => {
store.dispatch('TodoLists/editCard', {
todoCard:{
id: Math.floor(Math.random() * 100000),
person_name: card.value.person_name,
description: card.value.description
},
list_id: props.list_id,
card_id: props.card_id
});
}
</script>
<template>
<div>
<teleport to="body">
<div class="modal" id="sample-modal" v-show="props.isEditable" @click="emitTest('close')"></div>
<div class="modal-content" v-show="isEditable">
<form @submit.prevent="editCard">
<label>
誰が実行するか入力してください。<br>
<input type="text" id="description" v-model="card.person_name" /><br>
</label>
<label>
実行するタスクの内容を記載してください。<br>
<input type="text" id="description" v-model="card.description" /><br>
</label>
<input type="submit" value="submit"/>
</form>
</div>
</teleport>
</div>
</template>
<style scoped>
//省略
</style>
②Vuexにメソッドの定義
src/store/todo-lists/index.ts
import { Module, ActionTree, MutationTree, GetterTree } from "vuex";
//型定義省略
const savedLists = localStorage.getItem('todo-lists')
export const state: TodoListsState = {
todoLists: savedLists ? JSON.parse(savedLists): []
};
const getters: GetterTree<TodoListsState, RootState> = {
getTodoCardById: state => (list_id: number, card_id: number) =>state.todoLists.find(list=>list.id === list_id)!.todoCards.find(card => card.id == card_id)!
const mutations: MutationTree<TodoListsState> = {
editCard(state, payload: {card_id: number,list_id: number, todoCard: TodoCard}){
const todoList = state.todoLists.find(list=>list.id === payload.list_id)!
const TodoCard = todoList.todoCards.find(card => card.id == payload.card_id)!
TodoCard.description = payload.todoCard.description
TodoCard.person_name = payload.todoCard.person_name
TodoCard.isEditable = false
},
};
const actions: ActionTree<TodoListsState, RootState> = {
editCard({commit}, payload: {card_id:number, list_id:number, todoCard: TodoCard}) {
commit('editCard', payload)
},
}
export const TodoListsModule: Module<TodoListsState, RootState> = {
namespaced: true,
state,
getters,
actions,
mutations,
};