Ruoyi字典源码学习
此文章属于ruoyi项目实战系列
使用目的
- 什么是字典数据:具体的值(0,1,"Y","N"),对应具体的业务逻辑("男","女","是","否")。
- 字典数据不应该只写死在代码中,还应存入数据库,通过管理系统来增删改查。
源码分析
ruoyi项目在低于3.7.0的版本中,前端字典功能实现比较简单,每个index.vue页面都请求dict的api,获取数据再加工显示即可。3.7.0之后的版本使用了混入,所以复杂了一些。
分析
入口:查看全局入口文件
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 = this
return {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合并,并且将合并结果赋值给opts
if (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.type
Vue.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,将数据组装进dict
return Promise.all(ps)
}
简单通过注释解释一下init里的一些调用函数源码
DictMeta.parse
DictMeta.parse= function(options) {
let opts = null
if (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.type
let dicts = dictMeta.responseConverter(response, dictMeta)//将response转换成DictData
if (!(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.set
dict.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-option
v-for="dict in dict.type.sys_job_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select> export default{
dicts:['sys_job_group','sys_job_status'],
//dict:{'sys_job_group':[data1,data2],'sys_job_status':[data1,data2]} 通过上文的代码全局混入得到
}
Ruoyi字典源码学习的更多相关文章
- Aspects 源码学习
AOP 面向切面编程,在对于埋点.日志记录等操作来说是一个很好的解决方案.而 Aspects 是一个对于AOP编程的一个优雅的实现,也可以直接借助这个库来使用AOP思想.需要值得注意的是,Aspect ...
- Redis源码学习:Lua脚本
Redis源码学习:Lua脚本 1.Sublime Text配置 我是在Win7下,用Sublime Text + Cygwin开发的,配置方法请参考<Sublime Text 3下C/C++开 ...
- threadpool源码学习
threadpool源码学习 __all__ = [ 'makeRequests', 'NoResultsPending', 'NoWorkersAvailable', 'ThreadPool', ' ...
- Asp.NetCore源码学习[2-1]:配置[Configuration]
Asp.NetCore源码学习[2-1]:配置[Configuration] 在Asp. NetCore中,配置系统支持不同的配置源(文件.环境变量等),虽然有多种的配置源,但是最终提供给系统使用的只 ...
- Asp.NetCore源码学习[2-1]:日志
Asp.NetCore源码学习[2-1]:日志 在一个系统中,日志是不可或缺的部分.对于.net而言有许多成熟的日志框架,包括Log4Net.NLog.Serilog 等等.你可以在系统中直接使用这些 ...
- [阿里DIN]从论文源码学习 之 embedding_lookup
[阿里DIN]从论文源码学习 之 embedding_lookup 目录 [阿里DIN]从论文源码学习 之 embedding_lookup 0x00 摘要 0x01 DIN代码 1.1 Embedd ...
- [阿里DIN] 从论文源码学习 之 embedding层如何自动更新
[阿里DIN] 从论文源码学习 之 embedding层如何自动更新 目录 [阿里DIN] 从论文源码学习 之 embedding层如何自动更新 0x00 摘要 0x01 DIN源码 1.1 问题 1 ...
- [数据结构1.2-线性表] 动态数组ArrayList(.NET源码学习)
[数据结构1.2-线性表] 动态数组ArrayList(.NET源码学习) 在C#中,存在常见的九种集合类型:动态数组ArrayList.列表List.排序列表SortedList.哈希表HashTa ...
- [算法2-数组与字符串的查找与匹配] (.NET源码学习)
[算法2-数组与字符串的查找与匹配] (.NET源码学习) 关键词:1. 数组查找(算法) 2. 字符串查找(算法) 3. C#中的String(源码) 4. 特性Attribute 与内 ...
随机推荐
- oracle删除超过N天数据脚本
公司内做的项目是工厂内的,一般工厂内数据要求的是实时性,很久之前的数据可以自行删除处理,我们数据库用的oracle,所以就想着写一个脚本来删除,这样的话,脚本不管放在那里使用都可以达到效果 由于服务器 ...
- 在centos7.6上部署前后端分离项目Nginx反向代理vue.js2.6+Tornado5.1.1,使用supervisor统一管理服务
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_102 这一次使用vue.js+tornado的组合来部署前后端分离的web项目,vue.js不用说了,前端当红炸子鸡,泛用性非常广 ...
- 英特尔CPU系列
1.酷睿(Core)系列,主要应用于管理 3D.高级视频和照片编辑,玩复杂游戏,享受高分辨率 4K 显示. 2.奔腾(PenTIum)系列,主要应用于借助功能丰富的处理器,加快便携式 2 合 1 电脑 ...
- 在.NET 6.0中使用不同的托管模型
大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进. 本章是<定制ASP NET 6.0框架系列文章>的第六篇.在本章中,我 ...
- PerfView专题 (第八篇):洞察 C# 内存泄漏之寻找静态变量名和GC模式
一:背景 这篇我们来聊一下 PerfView 在协助 WinDbg 分析 Dump 过程中的两个超实用技巧,可能会帮助我们快速定位最后的问题,主要有如下两块: 洞察内存泄漏中的静态大集合变量名. 验证 ...
- CF600E Lomsat gelral (dfs序+莫队)
题面 题解 看到网上写了很多DSU和线段树合并的题解,笔者第一次做也是用的线段树合并,但在原题赛的时候却怕线段树合并调不出来,于是就用了更好想更好调的莫队. 这里笔者就说说莫队怎么做吧. 我们可以通过 ...
- Crash的数字表格 (莫比乌斯反演)
Crash的数字表格 Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时被a和b ...
- java方法---可变参数
可变参数 在方法的声明中,在指定参数类型后面加一个...(省略号) 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数,任何普通参数必须在它之前声明:
- 图床搭建|chrome插件|操作简单不要钱
为什么需要一个图床 为了写博客 图床:专门用来存放图片,同时允许你把图片对外连接的网上空间. 用markdown格式写作,插入图片需要图片的url地址,然后博客的背景图也是要用url地址. 有段时间, ...
- hadoop项目之求出每年二月的最高气温(Combiner优化)
hadoop项目之求出每年二月的最高气温(Combiner优化) 一.项目结构 一.java实现随机生成日期和气温 package com.shujia.weather; import java.io ...