前置き
今回はqueryによるModalの切り替えです!
上の画像のurlにご注目👀
queryが分からない場合はこちら
https://note.com/aliz/n/ndf76ebe9853b
メリット
1つのcomponentsで
複数のModalを表示させることができます✨
Modalごとにcomponentsを
作らなくても良いんです✨
ちなみにModalが1種類だけで良ければ
シンプルな解説記事をご覧ください
https://note.com/aliz/n/n2f0bc857defb
テンプレート
aLizでテンプレートを用意しているので
ぜひgit cloneして使ってください🍒
scssが使えたり
ESlintで綺麗なコードが書けたり
便利です〜✨
ESlintエラーはこれで自動で直ります💕
terminal
$ npm run lint:fix
変数で背景色などを変えています!
どちらかで調整してみてください🌟
assets/scss/common.scssで
color, background-colorをコメントアウト
または
assets/scss/_colors.scssで
該当する変数の色を変更する
構成
) pages
buttonをclickでrouter.push
) components
中身はqueryで切り替え
pageでrouter.pushしたqueryに合わせて
v-ifで表示を切り替える
固定
外見の白背景、閉じるボタン、閉じる背景
下準備
aLizテンプレート使用の場合
) pages
importしているcomponents/atoms/ButtonDefault.vue
こちらは消してOKです!
$emitの使い方の参考に入れています。
続きの記事で使うのでコメントアウトでもOK♪
Step1: Modalを作成
流れ
土台のModalを作りましょう♪
ファイルを作ったら
layouts/default.vueに入れて
表示を確認しながらやっていきましょう👀
ディレクトリ
アトミックデザインに基づいて
ファイル分けをしています🙋♀️
要素の大きさごとに分けているので
どこに何があるのか直感的に分かり
非常に便利です!✨
もちろん好きに作ってもらってもOKです!
分け方などはこちらを参考にしてください👀
また原則としてimportするのは
自分の1つ下のサイズのみです💡
Atomic Design とは
directory
components/
--| templates/
----| modals/
-----| ModalRoute.vue
layouts/
--| default.vue
layouts/default.vueって?
pagesに毎回componentsを
importしなくても良くなります🤗
コード
) file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<template> <div class="layout layout-default"> <main class="content"> <nuxt /> <ModalRoute /> </main> </div> </template> <script lang="ts"> import Vue from 'vue' export default Vue.extend({ name: 'LayoutDefault', components: { ModalRoute: () => import('@/components/templates/modals/ModalRoute.vue'), }, }) </script> // スタイリングは変更ないため省きます |
) components
iconはiconmonstrのX Mark 1
HTML/CSSがメインのため解説なし
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 |
<template> <div class="modal-route"> <div class="bg" /> <div class="modal-wrap"> <button class="button"> <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> <!-- 切り替える中身 --> <p class="text"> Hello Nuxt.js! </p> </div> </div> </template> <script> import Vue from 'vue' export default Vue.extend({ name: 'Modal', }) </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%; } .text { font-size: 36px; } } } </style> |
Step2: queryで表示/非表示を切り替える
今のままだと常にModalが表示されます👀
queryでModalの
表示/非表示を切り替えましょう!🍒
Vue Router基礎編(params, query)はこちら
コード
) pages
$router.push('?modal={好きな英数字}')
$router.pushでqueryを指定します。
queryが'modal'の時にModalRouteを表示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<template> <div class="page page-index"> <h1>aLiz Nuxt's Template</h1> <button @click="$router.push('?modal=abc')" > Click! </button> </div> </template> <script lang="ts"> import Vue from 'vue' export default Vue.extend({ name: 'PageTop', layout: 'default', components: { }, }) </script> |
) components
template部分のみ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<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> <!-- 切り替える中身 --> <p class="text"> Hello Nuxt.js! </p> </div> </div> </div> </template> |
解説
- v-if="$route.query.modal"
Modal全体を
queryが'modal'の時のみ表示させる - @click="$router.push('/')"
背景と閉じるボタンをクリックしたら
queryの'modal'を外して
Modal全体を非表示にする
$emitがいらないので楽ですね♪
Step3: 中身をqueryごとに作る
中身は分かりやすく
<p>タグのみでやりましょう🌟
作ったらurlを変更して
チェックしましょう✨👀
コード
) components
template部分のみ
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 |
<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> <!-- 切り替える中身 --> <p v-if="$route.query.modal === 'abc'" class="text" > Hello Nuxt.js! </p> <p v-if="$route.query.modal == '123'" class="text" > {{ $route.query.modal }} </p> </div> </div> </template> |
解説
- v-if="$route.query.modal === 'abc'"
queryが?modal=abcならtrueで表示
→index.vueでbuttonをクリックすると
queryが一致するので表示 - v-if="$route.query.modal === '123'"
queryが?modal=123ならtrueで表示 - {{ $route.query.modal }}
ついでに表示も変えてみましょう♪
Step4: 調整
ボタンを表示を追加したり
実際のページらしいテキストに変更し
見た目を整えていきましょう🍒
buttonを追加する
それぞれqueryをloginとregisterに変更
コード
) pages
template部分のみ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<template> <div class="page page-index"> <h1>aLiz Nuxt's Template</h1> <button @click="$router.push('?modal=login')" > ログイン </button> <button @click="$router.push('?modal=register')" > 登録 </button> </div> </template> |
) components
template部分のみ
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 |
<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> <!-- 切り替える中身 --> <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> </div> </template> |
今回はここまで!
Modalの外側と内側で
コンポーネント分けをし、
最終的にformを作成していきます!