此文章屬于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="https://www.cnblogs.com/allworldg/archive/2022/10/07/dict.value" /> </el-select> export default{ dicts:['sys_job_group','sys_job_status'], //dict:{'sys_job_group':[data1,data2],'sys_job_status':[data1,data2]} 通過上文的代碼全域混入得到 }
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/511004.html
標籤:其他
上一篇:疫情背景下,如何選擇管理軟體?
