Vue+element+Nodejs学习记录(6)

26 篇文章 0 订阅
23 篇文章 1 订阅

1.axios拦截

axios拦截就是axios的二次封装,这样便于权限管理和统一异常处理,全局拦截器可以根据接口错误码进行统一处理,而不需要再每一个接口内部进行控制,第二个好处就是,可以做全局的loading效果,如果不在全局做,你就要在每一个接口前显示loading,接口结束进行关闭,不便于代码维护,前端尽可能的去统一管理代码。

参考文章:
https://hooray.github.io/posts/1059e373/
https://juejin.im/post/5bab739af265da0aa3593177
https://segmentfault.com/a/1190000008383094
https://zhuanlan.zhihu.com/p/33918784
https://blog.csdn.net/qq_36575992/article/details/80338538
https://blog.csdn.net/qq_38145702/article/details/81558816

https://segmentfault.com/q/1010000017347607/a-1020000017350518
https://blog.csdn.net/well2049/article/details/85003062
https://blog.csdn.net/rickiyeat/article/details/77030124
https://blog.csdn.net/sjn0503/article/details/74729300
https://blog.csdn.net/qq_33207292/article/details/72867211
https://blog.csdn.net/moxiaoya1314/article/details/73650751

2.Express设置cors

1.installation

npm install cors

2.Usage

//1.simple usage(Enable All CORS Requests)
var express = require('express')
var cors = require('cors')
var app = express()

app.use(cors())

app.get('/products/:id', function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for all origins!'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

//2.Enable CORS for a Single Route
var express = require('express')
var cors = require('cors')
var app = express()

app.get('/products/:id', cors(), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for a Single Route'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

//3.Configuring CORS
var express = require('express')
var cors = require('cors')
var app = express()

var corsOptions = {
  origin: 'http://example.com',
  optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}

app.get('/products/:id', cors(corsOptions), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for only example.com.'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

更多介绍可以参考文章:
http://expressjs.com/en/resources/middleware/cors.html#installation

https://www.jianshu.com/p/f650dfad5574
https://blog.csdn.net/sunq1982/article/details/77887655
https://www.jianshu.com/p/af2cad6d91fb

3.Vue中代理设置vue.config.js

我们可以在服务端进行设置跨域,我们在前端也可以设置代理,比如我们的Vue的端口是8080,后端的端口8000,这时就涉及到跨域,要进行代理设置,我们在vue.config.js中设置代码是:

module.exports = {

	publicPath:'/',
	
	devServer:{

		open: true,
	    host: 'localhost',
	    port: 8080,
	    https: false,
	    hotOnly: false,


		proxy:{
			'/api':{
				target:'http://localhost:8000/api',
				changOrigin: true, //允许跨域
				pathRewrite:{
					'^/api':''
				}
			}
		}

	}

}

参考文章:
https://blog.csdn.net/qq_40190624/article/details/85257610
https://blog.csdn.net/weixin_38201500/article/details/84791835
https://segmentfault.com/a/1190000014474361
https://segmentfault.com/a/1190000016602951
https://darknesschaser.github.io/2018/07/26/vue%E5%85%A8%E5%AE%B6%E6%A1%B6%E9%85%8D%E7%BD%AEwebpack%E5%8F%8D%E4%BB%A3/?tdsourcetag=s_pcqq_aiomsg

4.Vuex再学习

参考imooc课程。

Vuex应用场景

1.多个视图依赖于同一状态(多组件之间状态共享,读状态的作用)
2.来自不同视图的行为需要改变同一个状态(不同组件可以改变同一状态,改状态的作用)

Vuex的组成介绍

在这里插入图片描述

1.state:数据仓库
State在Vuex中代表的是数据的来源,Vuex所有数据都会存储在State中,是数据的唯一来源。

2.getter:原来获取数据
可类比Vuex中的computed属性,对state中数据进行一些操作

3.Mutation:用来修改数据
Mutation的操作是同步的,异步的话会有很大的麻烦,Mutation本质上也是一个function

4.Action:用来提交mutation
Action可以进行异步的操作

安装Vuex

1.安装vuex包:npm install vuex
2.创建vuex实例:new Vuex.store()
3.main.js中将vuex实例挂载到vue对象上

Vuex使用

1.获取Vuex中state的值(例如state中的count)

{{this.$store.state.count}}

2.修改state中的值

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

export default new Vuex.Store({

	state:{
		city:'上海'
	},

	mutations:{
		changeCity(state,city){
			state.city = city
		}
	},

	action:{
		changeCity(ctx,city){
			ctx.commit('changeCity',city)
	}

});

Vue文件中如果修改Vuex

最原始写法:this.$store.dispatch('changeCity',city) 使用dispatch触发一个changeCity函数
或者直接使用mutations中commit:this.$store.commit('changeCity',city)

5.token和jwt

身份认证的两种方式

1.基于cookie

基于cookie的服务端认证,就是我们所熟知session,在服务端生成用户相关的 session 数据,而发给客户端 sesssion_id 存放到 cookie 中,这样用客户端请求时带上 session_id 就可以验证服务器端是否存在 session 数据,以此完成用户认证。

2.基于Token令牌

基于token的用户认证是一种服务端无状态的认证方式,服务端不用存放token数据。用户验证后,服务端生成一个token(hash或encrypt)发给客户端,客户端可以放到cookie或localStorage(sessionStorage)中,每次请求时在Header中带上token,服务端受到token通过验证后即可确认用户身份。

JWT的组成

JWT的本质实际上就是一个字符串,它有三部分组成头部+载荷+签名。

// 1.Header
{
  "alg": "HS256",//所使用的签名算法
  "typ": "JWT"
}

// 2.Payload
{
  //该JWT的签发者
  "iss": "luffy",
  // 这个JWT是什么时候签发的
  "iat":1441593502,
  //什么时候过期,这是一个时间戳
  "exp": 1441594722,
  // 接收JWT的一方
  "aud":"www.youdao.com",
  // JWT所面向的用户
  "sub":"any@126.com",
  // 上面是JWT标准定义的一些字段,除此之外还可以私人定义一些字段
  "form_user": "fsdfds"
}

// 3.Signature 签名
将上面两个对象进行base64编码之后用.进行连接,然后通过HS256算法进行加密就形成了签名,一般需要加上我们提供的一个密匙,例如secretKey:'name_luffy'
const base64url = require('base64url')

const base64header = base64url(JSON.stringify(header));
const base64payload = base64url(JSON.stringify(payload));
const secretKey = 'name_luffy';
const signature = HS256(`${base64header}.${base64payload}`,secretKey);


// JWT
// 最后就形成了我们所需要的JWT:
const JWT = base64header + "." + base64payload + "." + signature;
// 它长下面这个样子:
// eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

JWT的工作原理

在这里插入图片描述

前后端如何用这个东西做身份验证

接下来要详细的说如何使用jwt来进行前后端的身份验证了,具体思路如下:

用户登录注册的逻辑不需要身份验证,因为没有用户的身份信息和登录状态;
用户登录之后后端生成token并返给前端,前端拿到token之后将token缓存在本地,可以使localStorage也可以是cookie,以便接下来使用。。
其他内容涉及到前后端交互的都需要前端把认证的token信息放在请求头部传给后端
后端收到请求先校验token,如果token合法(也就是token正确且没过期),则执行next(),否则直接返回401以及对应的message。

token登陆的具体实现细节

查看参考资料:https://juejin.im/post/5b06c6baf265da0db4791805

6.Vue中template中嵌套template

<template>
    <el-row class="menu_page">
         <el-col>

             <el-menu
                mode="vertical"
                background-color="#324057"
                text-color="#fff"
                active-text-color="#409eff" 
                class="el-menu-vertical-demo">

                <!--左侧-首页-->
                <router-link to="/home">
                    <el-menu-item index="0">
                        <i class="el-icon-s-home"></i>
                        <span slot="title">首页</span>
                    </el-menu-item>
                </router-link>

                <!--用户管理和信息管理-->
                <template  v-for="item in items" >

                    <el-submenu v-if="item.children" :index="item.path" :key="item.path">
                        <template slot="title">
                            <i :class="'fa fa-margin '+item.icon"></i>
                            <span slot="title">{{item.name}}</span>
                        </template>
                        <router-link v-for="(citem,cindex) in item.children" 
                            :to="citem.path" :key="cindex">
                            <el-menu-item 
                                :index='citem.path'>
                                <span slot="title">{{citem.name}}</span>
                            </el-menu-item> 
                        </router-link>
                    </el-submenu> 

                </template>

             </el-menu>

         </el-col>
    </el-row>
</template>
<script>
export default {
  name: "leftmenu",
  data() {
    return {
      items: [
        {
          icon: "el-icon-user",
          name: "用户管理",
          path: "fund", //设置:key
          children: [{ path: "foundlist", name: "用户信息" }]
        },
        {
          icon: "el-icon-edit",
          name: "信息管理",
          path: "info",
          children: [{ path: "infoshow", name: "个人信息" }]
        }
      ]
    };
  }
};
</script>
<style scoped>
.menu_page {
  position: fixed;
  top: 60px;
  left: 0;
  min-height: 100%;
  background-color: #324057;
  z-index: 99;
}
.el-menu {
  border: none;
}
.fa-margin {
  margin-right: 5px;
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
  width: 180px;
  min-height: 400px;
}
.el-menu-vertical-demo {
  width: 35px;
}
.el-submenu .el-menu-item {
  min-width: 180px;
}

.hiddenDropdown,
.hiddenDropname {
  display: none;
}
a {
  text-decoration: none;
}
</style>

在这里插入图片描述
把中间的template标签改成div效果是一样的,用template有什么别的作用吗?

回答:template不会渲染成元素,用div的话会被渲染成元素。把if,show,for等语句抽取出来放在template上面,也就是和指令中的v-if/v-for一起用,把绑定的事件放在temlpate里面的元素上,可以使html结构更加清晰,还可以改善一个标签过长的情况。

参考文章: https://segmentfault.com/q/1010000010727886

更多参考资料:
https://segmentfault.com/a/1190000015718564
https://segmentfault.com/a/1190000014062679

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值