前置き
前回の続きです!
1つのcomponentsで
複数のModalを表示させましょう✨
Step5: 中身をcomponents分けする
Modalの外側と内側で
componentsを切り分けていきましょう。
queryによって切り替えているpタグを
organismsに移動させます🎈🧸
propsを使わなくて済むので
本当にただ移動させるだけです、楽ちん♪
directory
components/
--| organisms/
----| modals/
-----| ModalContainer.vue
--| templates/
----| modals/
-----| ModalRoute.vue
layouts/
--| default.vue
コード
) components
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<template> <div class="modal-container"> <!-- 切り替える中身 --> <p v-if="$route.query.modal === 'login'" class="text" > {{ $route.query.modal }} </p> <p v-if="$route.query.modal == 'register'" class="text" > {{ $route.query.modal }} </p> </div> </template> <script lang="ts"> import Vue from 'vue' export default Vue.extend({ name: 'Modal', }) </script> <style lang="scss" scoped> .modal-container { .text { font-size: 36px; } } </style> |
Step6: 中身をFormにする
ついでにformを作りましょう🌟
password入力のinputも作ると
inputをmoleculesで作る必要が出てくるので
一旦イメージだけできればOKです🧸🍯
コード
) components
@click="$emit('submit', form)"
inputに入力する値formを$emitで渡します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
<template> <div class="modal-container"> <!-- 切り替える中身 --> <form class="form" v-if="$route.query.modal === 'login'" @submit.prevent > <label class="label"> <span class="label"> {{ $route.query.modal }} </span> <input v-model="form.email" :type="type" placeholder="email" > </label> <button class="button" type="submit" @click="$emit('submit', form)" > {{ $route.query.modal }} </button> </form> <form class="form" v-if="$route.query.modal === 'register'" @submit.prevent > <label class="label"> <span class="label"> {{ $route.query.modal }} </span> <input v-model="form.email" :type="type" placeholder="email" > </label> <button class="button" type="submit" @click="$emit('submit', form)" > {{ $route.query.modal }} </button> </form> </div> </template> <script lang="ts"> import Vue from 'vue' export default Vue.extend({ name: 'Modal', data () { return { form: { email: '', }, } }, props: { type: { type: String, default: 'text', }, }, }) </script> <style lang="scss" scoped> .modal-container { .form { .label { font-size: 24px; .label { display: block; } } .button { display: block; } } } </style> |
) components
@submit
$emitでつけたイベント名
// eslint-disable-line
consoleなど特定の行に書かないと
ESLintでエラーになります。
https://qiita.com/nju33/items/2d0cfea4fffbfdbff87a
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
<template> <div v-if="$route.query.modal" class="modal-route" > <div class="bg" @click="$router.push('/')" /> <div class="modal-wrap"> <button class="button" @click="$router.push('/')" > <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M24 20.188l-8.315-8.209 8.2-8.282-3.697-3.697-8.212 8.318-8.31-8.203-3.666 3.666 8.321 8.24-8.206 8.313 3.666 3.666 8.237-8.318 8.285 8.203z" /></svg> </button> <ModalContainer @submit="submit" /> </div> </div> </template> <script> import Vue from 'vue' export default Vue.extend({ name: 'Modal', components: { ModalContainer: () => import('@/components/organisms/modals/ModalContainer.vue'), }, methods: { submit (form) { console.log(form) // eslint-disable-line }, }, }) </script> <style lang="scss" scoped> .modal-route { position: fixed; top: 0; width: 100%; height: 100%; .bg { width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); } .modal-wrap { border-radius: 8px; background-color: #ffffff; width: 50%; height: 50%; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); padding: 30px; .button { border: none; position: absolute; top: 5%; right: 2%; } } } </style> |
Step7: Formを分ける
今はformが2種類ですが
もし増えたら管理が面倒なので
分けてしまいましょう💡
分けたら意味ないのでは?
安心してください😌
componentタグを使えば良いのです✨
ディレクトリ は
modalsというファイルを作り
ModalContainerのform2つを
それぞれに分けましょう。
directory: before
components/
--| organisms/
----| modals/
-----| ModalContainer.vue
--| templates/
----| modals/
-----| ModalRoute.vue
layouts/
--| default.vue
directory: after
components/
--| templates/
----| modals/
-----| ModalRoute.vue
modals/
--| login.vue
--| register.vue
layouts/
--| default.vue
コード
) file
formのregister部分を除きましょう🧹
$emitのイベント名を分かりやすく
submitLoginに変更しましょう!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
<template> <div class="modal-container"> <!-- 切り替える中身 --> <form v-if="$route.query.modal === 'login'" class="form" @submit.prevent="$emit('submitLogin', form)" > <label class="label"> <span class="label"> {{ $route.query.modal }} </span> <input v-model="form.email" :type="type" placeholder="email" > </label> <button class="button" type="submit" > {{ $route.query.modal }} </button> </form> </div> </template> <script lang="ts"> import Vue from 'vue' export default Vue.extend({ props: { type: { type: String, default: 'text', }, }, data () { return { form: { email: '', }, } }, }) </script> <style lang="scss" scoped> .modal-container { .form { .label { font-size: 24px; .label { display: block; } } .button { display: block; } } } </style> |
) file
変更部分はlogin.vueと同じです
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
<template> <div class="modal-container"> <!-- 切り替える中身 --> <form v-if="$route.query.modal === 'register'" class="form" @submit.prevent="$emit('submitRegister', form)" > <label class="label"> <span class="label"> {{ $route.query.modal }} </span> <input v-model="form.email" :type="type" placeholder="email" > </label> <button class="button" type="submit" > {{ $route.query.modal }} </button> </form> </div> </template> <script lang="ts"> import Vue from 'vue' export default Vue.extend({ props: { type: { type: String, default: 'text', }, }, data () { return { form: { email: '', }, } }, }) </script> <style lang="scss" scoped> .modal-container { .form { .label { font-size: 24px; .label { display: block; } } .button { display: block; } } } </style> |
) components
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
<template> <div v-if="$route.query.modal" class="modal-route" > <div class="bg" @click="$router.push('/')" /> <div class="modal-wrap"> <button class="button" @click="$router.push('/')" > <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M24 20.188l-8.315-8.209 8.2-8.282-3.697-3.697-8.212 8.318-8.31-8.203-3.666 3.666 8.321 8.24-8.206 8.313 3.666 3.666 8.237-8.318 8.285 8.203z" /></svg> </button> <!-- <ModalContainer @submit="submit" /> --> <component :is="$route.query.modal" @submitLogin="submit($event)" @submitRegister="submit($event)" /> </div> </div> </template> <script> import Vue from 'vue' export default Vue.extend({ name: 'Modal', components: { login: () => import('@/modals/login.vue'), register: () => import('@/modals/register.vue'), }, methods: { submit (form) { console.log(form) // eslint-disable-line }, }, }) </script> <style lang="scss" scoped> .modal-route { position: fixed; top: 0; width: 100%; height: 100%; .bg { width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); } .modal-wrap { border-radius: 8px; background-color: #ffffff; width: 50%; height: 50%; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); padding: 30px; .button { border: none; position: absolute; top: 5%; right: 2%; } } } </style> |
解説
component :is="$route.query.modal"
:isでcomponentを呼び出します!
コンポーネントの登録が必要なので
中身をそれぞれimportしましょう📩
それぞれを1つのコンポーネントとみなし
queryで切り替えましょう🍒
@submitLogin="submit($event)"
$emitのイベント名を変えたので
どちらも書きましょう✍️
($event)は省略可能