Ruoyi字典源码学习

此文章属于ruoyi项目实战系列
使用目的

  1. 什么是字典数据:具体的值(0 , 1 , "Y" , "N") , 对应具体的业务逻辑("男" , "女" , "是" , "否") 。
  2. 字典数据不应该只写死在代码中 , 还应存入数据库 , 通过管理系统来增删改查 。
源码分析【Ruoyi字典源码学习】ruoyi项目在低于3.7.0的版本中 , 前端字典功能实现比较简单 , 每个index.vue页面都请求dict的api , 获取数据再加工显示即可 。3.7.0之后的版本使用了混入 , 所以复杂了一些 。
分析
  1. 入口:查看全局入口文件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插件对应的参数进行赋值 。
  2. 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(....)里的方法个人认为是为了拓展性 , 因为我全局查找也没有看到任何地方用到 。)
  3. 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)}
简单通过注释解释一下init里的一些调用函数源码
  1. 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对象 , 方便后续调用 。

    经验总结扩展阅读