Ruoyi字典源碼學習

来源:https://www.cnblogs.com/allworldg/archive/2022/10/07/ruoyi-dict-learn.html
-Advertisement-
Play Games

ruoyi項目在低於3.7.0的版本中,前端字典功能實現比較簡單,每個index.vue頁面都請求dict的api,獲取數據再加工顯示即可。3.7.0之後的版本使用了混入,所以複雜了一些。 ...


此文章屬於ruoyi項目實戰系列

使用目的

  1. 什麼是字典數據:具體的值(0,1,"Y","N"),對應具體的業務邏輯("男","女","是","否")。
  2. 字典數據不應該只寫死在代碼中,還應存入資料庫,通過管理系統來增刪改查。

源碼分析

ruoyi項目在低於3.7.0的版本中,前端字典功能實現比較簡單,每個index.vue頁面都請求dict的api,獲取數據再加工顯示即可。3.7.0之後的版本使用了混入,所以複雜了一些。

分析

  1. 入口:查看全局入口文件main.jsDictData.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 = 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(....)里的方法個人認為是為了拓展性,因為我全局查找也沒有看到任何地方用到。)

  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合併,並且將合併結果賦值給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里的一些調用函數源碼

  1. 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對象,方便後續調用。

  2. 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  
        })  
    }	
    
  3. 具體頁面應用
    例如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]} 通過上文的代碼全局混入得到
    }
    

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • MySQL約束 基本介紹 約束用於確保資料庫的數據滿足特定的商業規則 在mysql中,約束包括:not null,unique,primary key,foreign key 和check 5種 1.primary key(主鍵) 欄位名 欄位類型 primary key 用於唯一地標識表行的數據, ...
  • 一、什麼是關係型和非關係型資料庫,兩者都包含那種資料庫 1、關係型資料庫 關係型資料庫是指採用了關係模型來組織數據的資料庫。簡單來說,關係模式就是二維表格模型。 常見關係型資料庫管理系統(ORDBMS): Oracle、MySql、Microsoft SQL Server、 SQLite、Postg ...
  • 一、CentOS 7.9 安裝 redis-6.2.0 1 下載地址:https://download.redis.io/releases/redis-6.2.0.tar.gz 2 安裝gcc來進行編譯 Redis 由 C語言編寫,所以需要系統中有 gcc 編譯器 使用 gcc --version  ...
  • 一、CentOS 7.9 安裝 mongodb5.0.13 1 下載地址:https://www.mongodb.com/try/download/community2 2 安裝前的準備 # 操作系統內核版本 uname -a # 操作系統發行版本 cat /etc/redhat-release 3 ...
  • 一、CentOS 7.9 安裝 mysql-5.7.35 1 下載地址:https://downloads.mysql.com/archives/community/ 2 mysql-5.7.35 安裝包上傳到linux伺服器 使用Xftp 或者 wget 在伺服器上下載 # 推薦使用wget yu ...
  • 多表查詢02 4.表複製 自我複製數據(蠕蟲複製) 有時,為了對某個sql語句進行效率測試,我們需要海量數據時,可以用此法為表創建海量數據 -- 為了對某個sql語句進行效率測試,我們需要海量數據時,可以用此法為表創建海量數據 CREATE TABLE my_tab01( id INT , `nam ...
  • 多表查詢 前面講過的基本查詢都是對一張表進行查詢,但在實際的開發中遠遠不夠。 下麵使用表emp,dept,salgrade進行多表查詢 emp: dept: salgrade: 1.前置-mysql表查詢-加強 1.1查詢增強 使用where子句 如何查找1992.1.1後入職的員工 在mysql中 ...
  • 前文回顧 實現一個簡單的Database1(譯文) 實現一個簡單的Database2(譯文) 實現一個簡單的Database3(譯文) 譯註:cstsck在github維護了一個簡單的、類似SQLite的資料庫實現,通過這個簡單的項目,可以很好的理解資料庫是如何運行的。本文是第四篇,主要是使用rsp ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...