此文章属于ruoyi项目实战系列
使用目的
- 什么是字典数据:具体的值(0,1 , "Y","N"),对应具体的业务逻辑("男","女" , "是" , "否") 。
- 字典数据不应该只写死在代码中,还应存入数据库,通过管理系统来增删改查 。
分析
- 入口:查看全局入口文件
main.js
,DictData.install()
是字典功能的入口位置 。
function install() {Vue.use(DataDict, {//额外参数metas: {'*': {labelField: 'dictLabel',valueField: 'dictValue',request(dictMeta) {return getDicts(dictMeta.type).then(res => res.data)},},},})}
install全局注册了一个插件DataDict
,同时传入了额外参数{meta:xxx}
,目的是将DataDict插件对应的参数进行赋值 。
- DataDict插件:因为该插件本身是个function,所以Vue.use会直接将function视为
install()
方法执行 。
export default function (Vue, options) { mergeOptions(options) Vue.mixin({...})}
首先执行mergeOptions(options)
,目的是将传入的额外参数与DictOptions合并 。具体实现是通过递归调用mergeRecursive(source,target)
,将DictOptions的属性覆盖或者添加 。
其次注册全局混入Vue.mixin
,给所有 Vue 实例添加了data()
和created()
方法 。
Vue.mixin({ data(){const dict = new Dict()dict.owner = thisreturn {dict} }, created(){ .... this.dict.init(this.$options.dicts).then(()=>{...}) }})
data (): 每个 Vue 页面创建一个 Dict 。
created(): 调用Dict.init(dicts)方法,传入每个vue页面声明的dicts数组(例如dicts['sys_normal_disable']
) 。(额外补充:init().then(....)里的方法个人认为是为了拓展性,因为我全局查找也没有看到任何地方用到 。)
- Dict. init () : 看注释即可
init(options) {if (options instanceof Array) {//此处传进来的是每个index.vue的dicts属性,基本上是['dictName1','dictName2']之类的 。options = {types: options}}const opts = mergeRecursive(DEFAULT_DICT_OPTIONS, options)//options与DEFAULT合并,并且将合并结果赋值给optsif (opts.types === undefined) {throw new Error('need dict types')}const ps = []this._dictMetas = opts.types.map(t => DictMeta.parse(t)) //调用parse,将数组中的字符串转换为DictMeta对象返回 。this._dictMetas.forEach(dictMeta => {const type = dictMeta.typeVue.set(this.label, type, {})//dict.label添加属性 dictName:{}Vue.set(this.type, type, [])//dict.type 添加属性 dictName[]if (dictMeta.lazy) {return}ps.push(loadDict(this, dictMeta))})loadDict:请求后端api,将数据组装进dictreturn Promise.all(ps)}
- DictMeta.parse
DictMeta.parse= function(options) {let opts = nullif (typeof options === 'string') {opts = DictOptions.metas[options] || {}opts.type = options//opt{type:'字典名称'}} else if (typeof options === 'object') {opts = options}//创建{type:'字典名称"}并且赋值给DictOptions.meta属性opts = mergeRecursive(DictOptions.metas['*'], opts)//构造dictmeta原数据return new DictMeta(opts)}
主要将vue页面的dicts数组以及DictOption的meta数据在整合赋值到DictMeta对象,方便后续调用 。
- loadDict(dict,dictMeta)
function loadDict(dict, dictMeta) {return dictMeta.request(dictMeta)//请求后端api,获取字典数据.then(response => {const type = dictMeta.typelet dicts = dictMeta.responseConverter(response, dictMeta)//将response转换成DictDataif (!(dicts instanceof Array)) {console.error('the return of responseConverter must be Array.<DictData>')dicts = []} else if (dicts.filter(d => d instanceof DictData).length !==dicts.length) {console.error('the type of elements in dicts must be DictData')dicts = []}//将response的数据插入到dict.type['dictName']的数组中//splice实现了响应式改变数组元素,所以这里不用vue.setdict.type[type].splice(0, Number.MAX_SAFE_INTEGER, ...dicts)//将dicts(也就是dictData)赋值给dict.type[type]dicts.forEach(d => {Vue.set(dict.label[type], d.value, d.label)//dict.label{'dictName':{}}添加属性d.value:d.label})return dicts})}
- 具体页面应用例如job/index.vue,
<el-select v-model="queryParams.status" placeholder="请选择任务状态" clearable><el-optionv-for="dict in dict.type.sys_job_status":key="dict.value":label="dict.label":value="https://www.huyubaike.com/biancheng/dict.value"/></el-select> export default{dicts:['sys_job_group','sys_job_status'],//dict:{'sys_job_group':[data1,data2],'sys_job_status':[data1,data2]} 通过上文的代码全局混入得到}
推荐阅读
- 【Spring boot】启动过程源码分析
- 八 Netty 学习:新连接接入源码说明
- 深入底层C源码 Redis核心设计原理
- 七 Netty 学习:NioEventLoop 对应线程的创建和启动源码说明
- Spring mvc源码分析系列--Servlet的前世今生
- spring cron表达式源码分析
- 集合框架——LinkedList集合源码分析
- 含源码 手把手教你使用LabVIEW OpenCV DNN实现手写数字识别
- 补充部分---ScheduledThreadPoolExecutor类分析 线程池底层原理详解与源码分析
- 五 Netty 学习:服务端启动核心流程源码说明