缘起

哈喽大家好,今天周四啦,楼主明天要正式放假了,这里先祝大家节日快乐咯,希望在家里能继续研究点儿东西吧,今天呢是 nuxt
的最后一篇,主要是对权限登录进行研究,这一块咱们之前在说第一个项目的时候已经稍微说到了,具体的逻辑大家可以查看这篇文章《二十四║ Vuex + JWT
实现授权验证登录 <https://www.cnblogs.com/laozhang-is-phi/p/9658019.html>
》,具体的运行原理和流程,以及什么是 vuex ,在那里已经说的很清楚了,今天咱们就是主要在 nuxt
框架中使用,主要的代码的形式,理论知识比较少了,大家可以歇一歇了。这几天写了这么多,好多人可能都没看,不过没关系,继续回顾:

《二七║ Nuxt 基础:框架初探 <https://www.cnblogs.com/laozhang-is-phi/p/9682289.html>》:通过
SSR 来引入 nuxt 框架,第一次接触到该框架;

《二八║ Nuxt 基础:面向源码研究Nuxt.js
<https://www.cnblogs.com/laozhang-is-phi/p/9687504.html>》:通过研究 node_modules
中的源码,带领大家一步步了解 nuxt 是如何进行服务端渲染的;

《二九║ Nuxt实战:异步实现数据双端渲染 <https://www.cnblogs.com/laozhang-is-phi/p/9697450.html>
》:通过首页的数据加载,更加深刻的了解到 nuxt 的双端渲染,异步很重要;

《 三十║ Nuxt实战:动态路由+同构 <https://www.cnblogs.com/laozhang-is-phi/p/9702677.html>
》:通过首页和详情页的交互,进一步巩固 nuxt 的渲染模式和动态路由效果。

从上边大家可以看到,几乎每一篇都会说到 nuxt 这个框架的渲染模式,这个很重要,更是对 vue 的巩固。好啦,马上开始今天的讲解~

 

零、今天要完成橙色的部分



 

一、为详情页增加权限验证


 今天呢,咱们换一种玩儿法,就是将我们的详情页给增加一个权限,首页的数据大家都可以随便看,但是详情页却不能随便看,必须要登录,那我们就需要在我们的详情页增加一个权限,

如果 token 存在,则发送请求验证,如果不存在,直接跳转到登录页,那我们首先要添加一个登录页

1、添加登录页,获取token

 在 pages页面文件夹下,新建login 文件夹,然后添加 index.vue 登录页面,

这一块逻辑和我们之前的很像,大家可以参考着做对比


<template> <el-row type="flex" justify="center"> <el-card v-if="isLogin">
欢迎:admins<br> <br> <el-button type="primary" icon="el-icon-upload" @click="
loginOut">退出登录</el-button> </el-card> <el-form v-else ref="loginForm" :model="
user" :rules="rules" status-icon label-width="50px"> <el-form-item label="账号"
prop="name"> <el-input v-model="user.name"></el-input> </el-form-item>
<el-form-item label="密码" prop="pass"> <el-input v-model="user.pass" type="
password"></el-input> </el-form-item> <el-form-item> <el-button type="primary"
icon="el-icon-upload" @click="login">登录</el-button> </el-form-item> </el-form>
</el-row> </template> <script> import Vue from "vue"; export default { methods:
{ login: function() { let that= this; that.$store.commit("saveToken", ""); this
.$refs.loginForm.validate(valid => { if (valid) { //
发送请求登录,这里要注意下返回数据格式,如果有问题,参考 http.js 中的 response 设置 Vue.http.get("
Login/GetTokenNuxt?name="+that.user.name+"&pass="+that.user.name+"").then(res =>
{if (res.success) { console.log("登录成功"); var token = res.token;
that.$store.commit("saveToken", token); this.$notify({ type: "success", message:
"欢迎你," + this.user.name + "!", duration: 3000 }); this.$router.replace("/"); }
}).catch(err => { console.log("点赞失败", err); }); } else { return false; } }); },
loginOut(){this.isLogin=false; this.$store.commit("saveToken", ""); } }, data()
{return { isLogin:false, user: {}, rules: { name: [{ required: true, message: "
用户名不能为空", trigger: "blur" }], pass: [{ required: true, message: "密码不能为空",
trigger:"blur" }] } }; }, created() { } } </script>
2、自定义服务端插件 elementUI 



 

提醒:这里我用到了 elementUI ,请安装
npm i element-ui -S
安装成功后,作为插件使用,如果你不是很了解,请访问官网《插 件 <https://zh.nuxtjs.org/guide/plugins>
》一章节,这里说的很清楚,我在之前的文件中也有提到。

 在 plugins/server_site 文件夹下,新增 ElementUI.js 文件,作为我们的插件
import Vue from 'vue' import ElementUI from 'element-ui' Vue.use(ElementUI)
然后把这个 js 插件导入到 index.js 中,和 http.js一起注入到nuxt.config.js 中
//这个是 server_site 服务端插件全部 import Vue from "vue"; import http from "./http.js";
import"./ElementUI.js";//导入 elementUI插件 const install = function (VueClass,
opts = {}) { // http method VueClass.http = http; VueClass.prototype.$http =
http; }; Vue.use(install);
因为我们是把服务端的插件都打包了 server_site 下的index中,所以我们以后不用每一个都注入到我们的配置文件 nuxt.config.js
中,只需要将 服务端插件 一个放进去即可,但是样式还是需要引用的



 

 

3、在 strore 文件夹中,添加 index.js 文件,设置我们的store数据


import Vue from "vue"; import Vuex from "vuex"; Vue.use(Vuex); const store =
() =>new Vuex.Store({ state: { isLogined: false, token: "",//这里主要是用到了 token
userInfo: { name:"" }, loginBoxVisible: false }, mutations: { //保存 token 到
store和本地中 saveToken(state, data) { state.token = data;
window.localStorage.setItem("Token", data); }, changeLoginState (state,
isLogined) { state.isLogined= isLogined; }, changeLoginBoxVisible (state,
visible) { state.loginBoxVisible= visible; }, updateUserInfo (state, userInfo)
{ state.userInfo= userInfo; } }, actions: { initUser ({ state, commit }) { const
user = JSON.parse(localStorage.getItem("userInfo")); if (user) { state.userInfo
= user; commit("changeLoginState", true); } } } }); export default store;
 

4、详情页中增加权限验证

 大家一定还记得这个图片,这个是我们之前讲到的 nuxt 的执行流程图,这里说下 fetch()



fetch 方法用于在渲染页面前填充应用的状态树(store)数据, 与 asyncData 方法类似,不同的是它不会设置组件的数据。

如果页面组件设置了 fetch 方法,它会在组件每次加载前被调用(在服务端或切换至目标路由之前)。

 

我们可以利用该方法,获取 状态树 中的 token 信息,并做处理,在昨天的基础上,我们只对 fetch() 方法,简单修改
<script> import Vue from "vue"; export default { layout: "blog", async
asyncData ({params, error }) { // 获取文章详情 let data = {}; try { data = await
Vue.http.get(`blog/${params.id}`); return { data: data }; } catch (e) { //
error({ statusCode: 404, message: "出错啦" }); } }, //在这里进行判断 token fetch ({
store, redirect }) {if (!(store.state.token&&store.state.token.length>=128)) {
//跳转登录页 return redirect('/login') } }, data () { return { comments: [] }; },
head () {return { title: `${this.data.btitle}`, meta: [ { name: "description",
content:this.data.btitle } ] }; } }; </script>
 

5、最后在 http.js 中,开启 http 拦截器 
// http.interceptors.request.use((data, headers) => { // return data; // }); //
http request 拦截器 http.interceptors.request.use( config => { //
注意,首次服务端渲染的时候,还没有出现 DOM,所以找不到 windows 对象,这里用 try 处理掉了 try { if
(window.localStorage.Token&&window.localStorage.Token.length>=128) {//
store.state.token 获取不到值 config.headers.Authorization =
window.localStorage.Token; } }catch (e) { } return config; }, err => { return
Promise.reject(err); } );
 

6、查看页面,体验效果

这里我们就已经限制了详情页,需要登录才能查看,其实这一块逻辑我们可以单拿出来放到中间件 middleware 里来使用,效果会更好,这里举个栗子:路由鉴权
<https://zh.nuxtjs.org/examples/auth-routes>

提醒: 因为我们用的是 store 判断的是否登录,但是如果刷新页面,我们用的是 服务端渲染,所以 store
会被更新掉,也就是为空了,大家可以用两个办法处理
1、用 localStorage 来判断是否存在token;

2、每次服务端渲染,需要更新状态树 store 中的 token;

 

 

二、结语 

 今天的讲解比较简单,主要是验证逻辑我们之前也已经提到了,在我们系列的 24 篇中,本文只是简单的将其搬到我们的 nuxt
框架中来,只不过中间还是会有一些小问题大家需要注意:

1、插件 plugins 的使用很重要,2、基于 axios 的 http 封装,我只是写了简单的一个
demo,复杂的大家可以找一些大的项目框架,自行研究研究;3、路由机制也是需要留心的一个小知识点,虽然不需要我们配置了,不过还是要了解内部结构。

好啦,nuxt 基本教程这里就说这么多吧,祝大家在大长假里开开森森哒~

 

三、GitHub

https://github.com/anjoy8/Blog.Vue.Nuxt
<https://github.com/anjoy8/Blog.Vue.Nuxt>

友情链接
ioDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信