VueRouter 路由守卫使用案例:进入页面时进行值集加载

路由守卫的使用案例------进入页面时进行值集加载

背景

项目里的前端项目是一个很大的项目,很多前端都在这个项目里开发,大概有三五个。而每个人都在自己开发的页面单独写了请求值集的方法,这就导致维护困难,代码量冗余。为何不把请求值集的方法统一起来做一个入口呢? 公司目前前端技术栈使用的是vue2

背景知识------值集是什么?

这个好像各家的叫法都不太一样,简单来说这东西就是key和value的合集。比如订单状态,以'已支付'状态为例,首先后端在真正保存数据到数据库的时候,不会真的保存一个中文字符串'已支付',而是会把它映射成一个自定义值,比如字符串'10'。后端提供的查询接口中,状态字段的值为'10',前端为了翻译成对应的中文值,就需要获取映射关系。 在数据库里,简化后的数据结构长这样。后端提供的查询接口关键词是值集代码。用值集代码查出对应的键值对集合:

值集代码 值集key 值集value
ORDER_STATE 10 待支付
ORDER_STATE 20 已支付

(值集的典型应用------下拉框)

当前现状

由于这个前端项目混合了许多页面,好几个前端在同时写。虽然后端请求值集的接口是固定的,但是每个前端都在自己写的页面里额外写了一个函数来获取值集,造成了相当大的代码冗余,难以维护。所以打算参考之前大哥写的一个思路,用路由守卫的方式去请求值集。我们只需要维护一个页面→值集的map配置,新增页面的时候,在配置里添加对应的值机代码就行了

实现思路

设置一个自定义的路由守卫,在进入某一页面前(beforeEach钩子),根据页面的路由查找一个自定义的配置。再根据查找到的配置请求接口,将获取到的接口存入到localStorage或VueStore里。

看看代码

我们先自定义一个维护值集属性的js,这样后续我们新增页面需要使用新值集时,只需要修改这个配置文件,新增路由和值集代码就可以了,这样就做到了统一入口维护。

arduino 复制代码
// value-set-config.js
let config = [
  '/orderManage/list': ['ORDER_STATE'],
]
export default config

然后我们写一个js,这个js做数据处理,请求后端接口-转换数据格式-保存转换后数据格式至缓存 这部分各家都有各家的处理方法,代码也就只截取部分,做个大概展示了哈

typescript 复制代码
// value-set.js

import { get } from '@/libs/axios';
import store from '../store';
import valueSetCode from './value-set-config'


// 数据格式化
let dataFormat = (data) => {
	let result = {};
	if (data && typeof (data.data) == 'object') {
		for (var key in data.data) {
			// result[key] = data.data[key].map(({ id, itemCode, itemName, setName, status }) => {
			// 	return { id, itemCode, itemName, setName, status }
			// });
			result[key] = data.data[key].map((item) => {
				return { ...item }
			});
		}
	}
	return result;
}


// 请求后端值集查询接口
let requestFn = (routerName, type = 'byRouter') => {

	let url = OPTIONS.url;
	if (url === null || OPTIONS.valueSetCodeObj === null) {
		throw new Error('value-set OPTIONS 缺少配置')
	}
  
  // axios请求
	return get(url)(getParams(routerName));
}


//router 全局路由获取
export let getValueSetByRouter = async (routerName, router) => {

	let { data } = await requestFn(routerName)
	if (!data.data) {
		localStorage.setItem('codeSet', '{}');
		return;
	}
	let currentRouter = router.currentRoute.name;
	localStorage.setItem('codeSet', JSON.stringify(dataFormat(data)));
	return dataFormat(data);
}


// 根据路由名称,读取配置,并请求后端接口,保存请求数据至VueStore
let getValueSetCode = async (routerName, router) => {
	console.log(routerName,'routerName')
	// 解决初始化值集报错
	let initCodeValue = () => {
		let obj = {};
		if (!valueSetCode[routerName]) {
			return 'no result';
		}
		valueSetCode[routerName].forEach(key => {
			obj[key] = [];
		})
		store.dispatch('setValueSetCode', obj)
	}
	if (initCodeValue() === 'no result') return;
	let result = await getValueSetByRouter(routerName, router);
	// console.log(result)
	store.dispatch('setValueSetCode', result)
}

VueStore的定义比较常规,就是最基础的取值设值,就不展示了。 最后,我们定义一个钩子函数,在路由至页面之前,调用之前定义好的接口,根据路由路径请求值集数据,并保存到缓存中

javascript 复制代码
// router/index.js

/**
* 省略若干无关代码
**/

// 路由配置
const RouterConfig = {
    mode: 'hash',
    routes: routers
};

export const router = new VueRouter(RouterConfig);
export default router;


// 钩子函数
router.beforeEach((to, from, next) => {
    // 省去若干无关代码
    getValueSetCode(to.name, router) // 请求值集
    // 省略若干无关代码
});

在main.js引入并使用自定义的router即可

javascript 复制代码
// main.js

import Vue from 'vue'
import { router } from './router/index'
/**
* 省略若干无关代码
**/
var vm = new Vue({
  ... // 省略无关代码
  el: '#app',
  router,
  ... // 省略无关代码
  },
})
export default vm

赛后总结

对于值集的加载,我们使用了统一入口进行处理,分成了以下几个步骤:

  1. 使用一个map来保存路由与请求值集之间的映射关系
  2. 自定义一个方法,这个方法的入参是 路由路径,实现的功能是请求后端的值集查询接口,并将请求值保存在缓存中
  3. 自定义路由守卫,在路由至指定页面前,请求步骤2中定义的方法,这样页面中就能获取到对应的值集了
xml 复制代码
// 指定页面中使用store中的值集
// 使用案例一则

<template>
<!-- 省去若干代码 -->
        <Form label="订单状态">
              <Select v-model="orderForm.orderState" disabled>
                <Option
                  v-for="(item, index) in valueSet.ORDER_STATE"
                  :value="item.itemCode"
                  :key="index"
                >
                  {{ item.itemName }}
                </Option>
              </Select>
        </Form >
<!-- 省去若干代码 -->
</template>

<script>
import { mapGetters } from "vuex";

export default {
  data(){
    return{
       orderForm:{ orderState:'' }
    }
  },
  computed:{
    valueSet() {
      return this.$store.state.codeValue.valueSet;
    }  
  },
  ...
}
</script>
相关推荐
程序媛小果2 分钟前
基于java+SpringBoot+Vue的桂林旅游景点导游平台设计与实现
java·vue.js·spring boot
喵叔哟21 分钟前
重构代码之取消临时字段
java·前端·重构
还是大剑师兰特1 小时前
D3的竞品有哪些,D3的优势,D3和echarts的对比
前端·javascript·echarts
王解1 小时前
【深度解析】CSS工程化全攻略(1)
前端·css
一只小白菜~1 小时前
web浏览器环境下使用window.open()打开PDF文件不是预览,而是下载文件?
前端·javascript·pdf·windowopen预览pdf
方才coding1 小时前
1小时构建Vue3知识体系之vue的生命周期函数
前端·javascript·vue.js
man20171 小时前
【2024最新】基于springboot+vue的闲一品交易平台lw+ppt
vue.js·spring boot·后端
阿征学IT1 小时前
vue过滤器初步使用
前端·javascript·vue.js
王哲晓1 小时前
第四十五章 Vue之Vuex模块化创建(module)
前端·javascript·vue.js
丶21361 小时前
【WEB】深入理解 CORS(跨域资源共享):原理、配置与常见问题
前端·架构·web