第五章 路由钩子及插件开发
前言
本章开始有点深入了哦~请同学们拿出你们的小本本,认真记笔记!上一章我们的登录页大概逻辑已经理顺了,今天我们完善一下。
登录标识(token)
有加群的小伙伴提出登录没有token,因为我们是自己mock数据的,所以只能写死返回一个冒牌token~,请打开src/mock/index.js
,把它改造一下,在返回结果中,新增token字段:
//mock/index.js
import Mock from 'mockjs'
//验证账号密码
let uTable = {
'password': '123456',
'username':"admin",
'token':'abcde12345'
}
const data = Mock.mock('http://user.com/login', (param) => {
let dataJson = JSON.parse(param.body)
if((dataJson.username == uTable.username) && (dataJson.password == uTable.password)) {
let result = {
state: 'ok',
token: uTable.token
}
return result
} else {
let result = {
state: 'no',
token: ''
}
return result
}
})
export default {
data
}
复制代码
此时在登录组件中,便可以打印出结果,如果账号密码匹配的话,你会看到多了token字段,接着我们要把获取的toke种到cookie里,因为有很多地方要操作cookie,我们写成插件,方便调用。在src下,新建plugins/components/cookies/index.js
//设置cookie
const setCookie = (c_key,c_val,exdays) => {
let exdate=new Date();
exdate.setTime(exdate.getTime() + 24*60*60*1000*exdays);//保存的天数
//字符串拼接cookie
window.document.cookie=c_key+ "=" +c_val+";path=/;expires="+exdate.toGMTString();
}
//获取cookie
const getCookie = (c_key) => {
let arr,reg=new RegExp("(^| )"+c_key+"=([^;]*)(;|$)");
if(arr=document.cookie.match(reg))
return unescape(arr[2]);
else
return null;
}
//删除cookie
const delCookie = (c_key) => {
let exp = new Date();
exp.setTime(exp.getTime() - 1);
let cval=getCookie(name);
if(cval!=null)
document.cookie= name + "="+cval+";expires="+exp.toGMTString();
}
//对外暴露方法
export default {
setCookie,
getCookie,
delCookie
}
复制代码
为了不必每次调用插件都得引入,我们把它添加为全局方法,新建plugins/index.js
//plugins/index.js
//引入刚才写好的插件
import Cookies from './components/cookies';
export default {
install(Vue,options) {
Vue.prototype.$Cookies = Cookies
}
}
复制代码
install
:当我们在main.js中用Vue.use()的时候,会默认调用install方法,并且会返回两个值:vue实例,可选的options参数。这一步完成后,我们在main.js
里注册一下。
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import axios from 'axios'
import Mock from '@/mock/index'
//引入刚才的plugins/index.js
import plugins from '@/plugins'
Vue.use(ElementUI);
//绑定到全局
Vue.use(plugins);
Vue.config.productionTip = false
Vue.prototype.$http= axios
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
复制代码
插件搞定!然后就可以在任意组件中,通过this.$Cookies.setCookie()
来进行调用。现在打开src/pages/user/Login.vue
组件,通过我们封装的cookie插件,把token种到cookie中:
<template>
<div class="login_page">
<section class="form_contianer">
<div class="manage_tip">
<p>第一个后台管理系统</p>
</div>
<el-form>
<el-form-item prop="username">
<el-input placeholder="用户名" v-model="uname"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input type="password" placeholder="密码" v-model="pwd"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" class="submit_btn" @click="login">登陆</el-button>
</el-form-item>
</el-form>
</section>
</div>
</template>
<script>
export default {
data() {
return {
uname:'',
pwd:''
}
},
methods: {
login () {
let self = this
this.$http({
method: 'get',
url: 'http://user.com/login',
data: {
username: this.uname,
password: this.pwd
}
})
.then((r) => {
if(r.data.state == 'ok') {
self.$Cookies.setCookie('mytoken',r.data.token)
self.$router.push({path:'/'})
} else {
self.$message.error('账号或密码错误,请重新填写');
}
})
}
}
}
</script>
<style scoped>
@import '../../assets/css/login.css';
</style>
复制代码
cookie种好了,童鞋们可以自行console一下看是否成功,至于怎么打印,调用我们封装的插件喽,如果不会请自行领悟。。种了cookie还没完,我们还需要在路由跳转前进行判断,如果没有cookie,也就是没登录,那我们就不允许打开首页或其他页面,这里就要用到路由钩子beforeEnter
,现在打开src/router/index.js
:
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Login from '@/pages/user/Login'
import $Cookies from '@/plugins/components/cookies'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld,
//路由钩子,在跳转前进行判断
beforeEnter: (to, from, next) => {
console.log($Cookies.getCookie('mytoken'))
if($Cookies.getCookie('mytoken')) {
next()
}else {
next({path:'/login'})
}
}
},
{
path: '/login',
name: 'Login',
component: Login
}
]
})
复制代码
beforeEnter
:每个钩子方法接收三个参数:
- to:即将要进入的目标
- from : 当前导航正要离开的路由
- next(): 进行管道中的下一个钩子。一定要调用该方法来 resolve 这个钩子。next({ path: '/login' })这个写法就是把当前路由重定向到我们指定的路由。
这里要强调一下,为什么不直接用this.$Cookies来调用我们的插件呢,因为当钩子执行前,组件实例还没被创建,this自然也就是个野指针喽。所以我们只能把插件引入再调用。
结语
继续广告下我们的Q群:57991865,欢迎进群交流。
完整代码点我,密码:czkn