main.js
import App from './App.vue'
import Vue from 'vue'
import router from './router/'
import components from './components/header.js' //加载公共组件
import store from './store/'
Object.keys(components).forEach((key) => {
var name = key.replace(/(\w)/, (v) => v.toUpperCase()) //首字母大写
Vue.component(`v${name}`, components[key])
})
router.beforeEach(({ meta, path }, from, next) => {
var { auth = true } = meta
var isLogin = Boolean(store.state.user.id) //true用户已登录, false用户未登录
if (auth && !isLogin && path !== '/login') {
return next({ path: '/login' })
}
next()
})
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
router.js
import Vue from 'vue'
import Router from 'vue-router'
import App from '../App.vue'
// import Home from '../pages/home.vue'
const Home = () => import('../pages/home.vue')
const Login = () => import('../pages/login.vue')
const Main = () => import('../pages/main.vue')
const Loginout = () => import('../pages/loginout.vue')
Vue.use(Router)
const router = new Router({
routes: [
{
path: '/',
component:App,
children:[
{ path: '/', meta: { auth: false },component: Home }, //首页
{ path: '/login', meta: { auth: false },component: Login }, //登录
{ path: '/main', component: Main }, //个人中心
{ path: '/loginout', component: Loginout }, //退出
{
path: '*', //其他页面,强制跳转到登录页面
redirect: '/login'
}
]
},
]
})
export default router
登录状态管理器store
index.js
import Vue from 'vue'
import Vuex from 'vuex'
import user from './user'
// 挂载vuex
Vue.use(Vuex)
// 创建vue对象
export default new Vuex.Store({
modules:{
user
}
})
store.js
import Vue from 'vue'
export const USER_SIGNIN = 'USER_SIGNIN' //登录成功
export const USER_SIGNOUT = 'USER_SIGNOUT' //退出登录
export default {
state: JSON.parse(sessionStorage.getItem('user')) || {},
mutations: {
[USER_SIGNIN](state, user) {
sessionStorage.setItem('user', JSON.stringify(user))
Object.assign(state, user)
},
[USER_SIGNOUT](state) {
sessionStorage.removeItem('user')
Object.keys(state).forEach(k => Vue.delete(state, k))
}
},
actions: {
[USER_SIGNIN]({commit}, user) {
commit(USER_SIGNIN, user)
},
[USER_SIGNOUT]({commit}) {
commit(USER_SIGNOUT)
}
}
}
login.vue
<template> <div> <v-header title="登录"> <router-link slot="left" to="/">返回</router-link> </v-header> <form class="login" @submit.prevent="submit"> <div class="line"> <div v-show="btn && !form.id">id不能为空</div> <input type="text" placeholder="请输入你的id" v-model="form.id" /> </div> <div class="line"> <div v-show="btn && !form.pwd">用户名不能为空</div> <input type="text" placeholder="请输入密码" v-model="form.pwd" /> </div> <button>登录</button> </form> </div> </template> <script> import { mapActions } from "vuex"; import { USER_SIGNIN } from "../store/user"; export default { data() { return { btn: false, form: { id: "", pwd: "" } }; }, methods: { ...mapActions([USER_SIGNIN]), submit() { this.btn = true if (!this.form.id || !this.form.pwd) return this.USER_SIGNIN(this.form); console.log(this.form); this.$router.replace({ path: "/" }); } } }; </script> <style lang="less" scoped> .login { padding: 50px; text-align: center; .line { padding: 5px; input { padding: 0 10px; line-height: 28px; } } } button { padding: 0 20px; margin-top: 20px; line-height: 28px; } </style>
home.vue
<template> <div> <v-header title="首页"> <router-link slot="right" v-if="user.id" to="/main">{{user.id}}</router-link> </v-header> <div class="login-msg" v-if="!user.id"> <router-link to="/login">你还未登录,请先登录</router-link> </div> <div class="msg" v-if="user.id"> 哈哈,恭喜你已经入坑Vue2 </div> </div> </template> <script> import {mapState} from 'vuex' export default { data() { return {}; }, computed:{ ...mapState({user:state => state.user}) } }; </script> <style lang="less" scoped> .login-msg { text-align: center; padding: 50px; } </style>
main.vue
<template> <div> <v-header title="个人中心"> <router-link slot="left" to="/">首页</router-link> <router-link slot="right" to="/loginout">退出</router-link> </v-header> <div>欢迎回家{{user.pwd}}</div> </div> </template> <script> import { mapState } from "vuex"; export default { data() { return {}; }, computed: { ...mapState({ user: state => state.user }) } }; </script> <style lang="less" scoped> </style>
loginout.vue
<template> <div> <v-header title="退出"> <router-link slot="left" to="/main">返回</router-link> </v-header> <div class="btn"> <button @click="submit">确认退出</button> </div> </div> </template> <script> import { mapActions } from 'vuex' import { USER_SIGNOUT } from '../store/user' export default { data() { return {}; }, methods: { ...mapActions([USER_SIGNOUT]), submit() { this.USER_SIGNOUT() this.$router.replace({ path: "/login" }); } } }; </script> <style lang="less" scoped> .btn{ padding: 50px; text-align: center; button{ padding: 5px 10px; } } </style>
公共组件header
header.vue
<template> <div> <header class="header"> <div class="item left"> <slot name="left"></slot> </div> <div class="title">{{title}}</div> <div class="item right"> <slot name="right"></slot> </div> </header> </div> </template> <script> export default { props: { title: { type: String, default: "" } } }; </script> <style lang="less" scoped> .header { position: relative; line-height: 38px; background: #222; color: #fff; text-align: center; .item { position: absolute; top: 0; bottom: 0; z-index: 1; a { color: #fff; } } .left { left: 10px; } .right { right: 10px; } } </style>