php - I want to global menu with Vue component which can change items when user login or logout
one text
I develop SPA service. Frontend is run by Vue.js and Backend is run by Laravel. I implement login function with laravel sanctum.
If user success login, vue hold value in local storage.
login() {
axios.get("/sanctum/csrf-cookie").then(response => {
axios
.post("/api/login", {
email: this.email,
password: this.password
})
.then(response => {
localStorage.setItem("auth", "true");
})
});
And if user logout, removeItem from localstorage.
logout() {
axios
.post("api/logout")
.then(response => {
this.user = "";
this.localStorage = "";
localStorage.removeItem("auth");
this.$router.push("/login");
})
},
I already implement preventing access to pages which are for login user by unlogin user.
resources/app.js
import VueRouter from 'vue-router';
window.Vue = require('vue').default;
import HeaderComponent from "./components/HeaderComponent";
import store from './store';
Vue.component('header-component', HeaderComponent);
Vue.use(VueRouter);
const router = new VueRouter({
mode: 'history',
routes: [
{
path: '/autoFunction',
name: 'autoFunction',
component: AutoComponent,
meta: { authOnly: true }
},
{
path: "/login",
name: "login",
component: LoginComponent,
meta: { guestOnly: true }
},
]
});
function isLoggedIn() {
return localStorage.getItem("auth");
}
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.authOnly)) {
if (!isLoggedIn()) {
next("/login");
} else {
next();
}
} else if (to.matched.some(record => record.meta.guestOnly)) {
if (isLoggedIn()) {
next("/welcome");
} else {
next();
}
} else {
next();
}
});
const app = new Vue({
el: '#app',
router,
store,
});
I also want to control global menu by user's login status.
resources/js/components/HeaderComponent.vue
<template>
<div>
<header class="l-header">
<nav>
<ul class="c-menu__ul" v-if="isLoggedIn()">
<a @click="logout">
<li>Logout</li>
</a>
</ul>
<ul class="c-menu__ul" v-if="!isLoggedIn()">
<router-link v-bind:to="{name: 'login'}">
<li>Login</li>
</router-link>
</ul>
</nav>
</header>
</div>
</template>
<script>
import axios from 'axios';
import store from "../store";
export default {
data() {
return {
user: "",
};
},
mounted() {
axios.get("/api/getUserInfo").then(response => {
this.user = response.data;
});
},
};
</script>
Is it possible to use app.js's methods in HeaderComponent.vue?
I also tried Vuex but I could't control global menu when user access external page and retuern.
resources/js/store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
isLoggedIn: false,
},
mutations: {
onUserLoginStatusChanged(state, isLoggedIn) {
state.isLoggedIn = isLoggedIn;
}
},
getters: {
isLoggedIn(state) {
return state.isLoggedIn;
}
}
});
resources/js/components/HeaderComponent.vue
<nav>
<ul class="c-menu__ul" v-if="this.$store.getters.isLoggedIn">
<a @click="logout">
<li>Logout</li>
</a>
</ul>
<ul class="c-menu__ul" v-if="!this.$store.getters.isLoggedIn">
<router-link v-bind:to="{name: 'login'}">
<li>Login</li>
</router-link>
</ul>
</nav>
Source