Skip to content

Instantly share code, notes, and snippets.

@ergofriend
Last active February 23, 2019 02:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ergofriend/6ef7e4717654a207c8e02693c5a877ec to your computer and use it in GitHub Desktop.
Save ergofriend/6ef7e4717654a207c8e02693c5a877ec to your computer and use it in GitHub Desktop.
Vue vuexでfirebaseのログイン保持 ref: https://qiita.com/ErgoFriend/items/bd1bb445e185bf45e272
<template>
<div class="about">
<div class="box">
<div class="media">
<figure class="image is-64x64 media-left">
<img class="is-rounded" :src="user.photoURL">
</figure>
<div class="media-content">
<div class="content">
<p>
<strong>{{ user.displayName }} </strong> <small>{{ user.email }} </small>
<br>
{{ user.uid }}
</p>
</div>
<nav class="level is-mobile">
<div class="level-left">
<a class="level-item">
<span class="icon is-small"><i class="fas fa-reply"></i></span>
</a>
<a class="level-item">
<span class="icon is-small"><i class="fas fa-retweet"></i></span>
</a>
<a class="level-item">
<span class="icon is-small"><i class="fas fa-heart"></i></span>
</a>
</div>
</nav>
</div>
</div>
</div>
<footer class="footer">
<div class="content has-text-centered">
<p>
<strong>Makina</strong> by <a href="https://twitter.com/ergofriend">ergofriend</a>. The source code is licensed
<a href="http://opensource.org/licenses/mit-license.php">MIT</a>. The website content
is licensed <a href="http://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY NC SA 4.0</a>.
</p>
</div>
</footer>
</div>
</template>
<script>
export default {
name: "about",
computed: {
user() {
return this.$store.getters.user;
}
},
components: {}
};
</script>
<style scoped>
.box {
margin: 5% 10%;
}
</style>
<template>
<div id="app">
<Navigation />
<router-view/>
</div>
</template>
<script>
import Navigation from "@/components/Navigation.vue";
export default {
name: "home",
components: {
Navigation
}
};
</script>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
}
#nav a {
font-weight: bold;
color: #2c3e50;
}
#nav a.router-link-exact-active {
color: #42b983;
}
</style>
<template>
<div class="authentication">
<!-- ログイン時にはフォームとログアウトボタンを表示 -->
<div v-if="userStatus" key="login" class="navbar-item">
<p class="navbar-item">{{ user.displayName }}</p>
<button type="button" class="button is-small is-info is-outlined" @click="doLogout">
Sign out
</button>
</div>
<!-- 未ログイン時にはログインボタンを表示 -->
<div v-else key="logout">
<button type="button" class="google-button" @click="doLogin">
<span class="google-button__icon">
<svg viewBox="0 0 366 372" xmlns="http://www.w3.org/2000/svg"><path d="M125.9 10.2c40.2-13.9 85.3-13.6 125.3 1.1 22.2 8.2 42.5 21 59.9 37.1-5.8 6.3-12.1 12.2-18.1 18.3l-34.2 34.2c-11.3-10.8-25.1-19-40.1-23.6-17.6-5.3-36.6-6.1-54.6-2.2-21 4.5-40.5 15.5-55.6 30.9-12.2 12.3-21.4 27.5-27 43.9-20.3-15.8-40.6-31.5-61-47.3 21.5-43 60.1-76.9 105.4-92.4z" id="Shape" fill="#EA4335"/><path d="M20.6 102.4c20.3 15.8 40.6 31.5 61 47.3-8 23.3-8 49.2 0 72.4-20.3 15.8-40.6 31.6-60.9 47.3C1.9 232.7-3.8 189.6 4.4 149.2c3.3-16.2 8.7-32 16.2-46.8z" id="Shape" fill="#FBBC05"/><path d="M361.7 151.1c5.8 32.7 4.5 66.8-4.7 98.8-8.5 29.3-24.6 56.5-47.1 77.2l-59.1-45.9c19.5-13.1 33.3-34.3 37.2-57.5H186.6c.1-24.2.1-48.4.1-72.6h175z" id="Shape" fill="#4285F4"/><path d="M81.4 222.2c7.8 22.9 22.8 43.2 42.6 57.1 12.4 8.7 26.6 14.9 41.4 17.9 14.6 3 29.7 2.6 44.4.1 14.6-2.6 28.7-7.9 41-16.2l59.1 45.9c-21.3 19.7-48 33.1-76.2 39.6-31.2 7.1-64.2 7.3-95.2-1-24.6-6.5-47.7-18.2-67.6-34.1-20.9-16.6-38.3-38-50.4-62 20.3-15.7 40.6-31.5 60.9-47.3z" fill="#34A853"/></svg>
</span>
<span class="google-button__text">Sign in with Google</span>
</button>
</div>
</div>
</template>
<script>
import Firebase from './../firebase';
export default {
name: 'authentication',
created: function() {
Firebase.onAuth();
},
computed: {
user() {
return this.$store.getters.user;
},
userStatus() {
// ログインするとtrue
return this.$store.getters.isSignedIn;
}
},
methods: {
// ログイン処理
doLogin() {
Firebase.login();
},
// ログアウト処理
doLogout() {
Firebase.logout();
}
}
};
</script>
<style scoped>
.authentication {
display: inline-block;
}
.google-button {
height: 40px;
border-width: 0;
background: white;
color: #737373;
border-radius: 5px;
white-space: nowrap;
box-shadow: 1px 1px 0px 1px rgba(0, 0, 0, 0.05);
transition-property: background-color, box-shadow;
transition-duration: 150ms;
transition-timing-function: ease-in-out;
padding: 0;
}
.google-button:focus,
.google-button:hover {
box-shadow: 1px 4px 5px 1px rgba(0, 0, 0, 0.1);
}
.google-button:active {
background-color: #e5e5e5;
box-shadow: none;
transition-duration: 10ms;
}
.google-button__icon {
display: inline-block;
vertical-align: middle;
margin: 8px 0 8px 8px;
width: 18px;
height: 18px;
box-sizing: border-box;
}
.google-button__icon--plus {
width: 27px;
}
.google-button__text {
display: inline-block;
vertical-align: middle;
padding: 0 24px;
font-size: 14px;
font-weight: bold;
font-family: "Roboto", arial, sans-serif;
}
html,
body {
height: 100%;
}
body {
background-color: #f0f0f0;
display: flex;
align-items: center;
justify-content: center;
}
</style>
node 8.11.4
npm 5.6.0
vue 3.0.1
npm install -g @vue/cli
npm install -g @vue/cli-service-global
git clone https://github.com/ErgoFriend/makina.git
cd makina
npm install
vue ui
export default {
init() {},
login() {},
logout() {},
onAuth() {}
};
import firebase from "@firebase/app";
import "@firebase/auth";
import store from "./store";
const config = {
apiKey: "ほげほげ",
authDomain: "ほげほg..."
data.... //省略します!
};
export default {
init() {
firebase.initializeApp(config);
firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION);
},
login() {
const provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider)
},
logout() {
firebase.auth().signOut()
},
onAuth() {
firebase.auth().onAuthStateChanged(user => {
user = user ? user : {};
store.commit('onAuthStateChanged', user);
store.commit('onUserStatusChanged', user.uid ? true : false);
});
}
};
<template>
<div class="home">
<h1>hello</h1>
</div>
</template>
<script>
export default {
name: "home",
components: {}
};
</script>
<style scoped>
.home {
height: 90vh;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
background-image: url("https://pbs.twimg.com/media/DgOcLUnU8AEgN56.jpg");
}
</style>
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import Buefy from "buefy";
import "buefy/dist/buefy.min.css";
Vue.use(Buefy);
import Firebase from "./firebase";
Firebase.init();
Vue.config.productionTip = false;
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");
<template>
<div id="nav">
<nav class="navbar is-transparent" v-bind:class="{'is-fixed-bottom':menuPosition}">
<div class="navbar-brand">
<router-link class="navbar-item" to="/">
<img src="https://bulma.io/images/bulma-logo.png" alt="Bulma: a modern CSS framework based on Flexbox" width="112" height="28">
</router-link>
<div class="navbar-burger burger " v-bind:class="{ 'is-active': menuActive }" v-on:click="menuToggle()" data-target="navbarExampleTransparentExample">
<span></span>
<span></span>
<span></span>
</div>
</div>
<div id="navbarExampleTransparentExample" class="navbar-menu" v-bind:class="{ 'is-active': menuActive }">
<div class="navbar-start">
<router-link class="navbar-item" to="/">Home</router-link>
<router-link class="navbar-item" to="/about">About</router-link>
</div>
<div class="navbar-end">
<Authentication />
</div>
</div>
</nav>
</div>
</template>
<script>
import Authentication from "@/components/Authentication.vue";
export default {
name: "navigation",
components: {
Authentication
},
created() {
if (window.innerWidth < 920) {
this.menuPosition = !this.menuPosition;
}
},
data() {
return {
menuActive: false,
menuPosition: false
};
},
methods: {
menuToggle() {
this.menuActive = !this.menuActive;
}
}
};
</script>
<style scoped>
#nav {
padding: 30px;
}
#nav a {
font-weight: bold;
color: #555;
}
#nav a.router-link-exact-active {
color: #3273dc;
}
</style>
│ App.vue
│ main.js
│ router.js
│ store.js
| firebase.js //追加
├─assets
│ logo.png
├─components
│ // HelloWorld.vue を削除します
| Authentication.vue //追加
| Navigation.vue //追加
└─views
About.vue
Home.vue
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
user: {},
status: false
},
mutations: {
onAuthStateChanged(state, user) {
state.user = user; //firebaseが返したユーザー情報
},
onUserStatusChanged(state, status) {
state.status = status; //ログインしてるかどうか true or false
}
},
getters: {
user(state) {
return state.user;
},
isSignedIn(state) {
return state.status;
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment