VueJS 更新侧边栏组件
VueJS Update Sidebar Component
我在更新组件时遇到了问题。我解释一下:
我有一个使用 VueJS 和 Vuex 的单页应用程序。我的 App.vue
是这样的:
<template>
<div class="wrapper">
<Sidebar></Sidebar>
</div>
</template>
<script>
import Sidebar from "../components/Menu/Sidebar";
export default {
name: 'App',
components:{Sidebar},
props:['user'],
updated () {
console.log(updated)
}
}
</script>
<style>
</style>
我的边栏组件是这样的:
<div >
<nav id="sidebar">
<div id="dismiss">
<i class="fas fa-arrow-left"></i>
</div>
<div class="sidebar-header">
<h3>
<router-link
:to="{name:'home'}"
>
Gamer-Seek App
</router-link>
</h3>
</div>
<div class="components" v-if="user">
<div class="d-flex">
<router-link
:to="{name: 'user_show', params:{id: user.id}}"
>
<img
:src="user.image" alt="user-avatar"
class="d-block"/>
</router-link>
<span class="pt-4 pl-3">Hello,<br> {{ user.username }}</span>
</div>
</div>
<div v-else>
<ul id="btn-content" class="d-flex list-unstyled justify-content-between components">
<li><router-link
:to="{name:'login'}"
><i class="fas fa-sign-in-alt"></i> Login
</router-link></li>
<li><router-link
:to="{name:'register'}"
><i class="fas fa-registered"></i> Register
</router-link></li>
</ul>
</div>
<ul class="list-unstyled components">
<li>
<router-link
:to="{name:'home'}"
>
<i class="fas fa-home"></i> Home
</router-link>
</li>
<li>
<a href="#pageSubmenu" data-toggle="collapse" aria-expanded="false" class="dropdown-toggle"><i
class="fas fa-gamepad"></i> Games</a>
<ul class="collapse list-unstyled" id="pageSubmenu">
<li>
<a href="#">Seek games</a>
</li>
</ul>
</li>
<li>
<router-link
:to="{name: 'about'}"
>
<i class="fas fa-address-card"></i> About
</router-link>
</li>
<li>
<a v-if="user" class="btn btn-danger"
@click.prevent="logout"
>Logout</a>
</li>
</ul>
</nav>
<div id="content">
<menu-app></menu-app>
<router-view></router-view>
</div>
</div>
</template>
<script>
import Menu from "../Menu/Nav";
export default {
name: 'Sidebar',
components: {
'menu-app': Menu
},
data () {
return {
user: ''
}
},
methods: {
logout: function () {
this.$store.dispatch('logout')
.then(() => {
this.user = false;
this.$router.push('/login')
})
},
}
}
</script>
我的商店模块:
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios';
import setAuthorizationToken from "../module/axiosHeader";
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
status: '',
token: localStorage.getItem('token') || '',
user: localStorage.getItem('user') || {}
},
mutations: {
auth_request(state) {
state.status = 'loading'
},
auth_success(state, token) {
state.status = 'success'
state.token = token
},
auth_user(state, user){
state.user =user
},
auth_error(state) {
state.status = 'error'
},
logout(state) {
state.status = ''
state.token = ''
},
},
actions: {
login({commit}, user) {
return new Promise((resolve, reject) => {
commit('auth_request')
axios({url: '/api/login_check', data: user, method: 'POST'})
.then(resp => {
const token = resp.data.token.token
const user = resp.data.user
localStorage.setItem('token', token)
localStorage.setItem('user', JSON.stringify(user))
localStorage.setItem('authenticated', 'success')
axios.defaults.headers.common['Authorization'] = 'Bearer ' + token
commit('auth_success', token)
commit('auth_user', user)
resolve(resp)
})
.catch(err => {
commit('auth_error')
localStorage.removeItem('token')
reject(err)
})
})
},
register({commit}, user) {
return new Promise((resolve, reject) => {
commit('auth_request')
axios({url: '/api/register', data: user, method: 'POST'})
.then(resp => {
const token = resp.data.token
const user = resp.data.user
localStorage.setItem('token', token)
setAuthorizationToken(token)
commit('auth_success', token)
commit('auth_user', user)
resolve(resp)
})
.catch(err => {
commit('auth_error', err)
localStorage.removeItem('token')
reject(err)
})
})
},
logout({commit}) {
return new Promise((resolve, reject) => {
commit('logout')
axios({url: '/api/logout'}).then(() => {
localStorage.clear();
setAuthorizationToken();
resolve()
}
).catch(error => {
reject(error)
}
)
})
}
},
getters: {
isLoggedIn: state => !!state.token,
authStatus: state => state.status,
userInfo : state => state.user
}
})
并完成我的 Vue 实例:
import Vue from 'vue';
import router from '../routes';
import App from '../views/App';
import {store} from "../stores/authentication-store";
import Axios from "axios";
import setAuthorizationToken from "./axiosHeader";
export default class VueClass {
static init() {
let hours = 24; // Reset when storage is more than 24hours
let now = new Date().getTime();
let setupTime = localStorage.getItem('setupTime');
if (setupTime == null) {
localStorage.setItem('setupTime', now)
} else {
if (now - setupTime > hours * 60 * 60 * 1000) {
localStorage.clear()
localStorage.setItem('setupTime', now);
}
}
router.beforeEach((to, from, next) => {
const publicPages = ['/login', '/register'];
const authRequired = !publicPages.includes(to.path);
const loggedIn = localStorage.getItem('user');
if (authRequired && !loggedIn) {
return next('/login');
}
next();
})
Vue.prototype.$http = Axios;
const token = localStorage.getItem('token')
if (token) {
setAuthorizationToken(token)
}
new Vue({
el: '#app',
store,
router,
template: '<App />',
components: {App},
data: {
user: ''
},
created: function () {
this.$http.interceptors.response.use(undefined, function (err) {
return new Promise(function (resolve, reject) {
if (err.status === 401 && err.config && !err.config.__isRetryRequest) {
this.$store.dispatch('logout')
}
throw err;
});
});
},
}
)
}
}
我的问题是,当用户登录或注销时,如何更新我的边栏。我想在他们登录时显示他们的个人资料,否则显示 login/register。
有多种方法可以实现这一点。在这种情况下,由于边栏和用户状态是全局属性,我将使用全局事件来处理它。为此,您可以尝试 Vue 事件总线方法:
创建 event-bus.js
,其中包含以下行:
import Vue from 'vue';
export const EventBus = new Vue();
在 app.js
中导入:
import { EventBus } from './event-bus.js';
那你就可以这样用了
发出事件(当用户登录或注销时):
EventBus.$emit('userLoggedIn', this.user);
(您也可以在商店中设置 user
而不是将其作为参数传递。)
或
EventBus.$emit('userLoggedOut');
您可以像这样在任何相关组件(例如您的边栏组件)中监听此事件:
导入 event-bus
:
import { EventBus } from '../event-bus.js';
然后是这样的:
created() {
EventBus.$on('userLoggedIn', () => {
// do whatever necessary
});
EventBus.$on('userLoggedOut', () => {
// do whatever necessary
});
}
我在更新组件时遇到了问题。我解释一下:
我有一个使用 VueJS 和 Vuex 的单页应用程序。我的 App.vue
是这样的:
<template>
<div class="wrapper">
<Sidebar></Sidebar>
</div>
</template>
<script>
import Sidebar from "../components/Menu/Sidebar";
export default {
name: 'App',
components:{Sidebar},
props:['user'],
updated () {
console.log(updated)
}
}
</script>
<style>
</style>
我的边栏组件是这样的:
<div >
<nav id="sidebar">
<div id="dismiss">
<i class="fas fa-arrow-left"></i>
</div>
<div class="sidebar-header">
<h3>
<router-link
:to="{name:'home'}"
>
Gamer-Seek App
</router-link>
</h3>
</div>
<div class="components" v-if="user">
<div class="d-flex">
<router-link
:to="{name: 'user_show', params:{id: user.id}}"
>
<img
:src="user.image" alt="user-avatar"
class="d-block"/>
</router-link>
<span class="pt-4 pl-3">Hello,<br> {{ user.username }}</span>
</div>
</div>
<div v-else>
<ul id="btn-content" class="d-flex list-unstyled justify-content-between components">
<li><router-link
:to="{name:'login'}"
><i class="fas fa-sign-in-alt"></i> Login
</router-link></li>
<li><router-link
:to="{name:'register'}"
><i class="fas fa-registered"></i> Register
</router-link></li>
</ul>
</div>
<ul class="list-unstyled components">
<li>
<router-link
:to="{name:'home'}"
>
<i class="fas fa-home"></i> Home
</router-link>
</li>
<li>
<a href="#pageSubmenu" data-toggle="collapse" aria-expanded="false" class="dropdown-toggle"><i
class="fas fa-gamepad"></i> Games</a>
<ul class="collapse list-unstyled" id="pageSubmenu">
<li>
<a href="#">Seek games</a>
</li>
</ul>
</li>
<li>
<router-link
:to="{name: 'about'}"
>
<i class="fas fa-address-card"></i> About
</router-link>
</li>
<li>
<a v-if="user" class="btn btn-danger"
@click.prevent="logout"
>Logout</a>
</li>
</ul>
</nav>
<div id="content">
<menu-app></menu-app>
<router-view></router-view>
</div>
</div>
</template>
<script>
import Menu from "../Menu/Nav";
export default {
name: 'Sidebar',
components: {
'menu-app': Menu
},
data () {
return {
user: ''
}
},
methods: {
logout: function () {
this.$store.dispatch('logout')
.then(() => {
this.user = false;
this.$router.push('/login')
})
},
}
}
</script>
我的商店模块:
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios';
import setAuthorizationToken from "../module/axiosHeader";
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
status: '',
token: localStorage.getItem('token') || '',
user: localStorage.getItem('user') || {}
},
mutations: {
auth_request(state) {
state.status = 'loading'
},
auth_success(state, token) {
state.status = 'success'
state.token = token
},
auth_user(state, user){
state.user =user
},
auth_error(state) {
state.status = 'error'
},
logout(state) {
state.status = ''
state.token = ''
},
},
actions: {
login({commit}, user) {
return new Promise((resolve, reject) => {
commit('auth_request')
axios({url: '/api/login_check', data: user, method: 'POST'})
.then(resp => {
const token = resp.data.token.token
const user = resp.data.user
localStorage.setItem('token', token)
localStorage.setItem('user', JSON.stringify(user))
localStorage.setItem('authenticated', 'success')
axios.defaults.headers.common['Authorization'] = 'Bearer ' + token
commit('auth_success', token)
commit('auth_user', user)
resolve(resp)
})
.catch(err => {
commit('auth_error')
localStorage.removeItem('token')
reject(err)
})
})
},
register({commit}, user) {
return new Promise((resolve, reject) => {
commit('auth_request')
axios({url: '/api/register', data: user, method: 'POST'})
.then(resp => {
const token = resp.data.token
const user = resp.data.user
localStorage.setItem('token', token)
setAuthorizationToken(token)
commit('auth_success', token)
commit('auth_user', user)
resolve(resp)
})
.catch(err => {
commit('auth_error', err)
localStorage.removeItem('token')
reject(err)
})
})
},
logout({commit}) {
return new Promise((resolve, reject) => {
commit('logout')
axios({url: '/api/logout'}).then(() => {
localStorage.clear();
setAuthorizationToken();
resolve()
}
).catch(error => {
reject(error)
}
)
})
}
},
getters: {
isLoggedIn: state => !!state.token,
authStatus: state => state.status,
userInfo : state => state.user
}
})
并完成我的 Vue 实例:
import Vue from 'vue';
import router from '../routes';
import App from '../views/App';
import {store} from "../stores/authentication-store";
import Axios from "axios";
import setAuthorizationToken from "./axiosHeader";
export default class VueClass {
static init() {
let hours = 24; // Reset when storage is more than 24hours
let now = new Date().getTime();
let setupTime = localStorage.getItem('setupTime');
if (setupTime == null) {
localStorage.setItem('setupTime', now)
} else {
if (now - setupTime > hours * 60 * 60 * 1000) {
localStorage.clear()
localStorage.setItem('setupTime', now);
}
}
router.beforeEach((to, from, next) => {
const publicPages = ['/login', '/register'];
const authRequired = !publicPages.includes(to.path);
const loggedIn = localStorage.getItem('user');
if (authRequired && !loggedIn) {
return next('/login');
}
next();
})
Vue.prototype.$http = Axios;
const token = localStorage.getItem('token')
if (token) {
setAuthorizationToken(token)
}
new Vue({
el: '#app',
store,
router,
template: '<App />',
components: {App},
data: {
user: ''
},
created: function () {
this.$http.interceptors.response.use(undefined, function (err) {
return new Promise(function (resolve, reject) {
if (err.status === 401 && err.config && !err.config.__isRetryRequest) {
this.$store.dispatch('logout')
}
throw err;
});
});
},
}
)
}
}
我的问题是,当用户登录或注销时,如何更新我的边栏。我想在他们登录时显示他们的个人资料,否则显示 login/register。
有多种方法可以实现这一点。在这种情况下,由于边栏和用户状态是全局属性,我将使用全局事件来处理它。为此,您可以尝试 Vue 事件总线方法:
创建 event-bus.js
,其中包含以下行:
import Vue from 'vue';
export const EventBus = new Vue();
在 app.js
中导入:
import { EventBus } from './event-bus.js';
那你就可以这样用了
发出事件(当用户登录或注销时):
EventBus.$emit('userLoggedIn', this.user);
(您也可以在商店中设置 user
而不是将其作为参数传递。)
或
EventBus.$emit('userLoggedOut');
您可以像这样在任何相关组件(例如您的边栏组件)中监听此事件:
导入 event-bus
:
import { EventBus } from '../event-bus.js';
然后是这样的:
created() {
EventBus.$on('userLoggedIn', () => {
// do whatever necessary
});
EventBus.$on('userLoggedOut', () => {
// do whatever necessary
});
}