見出し画像

【Nuxt.js】Modal実践編:QueryでModalを管理する①

🎈 この記事はWPへ移行しました
【Nuxt.js】Modal実践編:QueryでModalを管理する①

# 前置き

画像5

今回は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エラーはこれで自動で直ります💕

$ npm run lint:fix

⚠️変数で背景色などを変えています!
 どちらかで調整してみてください🌟
 ・assets/scss/common.scssで
  color, background-colorをコメントアウト
 ・assets/scss/_colors.scssで
  該当する変数の色を変更する

https://github.com/aLizlab/product_nuxt-template

難しければ通常ファイルでもOKです♪

# 構成

【index.vue】
・buttonをclickでrouter.push
【ModalRoute.vue】
・中身はqueryで切り替え
 pageでrouter.pushしたqueryに合わせて
 v-ifで表示を切り替える
・外見の白背景、
 閉じるボタン、
 閉じる背景は固定

# 下準備

【index.vue】
importしているcomponents/atoms/ButtonDefault.vue
こちらは消してOKです!
$emitの使い方の参考に入れています。
続きの記事で使うのでコメントアウトでもOK♪

# Step1: Modalを作成

スクリーンショット 2020-05-05 17.41.26

【流れ】
土台のModalを作りましょう♪
ファイルを作ったら
layouts/default.vueに入れて
表示を確認しながらやっていきましょう👀

【❓layouts/default.vue】
pagesに毎回componentsを
importしなくても良くなります🤗

【ディレクトリ 】
アトミックデザインに基づいて
ファイル分けをしています🙋‍♀️
要素の大きさごとに分けているので
どこに何があるのか直感的に分かり
非常に便利です!✨

もちろん好きに作ってもらってもOKです!
分け方などはこちらを参考にしてください👀
また原則としてimportするのは
自分の1つ下のサイズのみです💡
Atomic Design とは

【ディクトリ】

components/
--| templates/
----| modals/
-----| ModalRoute.vue

layouts/
--| default.vue

【layouts/default.vue】

<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/templates/ModalRoute.vue】
・iconはiconmonstrのX Mark 1
・HTML/CSSがメインのため解説なし

<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で表示/非表示を切り替える

画像2

今のままだと常にModalが表示されます👀
queryでModalの
表示/非表示を切り替えましょう!🍒
Vue Router基礎編(params, query)はこちらhttps://note.com/aliz/n/ndf76ebe9853b

【index.vue】

<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>

【解説】
・$router.push('?modal={好きな英数字}')
 $router.pushでqueryを指定します。
 queryが'modal'の時にModalRouteを表示

【ModalRoute.vue】
template部分のみ

<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ごとに作る

画像3

中身は分かりやすく
<p>タグのみでやりましょう🌟
作ったらurlを変更して
チェックしましょう✨👀

【ModalRoute.vue】
template部分のみ

<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: 調整

画像4

ボタンを表示を追加したり
実際のページらしいテキストに変更し
見た目を整えていきましょう🍒
・buttonを追加する
・それぞれqueryをloginとregisterに変更

【index.vue】
template部分のみ

<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>

【ModalRoute.vue】
template部分のみ

<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を作成していきます!

# 次回予告

【Nuxt.js】番外編:Progate初心者がNuxt.jsでWEBサイトを作るまでのロードマップ②
公開予定日は5/12(火)です🌟

前回の①はこちら
主にProgate〜GitHubまで
https://note.com/aliz/n/nb89303a84f66

記事が公開したときにわかる様、
フォローをお願いします😀💕

🎈 この記事はWPへ移行しました
【Nuxt.js】Modal実践編:QueryでModalを管理する①



この記事が気に入ったらサポートをしてみませんか?