LoginSignup
1
0

More than 3 years have passed since last update.

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

Posted at

前置き

modal5.gif

今回は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で
  該当する変数の色を変更する

難しければ通常ファイルでも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.png

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

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

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

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

file
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がメインのため解説なし

ModalRoute.vue
<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.gif

今のままだと常に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部分のみ

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

modal3.gif

中身は分かりやすく

タグのみでやりましょう🌟
作ったら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: 調整

modal4.gif

ボタンを表示を追加したり
実際のページらしいテキストに変更し
見た目を整えていきましょう🍒
・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

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

https://twitter.com/aLizlab

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0