侦听器、axios拦截器、导航守卫

侦听器

官方文档

侦听器:某个值(能通过this访问的)change事件

定义:

watch(data兄弟){
    
    
 本质就是一个function
 方法名(1:完整的写出该值2.去掉this,加上引号)(newVal,oldVal){
    
    
 		newVal:当前值
 		oldVal:上一刻的值
	 }
}

应用场景:
使用element-ui时,el-dialog写编辑页面时,使用isShow作为弹出改变的条件(:visible.sync="isShow")时,可用其重置表单(回到表单初始状态)

watch:{
    
    
	isShow(newVal){
    
    
		if(newVal===false){
    
    
			//重置表单
			this.$refs.from.resetFields()
		}
	}
}

axios拦截器

官方文档

拦截器是axios提供给开发者的一组回调函数,让我们可以在特定的时候添加自定义的逻辑

在这里插入图片描述

  1. 请求拦截器
    1. 发送请求的时候触发的回调函数
  2. 响应拦截器
    1. 数据响应回来之后,触发的回调函数

案例:
src目录下新建api文件夹下创建index.js配置拦截器

import axios from 'axios'
let _fetch = axios.create({
    
    
  baseURL:'https://autumnfish.cn/api',
  withCredentials: true     // 跨域类型时是否在请求中协带cookie
})
// 添加请求拦截器
_fetch.interceptors.request.use(function (config) {
    
    
  // 在发送请求之前做些什么
  window.console.log('请求拦截:',config);
  // config:就是axios请求的配置
  config.params.num = 10
  return config;
}, function (error) {
    
    
  // 对请求错误做些什么
  return Promise.reject(error);
});

// 添加响应拦截器
_fetch.interceptors.response.use(function (response) {
    
    
  // 对响应数据做点什么
  window.console.log('响应拦截器:',response);
  response.data.jokes = response.data.jokes[0]
  response.data.msg = '获取1条笑话'
  return response;
}, function (error) {
    
    
  // 对响应错误做点什么
  return Promise.reject(error);//暴露一个错误
});

function getList(params){
    
    
  return _fetch({
    
    
    url:'/joke/list',
    params
  })

}
export {
    
    getList}

App.vue

<template>
	<div>
		<button @click="getData">点我调用get</button>
	</div>
</template>

<script>
/* get 请求可用接口: https://autumnfish.cn/api/joke/list?num=10 */
import {
    
     getList } from '@/api/index.js'
export default {
    
    
	methods: {
    
    
		getData() {
    
    
			getList({
    
     num: 20 }).then((res) => {
    
    
				window.console.log(res)
			})
		},
	},
}
</script>

<style></style>

拦截的数据
在这里插入图片描述
在这里插入图片描述

  • 请求拦截和响应拦截的数据都是可以修改的,这里在请求拦截修改num 的参数为10,响应回来的结果也就只有10条
  • 响应拦截可以修改,如果改成一条,name只能获得一条数据

实际应用场景

// 使用axios
import axios from 'axios'
// 引入 message
import {
    
     Message } from 'element-ui' //Message相当于this.$message
import {
    
     getLocal, removeLocal } from '@/utils/local.js'
// 导入路由实例对象
import router from '@/router/index.js'
// 创建axios副本(修改axios的默认值)
const _fetch = axios.create({
    
    
  baseURL: process.env.VUE_APP_URL,
  withCredentials: true//跨域类型时是否在请求中协带cookie
})
// 添加请求拦截器
_fetch.interceptors.request.use(
  function (config) {
    
    
    // 在发送请求之前做些什么
    // window.console.log('请求拦截', config)
    config.headers.token = getLocal('token')
    return config
  },
  function (error) {
    
    
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

// 添加响应拦截器
_fetch.interceptors.response.use(
  function (response) {
    
    
    // 对响应数据做点什么
    // window.console.log('响应拦截', response)
    if (response.data.code == 200) {
    
    
      return response
    } else if (response.data.code == 206) {
    
    
      //提示一下
      Message.error(response.data.message)
      //清除token
      removeLocal('token')
      //跳转至登陆页   this.$router===router的实例对象
      router.push('/login')
      // 不是200情况.,我们都不希望.then再执行,直接让它跳转到.catch
      return Promise.reject(response.data.message)
    } else {
    
    
      Message.error(response.data.message)
      // alert(response.data.message)
      // return undefined
      // 不是200情况.,我们都不希望.then再执行,直接让它跳转到.catch
      return Promise.reject(response.data.message)
    }
  },
  function (error) {
    
    
    // 对响应错误做点什么
    return Promise.reject(error)
  }
)
export default _fetch

  • 在请求拦截时携带token
  • 在响应返回错误时.,我们都不希望.then再执行,直接让它跳转到.catch(return Promise.reject(response.data.message)

导航守卫

官方文档

如果我们希望在页面加载之前执行一些逻辑的话,可以使用导航守卫,执行的时机比组件的生命周期钩子更早

在这里插入图片描述

  • 前置守卫:还没有出from的路由
    • to:即将要进入的目标 路由对象,相当于相应路由的的this.$route
    • from:当前导航正要离开的路由,相当于相应路由的的this.$route
    • next():表示正常通过,不正常通过 next(path)
  • 后置守卫:已经进入to的路由
    • to:即将要进入的目标 路由对象,相当于相应路由的的this.$route
    • from:当前导航正要离开的路由,相当于相应路由的的this.$route
  • 应用
    • 进度条
    • 权限判断
    • 修改title
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
// 导入组件
import login from '@/views/login/login.vue'
import layout from '@/views/layout/layout.vue'
import business from '@/views/layout/business/business.vue'
import chart from '@/views/layout/chart/chart.vue'
import user from '@/views/layout/user/user.vue'
import subject from '@/views/layout/subject/subject.vue'
import question from '@/views/layout/question/question.vue'

// 实例化路由
const router = new VueRouter({
    
    
	routes: [
		// 准备路由规则
		{
    
     path: '/', redirect: '/login' },
		{
    
    
			path: '/login',
			component: login,
			meta: {
    
    
				title: '登录',
				roles:['超级管理员', '管理员', '老师', '学生']
			},
		},
		{
    
    
			path: '/layout',
			component: layout,
			redirect: '/layout/subject',
			children: [
				{
    
    
					path: '/layout/chart',
					component: chart,
					meta: {
    
    
						icon: 'el-icon-pie-chart',
						title: '数据概览',
						roles:['超级管理员', '管理员', '老师']
					},
				},
				{
    
    
					path: '/layout/user',
					component: user,
					meta: {
    
    
						icon: 'el-icon-user',
						title: '用户列表',
						roles:['超级管理员', '管理员']
					},
				},
				{
    
    
					path: '/layout/question',
					component: question,
					meta: {
    
    
						icon: 'el-icon-edit-outline',
						title: '题库列表',
						roles:['超级管理员', '管理员', '老师']
					},
				},
				{
    
    
					path: '/layout/business',
					component: business,
					meta: {
    
    
						icon: 'el-icon-office-building',
						title: '企业列表',
						roles:['超级管理员', '管理员', '老师']
					},
				},
				{
    
    
					path: '/layout/subject',
					component: subject,
					meta: {
    
    
						icon: 'el-icon-notebook-2',
						title: '学科列表',
						roles:['超级管理员', '管理员', '老师', '学生']
					},
				},
			],
		},
	],
})
import Nprogress from 'nprogress'
import 'nprogress/nprogress.css'
import store from '@/store/index.js'
import {
    
    Message} from 'element-ui'
import {
    
     removeLocal } from '@/utils/local.js'
// 路由导航守卫
// 路由前置守卫(还没进入目标路由)
// 路由拦截处理
router.beforeEach((to, from, next) => {
    
    
	//to:去的路由的信息 $route
	// from:从哪来的路由信息 $route
window.console.log('前to:',to);
window.console.log('前from:',from);
	// 进度条开始
	Nprogress.start()
	if(to.meta.roles.includes(store.state.role)){
    
    
		next() //允许通过 next()  不允许通过 next('path)

	}else{
    
    
		Message.error('您无权访问该页面')
		removeLocal('token')
		next('/login')
	}

})
// 路由后置守卫(已进入目标路由)
router.afterEach((to,from) => {
    
    
	window.console.log('后to:',to);
	window.console.log('后from:',from);
	// 结束进度
	Nprogress.done()
	// 修改title
	document.title = '名称---' + to.meta.title
})

// 暴露router
export default router

猜你喜欢

转载自blog.csdn.net/weixin_44757417/article/details/108923282
今日推荐