PROGRAMMING

ログインモーダルを作る【Vue.js】

今回の内容
・ElementUIでモーダルを表示する
・モーダルからログインする

今日はこんな感じでやっていきます。

今回の内容

ElementUIでモーダルを表示する

今日はElementUIというUIライブラリを使って、ログインモーダルを作っていきます。

チャットフォームをクリックした時にログイン用のモーダルを表示させるようにしますので、ChatFormをいじっていきます。

まずはターミナルで下記のコードを実行します。その後チャットフォームでモーダルを表示できるようにします。

$npm install element-ui -s
import Vue from 'vue'
import ElementUI from 'element-ui'
import { db } from '~/plugins/firebase'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)

このドキュメントのBasic usageによると、visible という boolean 型(true or false)のアトリビュートがあるようです。これを指定することでモーダルの表示・非表示を操作できるようです。

el-dialogvisibleの情報を入れるようにするには、下記のようになります。

上のを参考に下記のように変更します。

<template>
  <div class="input-container">
    <textarea v-model="text" @keydown.enter="addMessage"></textarea>
    <el-dialog title='Tips'
               :visible.sync='dialogVisible'
               width="30%">
               <span>This is a message</span>
     </el-dialog>
  </div>
</template>

<script>
import Vue from 'vue'
import ElementUI from 'element-ui'
import { db } from '~/plugins/firebase'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
export default {
  data() {
    return {
      dialogVisible: true,
      text: null,
    }
  },
  methods: {
    addMessage(event) {
      if (this.enterJapaneseConversion(event)) {
        return
      }
      const channelId = this.$route.params.id
      db.collection('channels')
        .doc(channelId)
        .collection('messages')
        .add({ text: this.text, createdAt: new Date().getTime() })
        .then(() => {
          this.text = null
        })
    },
    enterJapaneseConversion(event) {
      const codeForConversion = 229
      return event.keyCode === codeForConversion
    },
  },
}
</script>
<style scoped>
.input-container {
  padding: 10px;
  height: 100%;
}

textarea {
  width: 100%;
  height: 100%;
}
</style>

dialogVisible: true,

となっているので、チャンネルをクリックするだけでモーダルが開くなるようになっています。

.syncを追加しないとモーダルを閉じれないので、注意です。

モーダルからログインする

それでは、チャットフォームをクリックした時にモーダルを表示できるようにしたいので、openLoginModalというメソッドを作って実行していきます。

<template>
  <div class="input-container">
    <textarea
      v-model="text"
      @click="openLoginMpdal"
      @keydown.enter="addMessage"
    ></textarea>
    <el-dialog title="Tips" :visible.sync="dialogVisible" width="30%">
      <span>This is a message</span>
    </el-dialog>
  </div>
</template>

<script>
import Vue from 'vue'
import ElementUI from 'element-ui'
import { db } from '~/plugins/firebase'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
export default {
  data() {
    return {
      dialogVisible: false,
      text: null,
    }
  },
  methods: {
    openLoginModal() {
      this.dialogVisible = true
    },
    addMessage(event) {
      if (this.enterJapaneseConversion(event)) {
        return
      }
      const channelId = this.$route.params.id
      db.collection('channels')
        .doc(channelId)
        .collection('messages')
        .add({ text: this.text, createdAt: new Date().getTime() })
        .then(() => {
          this.text = null
        })
    },
    enterJapaneseConversion(event) {
      const codeForConversion = 229
      return event.keyCode === codeForConversion
    },
  },
}
</script>
<style scoped>
.input-container {
  padding: 10px;
  height: 100%;
}

textarea {
  width: 100%;
  height: 100%;
}
</style>

dialogVisible: falseでモーダルを表示させないようにしておき、openLoginModalでチャットフォームを触った時に表示させるようにしました。

上のgoogleのロゴ画像を表示して、ログイン用のモーダルでログインできるようにしていきます。

画像はasseteの下に追加しておきます。

まずはHTMLの方から変更していきます。

 <el-dialog title="" :visible.sync="dialogVisible" width="30%">
      <div class="image-container">
        <img src="~assets/google_sign_in.png" @click="login" />
      </div>
    </el-dialog>

<style scoped>
.input-container {
  padding: 10px;
  height: 100%;
}

textarea {
  width: 100%;
  height: 100%;
}

.image-container {
  display: flex;
  justify-content: center;
}

img {
  width: 70%;
  cursor: pointer;
}
</style>

上記のように画像を表示できるようにして、@clickloginメソッドを実行できるようにします。ついでにCSSも追加しておきます。

そしたら次はpages/index.vueからloginメソッドを持って来ます。pages/index.vueloginメソッドなどは全て削除します。

ChatForm.vueファイルでそのままloginメソッドを入れても、firebaseをimportしていないので、importします。

下記のようにコードを全て変更します。

<template>
  <div class="container"></div>
</template>
<script>
export default {
  methods: {},
}
</script>
<style>
.container {
  height: 100%;
}
</style>
<script>
import Vue from 'vue'
import ElementUI from 'element-ui'
import { db, firebase } from '~/plugins/firebase'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
export default {
  data() {
    return {
      dialogVisible: false,
      text: null,
    }
  },
  methods: {
    openLoginModal() {
      this.dialogVisible = true
    },
    addMessage(event) {
      if (this.enterJapaneseConversion(event)) {
        return
      }
      const channelId = this.$route.params.id
      db.collection('channels')
        .doc(channelId)
        .collection('messages')
        .add({ text: this.text, createdAt: new Date().getTime() })
        .then(() => {
          this.text = null
        })
    },
    enterJapaneseConversion(event) {
      const codeForConversion = 229
      return event.keyCode === codeForConversion
    },
    login() {
      const provider = new firebase.auth.GoogleAuthProvider()
      firebase
        .auth()
        .signInWithPopup(provider)
        .then((result) => {
          const user = result.user
          console.log(user)
          this.dialogVisible = false
        })
        .catch((error) => {
          window.alert(error)
        })
    },
  },
}
</script>

this.dialogVisible = falseloginメソッドに追加されていますが、これはログインが成功したらモーダルを閉じるようにしています。

こんな感じでちゃんとモーダルが出力されました。

まとめ

今日でログイン用のモーダルからログインすることが出来ました。

しかし、これではログイン状態を維持すること出来ていないので、次はその問題を解決していきたいと思います。

最後まで読んでくださりありがとうございました。

-PROGRAMMING

Copyright © Iseblog ,@2020 All Rights Reserved.