Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 麻豆va一区二区三区久久浪,欧美一区二区三区视频在线观看 ,免费视频久久看

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          前端工具:常用的Web前端ui框架匯總

          前端工具:常用的Web前端ui框架匯總

          lementui應該是大家用的最多的和最常見最穩定的ui框架,那么除了elementui還有哪些好用的框架呢?

          1.amazeui(妹子 UI) 中國首個開源 HTML5 跨屏前端框架

          Amaze UI 以移動優先(Mobile first)為理念,從小屏逐步擴展到大屏,最終實現所有屏幕適配,適應移動互聯潮流。
          官網地址:
          http://amazeui.shopxo.net/javascript/modal/

          2.WeUI 適配于微信小程序的ui框架

          WeUI 是一套同微信原生視覺體驗一致的基礎樣式庫,由微信官方設計團隊為微信內網頁和微信小程序量身設計,令用戶的使用感知更加統一。
          官網地址:
          https://weui.io/#button_default

          3.MintUI 是基于Vue.js移動組件庫

          // 安裝
          # Vue 1.x
          npm install mint-ui@1 -S
          # Vue 2.0
          npm install mint-ui -S
          
          
          // 引入全部組件
          import Vue from 'vue';
          import Mint from 'mint-ui';
          Vue.use(Mint);
          // 按需引入部分組件
          import { Cell, Checklist } from 'mint-ui';
          Vue.component(Cell.name, Cell);
          Vue.component(Checklist.name, Checklist);

          官網地址:
          http://mint-ui.github.io/docs/#/

          4.LayUI 兼容人類正在使用的全部瀏覽器(IE6/7 除外),可作為 Web 界面速成開發方案。

          基于瀏覽器端原生態模式,面向全層次的前后端開發者,易上手且開源免費的 Web 界面組件庫
          官網地址:
          https://layuion.com/docs/

          5.iviewUI

          基于Vue.js的一個UI框架,主要用PC端,組件比ElementUI更豐富。View Design基于 Vue.js 3 的企業級 UI 組件庫和前端解決方案,
          為數萬開發者服務。
          官網地址:
          https://www.iviewui.com/

          6.Naive UI Vue3+TypeScript組件庫

          Naive UI 是一個 Vue3 的組件庫。全量使用 TypeScript 編寫,和你的 TypeScript 項目無縫銜接。有超過 80 個組件,希望能幫你少寫點代碼。順便一提,它們全都可以 treeshaking。盡力讓它不要太慢。至少 select、tree、transfer、table、cascader 都可以用虛擬列表,整體使用感受還是很好的,全局配置化,減少很多無用代碼。
          官網地址:
          https://www.naiveui.com/zh-CN/os-theme/docs/introduction

          7.Ant Design Pro

          一個由螞蟻金服開源出來的企業級后臺前端UI框架,目前有Vue和React等版本。使用感受:react版本比vue版本好用穩定,vue版本可能是改造的原因,用起來有一些不方便,包括tree的虛擬加載都沒有更新,react版本比較豐富,這個組件推薦配合react使用。
          vue版本官網地址:
          https://2x.antdv.com/components/form-cn/
          react版本官網地址:
          https://ant.design/components/button-cn/

          8.Ionic Native 基于AngularJS框架的Javascript UI框架

          用于移動端開發,學習成本較高,版本好多,選擇的時候需要慎重,各種適配的版本,Ionic 是一個輕量的手機 UI 庫,具有速度快,界面現代化、美觀等特點。為了解決其他一些 UI 庫在手機上運行緩慢的問題。
          官網地址:
          http://www.ionic.wang/native_doc-index.html

          9.Uni-app

          uni-app 是一個使用 Vue.js (opens new window)開發所有前端應用的框架,開發者編寫一套代碼,可發布到iOS、Android、Web(響應式)、以及各種小程序(微信/支付寶/百度/頭條/飛書/QQ/快手/釘釘/淘寶)、快應用等多個平臺,如果要做微信小程序uni-app配合微信開發者文檔還是蠻香的,另一篇文章有具體入門進階介紹。
          官網地址:
          https://uniapp.dcloud.net.cn/

          以上就是今天的分享,希望對大家有幫助哦!

          容摘要:

          • 需求分析
          • 定義 interface
          • 定義 json 文件
          • 定義列表控件的 props
          • 基于 el-table 封裝,實現依賴 json 渲染
          • 實現內置功能:選擇行(單選、多選),格式化、鎖定等。
          • 使用 slot 實現自定義擴展
          • 做個工具維護 json 文件(下篇介紹)

          管理后臺里面,列表是一個常用的功能,UI庫提供了列表組件和分頁組件實現功能。雖然功能強大,也很靈活,只是還不能稱為低代碼,不過沒關系,我們可以寫點代碼讓UI庫變為摸魚神器!

          本篇介紹列表的設計思路和封裝方式。

          需求分析

          如果基于原生HTML來實現顯示數據列表的功能的話,那么需考慮如何創建 table,如何設置css等。
          如果直接使用UI庫的話,那么可以簡單很多,只需要設置各種屬性,然后綁定數據即可。
          以 el-table 為例:

            <el-table
              :data="tableData"
              border
              stripe
              style="width: 100%"
            >
              <el-table-column prop="date" label="Date" width="180" />
              <el-table-column prop="name" label="Name" width="180" />
              <el-table-column prop="address" label="Address" />
            </el-table>
          

          設置好屬性、記錄集合,然后設置列(el-table-column)即可。
          這樣一個列表就搞定了,再加上 el-pagination 分頁組件,編寫一些代碼即可實現分頁的功能。

          如果只是一個列表的話,這種方式沒啥問題,但是管理后臺項目,往往需要n個列表,而每個列表都大同小異,如果要一個一個手擼出來,那就有點麻煩了。

          那么如何解決呢?我們可以參考低代碼,基于 el-talbe 封裝一個列表控件,
          實現依賴 json 動態渲染列表,同時支持自定義擴展。

          定義 interface

          最近開始學習 Typescript,發現了一個現象,如果可以先定義好類型,那么代碼就可以更清晰的展現出來。

          另外 Vue3 的最新文檔,也采用了通過 interface 來介紹API功能的方式,所以我們也可以借鑒一下。

          依據 el-table 的屬性,定義列表控件屬性的 interface。

          Vue3 的 props 有一套約束方式,這個似乎和TS的方式有點沖突,沒想出了更好的方法(option API 和 script setup兩種定義props的方式,都有不足 ),所以只好做兩個 interface,一個用于定義組件的 props ,一個用于取值。

          • IGridPropsComp:定義組件的 props
          /**
           * 列表控件的屬性的描述,基于el-table
           */
          export interface IGridPropsComp {
            /**
             * 模塊ID,number | string
             */
            moduleId: IPropsValidation,
            /**
             * 主鍵字段的名稱 String,對應 row-key
             */
            idName: IPropsValidation,
            /**
             * table的高度, Number
             */
            height: IPropsValidation,
            /**
             * 列(字段)顯示的順序 Array<number|string>
             */
            colOrder: IPropsValidation,
            /**
             * 斑馬紋,Boolean
             */
            stripe: IPropsValidation,
            /**
             * 縱向邊框,Boolean
             */
            border: IPropsValidation,
            /**
             * 列的寬度是否自撐開,Boolean
             */
            fit: IPropsValidation,
            /**
             * 要高亮當前行,Boolean
             */
            highlightCurrentRow: IPropsValidation,
            /**
             * 鎖定的列數 Number,設置到 el-table-column 的 fixed
             */
            fixedIndex: IPropsValidation,
            /**
             * table的列的 IGridItem
             * * id: number | string,
             * * colName: string, 字段名稱
             * * label: string, 列的標簽、標題
             * * width: number, 列的寬度
             * * align: EAlign, 內容對齊方式
             * * headerAlign: EAlign 列標題對齊方式
             */
            itemMeta: IPropsValidation, // 
            /**
             * 記錄選擇的行:IGridSelection
             * * dataId: '', 單選ID number 、string
             * * row: {}, 單選的數據對象 {}
             * * dataIds: [], 多選ID []
             * * rows: [] 多選的數據對象 []
             */
            selection: IPropsValidation, 
              
            /**
             * 綁定的數據 Array, 對應 data
             */
            dataList: IPropsValidation
          
            // 其他擴展屬性
            [propName: string]: IPropsValidation
          
          }
          
          • moduleId:模塊ID,一個模塊菜單只能有一個列表,菜單可以嵌套。
          • itemMeta:列的屬性集合,記錄列表的列的屬性。
          • selection:記錄列表的單選、多選的 row。
          • dataList:顯示的數據,對應 el-table 的 data
          • 其他:對應 el-table 的屬性

          IGridPropsComp 的作用是,約束列表控件需要設置哪些屬性,屬性的具體類型,就無法在這里約束了。

          • IPropsValidation (不知道vue內部有沒有這樣的 interface)
          /**
           * vue 的 props 的驗證的類型約束
           */
          export interface IPropsValidation {
            /**
             * 屬性的類型,比較靈活,可以是 String、Number 等,也可以是數組、class等
             */
            type: Array<any> | any,
            /**
             * 是否必須傳遞屬性
             */
            required?: boolean,
            /**
             * 自定義類型校驗函數(箭頭函數),value:屬性值
             */
            validator?: (value: any)=> boolean,
            /**
             * 默認值,可以是值,也可以是函數(箭頭函數)
             */
            default?: any
          }
          

          取 props 用的 interface

          IGridPropsComp 無法約束屬性的具體類型,所以只好再做一個 interface。

          • IGridProps
          /**
           * 列表控件的屬性的類型,基于el-table
           */
           export interface IGridProps {
            /**
             * 模塊ID,number | string
             */
            moduleId: number | string,
            /**
             * 主鍵字段的名稱 String,對應 row-key
             */
            idName: String,
            /**
             * table的高度, Number
             */
            height: number,
            /**
             * 列(字段)顯示的順序 Array<number|string>
             */
            colOrder: Array<number|string>,
            /**
             * 斑馬紋,Boolean
             */
            stripe: boolean,
            /**
             * 縱向邊框,Boolean
             */
            border: boolean,
            /**
             * 列的寬度是否自撐開,Boolean
             */
            fit: boolean,
            /**
             * 要高亮當前行,Boolean
             */
            highlightCurrentRow: boolean,
            /**
             * 鎖定的列數 Number,設置到 el-table-column 的 fixed
             */
            fixedIndex: number,
            /**
             * table的列的 Object< IGridItem >
             * * id: number | string,
             * * colName: string, 字段名稱
             * * label: string, 列的標簽、標題
             * * width: number, 列的寬度
             * * align: EAlign, 內容對齊方式
             * * headerAlign: EAlign 列標題對齊方式
             */
            itemMeta: {
              [key:string | number]: IGridItem
            }, // 
            /**
             * 選擇行的情況:IGridSelection
             * * dataId: '', 單選ID number 、string
             * * row: {}, 單選的數據對象 {}
             * * dataIds: [], 多選ID []
             * * rows: [] 多選的數據對象 []
             */
            selection: IGridSelection, 
              
            /**
             * 綁定的數據 Array, 對應 data
             */
            dataList: Array<any>
          
            // 其他擴展屬性
            [propName: string]: any
          }
          

          對比一下就會發現,屬性的類型不一樣。因為定義 props 需要使用一套特定的對象格式,而使用 props 的時候需要的是屬性自己的類型。

          理想情況下,應該可以在 script setup 里面,引入外部文件 定義的 interface ,然后設置給組件的 props,但是到目前為止還不支持,只能在( script setup方式的)組件內部定義 props。希望早日支持,支持了就不會這么糾結和痛苦了。

          依據 el-table-column 定義列屬性的 interface。

          • IGridItem:列表里面列的屬性
          /**
           * 列的屬性,基于 el-table-column
           */
          export interface IGridItem {
            /**
             * 字段ID、列ID
             */
            id: number | string,
            /**
             * 字段名稱
             */
            colName: string,
            /**
             * 列的標簽、標題
             */
            label: string,
            /**
             * 列的寬度
             */
            width: number,
            /**
             * 內容對齊方式 EAlign
             */
            align: EAlign,
            /**
             * 列標題對齊方式
             */
            headerAlign: EAlign,
          
            // 其他擴展屬性
            [propName: string]: any
          }
          

          還是需要擴展屬性的,因為這里只是列出來目前需要的屬性,el-table-column 的其他屬性、方法還有很多,而且以后也可能會新增。

          這個屬性不是直接設置給組件的 props,所以不用定義兩套了。

          對齊方式的枚舉

          枚舉可以理解為常量,定義之后可以避免低級錯誤,避免手滑。

          • EAlign
          export const enum EAlign {
            left='left',
            center='center',
            right='right'
          }
          

          選擇記錄的 interface。

          列表可以單選也可以多選,el-table 在默認情況下似乎是二選一,覺得有點不方便,為啥不能都要?

          • 單選:鼠標單一任意一行就是單選;(清空其他已選項)
          • 多選:單擊第一列的(多個)復選框,就是多選;

          這樣用戶就可以愉快的想單選就單選,想多選就多選了。

          • IGridSelection
          /**
           * 列表里選擇的數據
           */
          export interface IGridSelection {
            /**
             * 單選ID number 、string
             */
            dataId: number | string,
            /**
             * 單選的數據對象 {}
             */
            row: any,
            /**
             * 多選ID []
             */
            dataIds: Array<number | string>,
            /**
             * 多選的數據對象 []
             */
            rows: Array<any>
          }
          

          其實我覺得只記錄ID即可,不過既然 el-talble 提供的 row,那么還是都記錄下來吧。

          定義 json 文件

          接口定義好之后,我們可以依據 interface 編寫 json 文件:

          {
            "moduleId": 142,
            "height": 400,
            "idName": "ID",
            "colOrder": [
              90,  100, 101 
            ],
            "stripe": true,
            "border": true,
            "fit": true,
            "highlightCurrentRow": true,
            "highlight-current-row": true,
            "itemMeta": {
              "90": {
                "id": 90,
                "colName": "kind",
                "label": "分類",
                "width": 140,
                "title": "分類",
                "align": "center",
                "header-align": "center"
              },
              "100": {
                "id": 100,
                "colName": "area",
                "label": "多行文本",
                "width": 140,
                "title": "多行文本",
                "align": "center",
                "header-align": "center"
              },
              "101": {
                "id": 101,
                "colName": "text",
                "label": "文本",
                "width": 140,
                "title": "文本",
                "align": "center",
                "header-align": "center"
              } 
            }
          }
          
          
          • 為什么直接設置 json 文件而不是 js 對象呢?
            因為對象會比較長,如果是代碼形式的話,那還不如直接使用UI庫組件來的方便呢。
          • 你可能又會問了,既然直接用 json文件,為啥還要設計 interface 呢?
            當然是為了明確各種類型,interface 可以當做文檔使用,另外封裝UI庫的組件的時候,也可以用到這些 interface。使用列表控件的時候也可以使用這些 interface。

          其實json文件不用手動編寫,而是通過工具來編寫和維護。

          定義列表控件的 props

          封裝組件之前需要先定義一下組件需要的 props:

          • props-grid.ts
          import type { PropType } from 'vue'
          
          import type {
            IGridProps,
            IGridItem,
            IGridSelection
          } from '../types/50-grid'
          
          /**
           * 表單控件需要的屬性propsForm
           */
          export const gridProps: IGridProps={
            /**
             * 模塊ID,number | string
             */
            moduleId: {
              type: Number,
              required: true
            },
            /**
             * 主鍵字段的名稱
             */
            idName: {
              type: String,
              default: 'ID'
            },
            /**
             * 字段顯示的順序
             */
            colOrder: {
              type: Array as PropType<Array<number | string>>,
              default: ()=> []
            },
            /**
             * 鎖定的列數
             */
            fixedIndex: {
              type: Number,
              default: 0
            },
            /**
             * table的列的 meta
             */
            itemMeta: {
              type: Object as PropType<{
                [key:string | number]: IGridItem
              }>
            },
            /**
             * 選擇的情況 IGridSelection
             */
            selection: {
              type: Object as PropType<IGridSelection>,
              default: ()=> {
                return {
                  dataId: '', // 單選ID number 、string
                  row: {}, // 單選的數據對象 {}
                  dataIds: [], // 多選ID []
                  rows: [] // 多選的數據對象 []
                }
              }
            },
            /**
             * 綁定的數據
             */
            dataList: {
              type: Array as PropType<Array<any>>,
              default: ()=> []
            },
            其他略。。。
          }
          
          

          按照 Option API 的方式設置 props 的定義,這樣便于共用屬性的定義(好吧似乎也沒有需要共用的地方,不過我還是喜歡把 props 的定義寫在一個單獨的文件里)。

          封裝列表控件

          定義好 json 、props之后,我們基于 el-table 封裝列表控件:

          • template 模板
            <el-table
              ref="gridRef"
              v-bind="$attrs"
              :data="dataList"
              :height="height"
              :stripe="stripe"
              :border="border"
              :fit="fit"
              :highlight-current-row="highlightCurrentRow"
              :row-key="idName"
              @selection-change="selectionChange"
              @current-change="currentChange"
            >
              <!--多選框,實現多選功能-->
              <el-table-column
                type="selection"
                width="55"
                align="center"
                header-align="center"
                @click="clickCheck"
              >
              </el-table-column>
              <!--依據 json 渲染的字段列表-->
              <el-table-column
                v-for="(id, index) in colOrder"
                :key="'grid_list_' + index + '_' + id"
                v-bind="itemMeta[id]"
                :column-key="'col_' + id"
                :fixed="index < fixedIndex"
                :prop="itemMeta[id].colName"
              >
              </el-table-column>
            </el-table>
          

          設置 type="selection"列,實現多選的功能。
          使用 v-for 的方式,遍歷出動態列。
          設置 :fixed="index < fixedIndex",實現鎖定左面列的功能。

          • js 代碼
            import { defineComponent, ref } from 'vue'
            // 列表控件的屬性 
            import { gridProps } from '../map'
          
            /**
             * 普通列表控件
             */
            export default defineComponent({
              name: 'nf-elp-grid-list',
              inheritAttrs: false,
              props: {
                ...gridProps // 解構共用屬性
              },
              setup (props, ctx) {
                // 獲取 el-table 
                const gridRef=ref(null)
           
                return {
                  gridRef
                }
              }
            })
          

          把 props 的定義放在單獨的 ts文件 里面,組件內部的代碼就可以簡潔很多。

          實現內置功能

          可以按照自己的喜好,設置一些內部功能,比如單選/多選的功能,格式化的功能等。

          • 定義控制函數 controller.ts
          import type { ElTable } from 'element-plus'
          
          // 列表控件的屬性 
          import type { IGridProps } from '../map'
          
          export interface IRow {
           [key: string | number]: any
          }
          
          /**
          * 列表的單選和多選的事件
          * @param props 列表組件的 props
          * @param gridRef el-table 的 $ref
          */
          export default function choiceManage<T extends IGridProps, V extends typeof ElTable>(props: T, gridRef: V) {
           // 是否單選觸發
           let isCurrenting=false
           // 是否多選觸發
           let isMoring=false
          
           // 單選
           const currentChange=(row: IRow)=> {
             if (isMoring) return // 多選代碼觸發
             if (!row) return // 清空
          
             if (gridRef.value) {
               isCurrenting=true
               gridRef.value.clearSelection() // 清空多選
               gridRef.value.toggleRowSelection(row) // 設置復選框
               gridRef.value.setCurrentRow(row) // 設置單選
               // 記錄
               props.selection.dataId=row[props.idName]
               props.selection.dataIds=[ row[props.idName] ]
               props.selection.row=row
               props.selection.rows=[ row ]
          
               isCurrenting=false
             }
           }
          
           // 多選
           const selectionChange=(rows: Array<IRow>)=> {
             if (isCurrenting) return
             // 記錄
             if (typeof props.selection.dataIds==='undefined') {
               props.selection.dataIds=[]
             }
             props.selection.dataIds.length=0 // 清空
             // 設置多選
             rows.forEach((item: IRow)=> {
               if (typeof item !=='undefined' && item !==null) {
                 props.selection.dataIds.push(item[props.idName])
               }
             })
             props.selection.rows=rows
             // 設置單選
             switch (rows.length) {
               case 0:
                 // 清掉單選
                 gridRef.value.setCurrentRow()
                 props.selection.dataId=''
                 props.selection.row={}
                 break
               case 1:
                 isMoring=true
                 // 設置新單選
                 gridRef.value.setCurrentRow(rows[0])
                 isMoring=false
                 props.selection.row=rows[0]
                 props.selection.dataId=rows[0][props.idName]
                 break
               default:
                 // 去掉單選
                 gridRef.value.setCurrentRow()
                 props.selection.row=rows[rows.length - 1]
                 props.selection.dataId=props.selection.row[props.idName]
             }
           }
          
           return {
             currentChange, // 單選
             selectionChange // 多選
           }
          }
          
          • 列表控件的 setup 里調用
          setup (props, ctx) {
            // 獲取 el-table 
            const gridRef=ref<InstanceType<typeof ElTable>>()
          
            // 列表選項的事件
            const {
              currentChange, // 單選
              selectionChange // 多選
            }=choiceManage(props, gridRef)
          
            return {
              selectionChange, // 多選
              currentChange, // 單選
              gridRef // table 的 dom
            }
          }
          

          這里有一個“度”的問題:

          • el-table 完全通過 slot 的方式實現各種功能,這種方法的特點是:非常靈活,可以各種組合;缺點是比較繁瑣。
            而我們需要尋找到一個適合的“折中點”,顯然這個折中點很難統一,這也是過渡封裝帶來的問題。
          • 不能遇到新的需求,就增加內部功能,這樣就陷入了《人月神話》里說的“焦油坑”,進去了就很難出來。

          這也是低代碼被詬病的因素。

          支持擴展

          那么如何找到這個折中點呢?可以按照 “開閉原則”,按照不同的需求,設置多個不同功能的列表控件,使用 slot 實現擴展功能。或者干脆改為直接使用 el-table 的方式。(要靈活,不要一刀切)

          比如簡單需求,不需要擴展功能的情況,設置一個基礎列表控件:nf-grid。
          需要擴展列的情況,設置一個可以擴展的列表控件:nf-grid-slot。

          如果需要多表頭、樹形數據等需求,可以設置一個新的列表控件,不過需要先想想,是不是直接用 el-table 更方便。

          要不要新增一個控件,不要慣性思維,而要多方面全局考慮。

          這里介紹一下支持 slot 擴展的列表控件的封裝方式:

            <el-table
              ref="gridDom"
              v-bind="$attrs"
              size="mini"
              style="width: 100%"
              :data="dataList"
              :height="height"
              :stripe="stripe"
              :border="border"
              :fit="fit"
              :highlight-current-row="highlightCurrentRow"
              :current-row-key="idName"
              :row-key="idName"
              @selection-change="selectionChange"
              @current-change="currentChange"
            >
              <!--顯示選擇框-->
              <el-table-column
                type="selection"
                width="55">
              </el-table-column>
              <!--顯示字段列表-->
              <template
                v-for="(id, index) in colOrder"
                :key="'grid_list_' + index + '_' + id"
              >
                <!--檢查插槽里是否包含 字段名,作為判斷依據-->
                <!--不帶插槽的列-->
                <el-table-column
                  v-if="!(slotsKey.includes(itemMeta[id].colName))"
                  :fixed="index < fixedIndex"
                  v-bind="itemMeta[id]"
                  :prop="itemMeta[id].colName"
                  :min-width="50"
                >
                </el-table-column>
                <!--帶插槽的列-->
                <el-table-column  v-else
                  v-bind="itemMeta[id]"
                >
                  <template #default="scope">
                    <!--讀取外部插槽內容,并且傳遞 scope -->
                    <slot :name="itemMeta[id].colName" v-bind="scope"></slot>
                  </template>
                </el-table-column>
              </template>
            </el-table>
          

          模板部分,首先判斷一下是否需要使用 slot,做一個分支。
          需要使用 slot 的列,通過 <template #default="scope"> 設置 slot。

          • 代碼部分
            import { defineComponent, ref } from 'vue'
            // 表單控件的屬性 
            import { gridProps } from '../map'
            import choiceManage from './controller'
          
            export default defineComponent({
              name: 'nf-elp-grid-slot',
              inheritAttrs: false,
              props: {
                ...gridProps
              },
              setup (props, ctx) {
                // 記錄插槽 的 名稱
                const slots=ctx.slots
                const slotsKey=Object.keys(slots)
           
                // 列表選項的事件
                const {
                  currentChange, // 單選
                  selectionChange // 多選
                }=choiceManage(props, gridRef)
          
                return {
                  slotsKey,
                  selectionChange, // 多選
                  currentChange // 單選
                }
              }
            })
          

          一般列表的使用方法

          封裝之后,使用起來就很方便了,引入 json文件,設置屬性即可。

          • template
            <nf-grid
              v-bind="gridMeta"
              :dataList="dataList"
              :selection="selection"
              size="small"
            />
          

          是不是簡單多了。

          • 代碼部分
            import { defineComponent, reactive } from 'vue'
            import { nfGrid, createDataList } from '../../../../lib-elp/main'
            import _gridMeta from '../../grid/grid.json'
            import _formMeta from '../../form/form.json'
           
            export default defineComponent({
              name: 'nf-elp-grid-page',
              components: {  nfGrid  },
              setup(props) {
                // 不需要動態改變的話,可以不使用 reactive。
                const gridMeta=reactive(_gridMeta)
                // 設置選擇的行
                const selection=reactive({
                  dataId: '', // 單選ID number 、string
                  row: {}, // 單選的數據對象 {}
                  dataIds: [], // 多選ID []
                  rows: [] // 多選的數據對象 []
                })
                // 設置記錄集。
                const dataList=reactive(_dataList)
          
                return {
                  dataList,
                  selection,
                  gridMeta
                }
              }
            })
          

          控件可以做成全局組件的形式。

          • 看看效果

          擴展列表的使用方法

          首先還是依據 json 渲染列表,然后根據需要設置插槽即可,設置插槽后會替換默認的列。

          • template
            可以使用 slot 自定義擴展列 <br>
            <!--表單控件-->
            <nf-grid
              v-grid-drag="gridMeta"
              v-bind="gridMeta"
              :dataList="dataList"
              :selection="selection"
              size="small"
            >
              <!--普通字段,用字段名作為插槽的名稱-->
              <template #text="scope">
                <div style="display: flex; align-items: center">
                  <el-icon><timer /></el-icon>
                  <span style="margin-left: 10px">擴展:{{ scope.row.text }}</span>
                </div>
              </template>
              <!--普通字段-->
              <template #week="scope">
                <span style="margin-left: 10px">{{ scope.row.week.replace('-w','年 第') + '周' }}</span>
              </template>
              <!--操作按鈕-->
              <template #option="scope">
                <el-button size="small" @click="handleEdit(scope.$index, scope.row)">修改</el-button>
                <el-button
                  size="small"
                  type="danger"
                  @click="handleDelete(scope.$index, scope.row)">刪除</el-button>
              </template>
            </nf-grid>
          

          通過 slot 擴展列,可以按照 Table-column 的匿名插槽的方式進行設置。
          列的先后順序還是由 colOrder 控制,和插槽的先后順序無關。

          • 代碼部分
            import { defineComponent, reactive } from 'vue'
            // 使用 圖標
            import { Timer } from '@element-plus/icons-vue'
            import { nfGridSlot, createDataList } from '../../../../lib-elp/main'
            import _gridMeta from '../../grid/grid.json'
            import _formMeta from '../../form/form.json'
          
            import { EAlign } from '../../../../lib/types/enum'
            import type { IGridSelection, IGridItem } from '../../../../lib/types/50-grid'
           
            export default defineComponent({
              name: 'nf-elp-grid-slot-page',
              components: {
                Timer,
                nfGrid: nfGridSlot
              },
              props: {
                moduleID: { // 模塊ID
                  type: [Number, String],
                  default: 1 
                }
              },
              setup(props) {
                const gridMeta=reactive(_gridMeta)
          
                // 設置列的先后順序和是否顯示
                gridMeta.colOrder=[90, 100, 101, 102, 105, 113, 115, 116, 120,121,150, 2000]
          
                // 設置一個操作按鈕列
                const optionCol: IGridItem={
                  id: 2000,
                  colName: "option",
                  label: "操作",
                  width: 180,
                  fixed: EAlign.right,
                  align: EAlign.center, // 使用枚舉
                  headerAlign: EAlign.center
                }
          
                gridMeta.itemMeta['2000']=optionCol // 設置操作列,也可以直接在json文件里設置。
                const dataList=reactive(_dataList)
          
                const handleEdit=(index: number, row: any)=> {
                  console.log(index, row)
                }
                const handleDelete=(index: number, row: any)=> {
                  console.log(index, row)
                }
          
                return {
                  handleEdit,
                  handleDelete,
                  dataList,
                  gridMeta
                }
              }
            })
          

          使用字段名稱作為插槽的名稱,可以把任意字段變成插槽的形式。

          如果要添加操作按鈕這類的列,可以給 itemMeta 添加對應的列屬性。

          • 看看效果:

          管理 json

          其實,前面介紹的那些大家可能都會想到,也許早就實踐過了,然后發現雖然看著挺好,但是其實沒有解決根本問題!只是把 template 里的問題轉移到 json 里面。

          雖然不需要設置模板,但是需要設置 json,還不是一樣,有啥本質區別嗎?

          其實不一樣的,管理 json 的難度明顯比管理模板要簡單得多。

          比如我們可以做一個維護 json 的小工具:

          • 首先從數據庫文檔生成基礎的 json(毛坯房);
          • 然后使用可視化+拖拽的方式設置格子細節(精裝修)。

          這樣就可以很方便的維護 json 了。具體實現方式,將在下一篇再介紹。

          源碼

          nf-ui-controller-UI庫的二次封裝的共用 JavaScript 函數: 對UI庫做二次封裝的純JavaScript函數,支持更多的UI庫的時候便于復用。

          nf-ui-elementPlus-基于 element-plus 的二次開發: 封裝UI庫(elementPlus),實現更簡潔的使用方式。

          動端web開發框架、類庫和UI組件簡介,有需要的收藏一波。

          react-native

          一個基于React的創建原生APP的框架

          html5-boilerplate

          一個用來構建快速、強大、可適配的webapp的前端模板

          ionic

          領先的HTML5移動開發框架和SDK,利用你所熟知的web技術構建難以置信的移動應用,是AngularJS最好的朋友。

          weui

          由微信官方設計團隊為微信Web開發量身打造的框架,包含移動web應用開發中有用的組件和模塊

          hammer.js

          實現多點觸控的javascript庫

          weex

          阿里推出的跨平臺的移動端開發框架,具有輕量級、可擴展和高性能的特點

          fastclick

          一個消除移動端瀏覽器上的點擊事件的300ms的延遲

          zepto

          Zepto.jsisaminimalistJavaScriptlibraryformodernbrowsers,withajQuery-compatibleAPI

          vux

          基于Vue和Weui的移動端框架

          wepy

          騰訊團隊推出的小程序組件化開發框架

          NativeScript

          NativeScript是一個利用JavaScript等WEB技術創建原生APP的框架

          Framework7

          功能強大的創建iOS&AndroidAPP的HTML框架

          mui

          最接近原生APP體驗的高性能框架

          ratchet

          用簡單的HTML,CSS,和JavaScript組件創建移動應用

          react-native-elements

          ReactNativeUI組件庫

          mint-ui

          基于vue.js的移動端UI框架

          amazeui

          移動端優先的開源HTML5跨屏前端框架,俗稱妹子UI

          jquery-mobile

          jQuery移動開發框架

          Mars

          騰訊移動Web前端知識庫

          interact.js

          JavaScriptdraganddrop,resizingandmulti-touchgestureswithinertiaandsnappingformodernbrowsers(andalsoIE8+)

          vant

          有贊開發的基于Vue.js2.0的UI組件庫

          OnsenUI

          用來構建混合移動端APP的HTML5UI框架

          muse-ui

          基于Vue2.0和MaterialDesigin的UI組件庫

          SUI-Mobile

          SUIMobile(MSUI)是由阿里巴巴國際UED前端出品的一個手機端的UI庫,輕量精美。更多信息請參考官網

          ant-design-mobile

          一個可配置的移動端UI框架

          TouchSwipe-Jquery-Plugin

          TouchSwipeisajqueryplugintobeusedwithjQueryontouchinputdevicessuchasiPad,iPhoneetc.

          jquery-weui

          創建微信混合app的UI庫

          jquery-ui-touch-punch

          AduckpunchforaddingtoucheventstojQueryUI

          device.js

          Device.jsmakesiteasytowriteconditionalCSS_and/or_JavaScriptbasedondeviceoperatingsystem(iOS,Android,Blackberry,Windows,FirefoxOS,MeeGo),orientation(Portraitvs.Landscape),andtype(Tabletvs.Mobile).

          react-native-ui-kitten

          可定制和可重用的react-native組件包

          iview-weapp

          一套高質量的微信小程序UI組件庫

          vonic

          基于Vue.js和ionic組件的SPAUI框架

          brick

          UIWebComponentsforModernWebApps

          app

          App.js是一個用來創建移動webapp的輕量級JavaScriptUI框架,可以表現得像原生APP而又不犧牲性能和優雅

          Lungo.js

          一個給開發者提供的設計、構建、分享跨設備應用的框架

          AlloyFinger

          騰訊Web前端團隊推出的輕量級的多點觸控手勢庫

          FooTable

          jQueryplugintomakeHTMLtablesresponsive

          vue-ydui

          一個基于Vue2.x的移動端組件庫

          wechat-h5-boilerplate

          為騰訊微信優化的H5動效模板,幫助你快速構建全屏滾動型H5頁面

          slip

          通過滑動和拖動手勢操作列表的UI庫

          mobi.css

          一個關注于移動端的輕量級的、靈活的css框架,

          vue-touch

          Vue.js的Hammer.js包裝器

          QuoJS

          針對移動設備的微型JavaScript庫

          pressure

          :point_down::boom:JavaScriptlibraryforhandlingbothForceTouchand3DTouchontheweb

          junior

          一個創建類似原生APP的html5應用的前端框架

          vum

          為手機webapp打造的基于Vue.js構建的UI框架

          mobiscroll

          ThecustomizablemobileUIlibraryfortouchdeviceslikesmartphonesandtablets

          zingtouch

          一個JavaScript觸摸手勢檢測庫

          montage

          montagejs是一個優雅的、開源的HTML5框架。它提供了模塊化組件,雙向數據綁定,以及更多功能

          pushy

          Pushyisaresponsiveoff-canvasnavigationmenuusingCSStransforms&transitions

          GMU

          基于zepto的ui組件庫,適用于移動端

          flex.css

          flex.cssis是一個聲明式的布局框架,能夠兼容多個MVVM框架和瀏覽器

          mobilebone

          單頁切換骨架。適用于移動webAPP,Hybrid混合APP,Phonegap開發,無兼容要求單頁PC應用等

          jquery.pep.js

          Pep,alightweightpluginforkineticdragonmobile/desktop

          Cloudajs

          CloudaFramework-一個針對移動WebApp的實時JavaScriptRIA框架

          jo

          Jo(0.5.0)是一個輕量級的(~16K)創建HTML5應用的外殼。可以和PhoneGap,Chrome,Safari,Opera,FireFox,iOS,Android,BlackBerry10,Tizen,&WindowsPhone8+一起工作

          touchui

          高質量移動端UI框架

          iosselect

          一個簡潔好看的模仿ios的webapp下拉菜單

          mand-mobile

          面向金融場景的Vue移動端UI組件庫,豐富、靈活、實用,快速搭建優質的金融類產品

          tabris-js

          tabris.js-用JavaScript開發原生應用

          aui

          移動端UI快速布局解決方案(APICloudUI框架)

          vue-carbon

          基于vue開發的materialdesignui庫

          cordova-plugin-ibeacon

          AniBeaconpluginforPhonegap/Cordova3.xandupwards.SupportsbothiOSandAndroid(contributionsarewelcome)

          touch.code.baidu.com

          TouchOfficalSite

          bindingx

          阿里團隊推出的weex和ReactNative上富交互問題的一種解決方案

          jQuery-Touch-Events

          AcollectionofmobileeventpluginsforjQuery.

          TinyNav.js

          Responsivenavigationpluginthatweighsjust443bytes

          Jingle

          JingleUI是一個基于html5、css3開發輕量級的移動webapp框架,提供一些基本交互方式,幫助您更方便的開發移動應用。

          light7

          一個輕量級的易用的移動端UI框架

          framework7-vue

          基于Framework7和Vue構建iOS和Android應用

          ydui

          一只注重審美,且性能高效的移動端&微信UI

          slip.js

          移動端跟隨手指滑動組件,零依賴。

          wepayui

          微信支付場景化組件,wepayui源碼

          BlendUI

          BlendUI是Clouda+中的重要組成部分,他能讓webapp的用戶界面體驗和交互能和Native媲美

          toucher

          面向移動端的手勢類庫

          touchjs

          一個移動端手勢檢測庫

          thumbs.js

          Addtouchsupporttoyourbrowserwiththumbs.js-asmall,transparent,andsyntax-lesslibrary.

          JMUI

          移動Web開發UI組件庫

          JM

          面向Mobile的極致JavaScript庫

          react-ui

          為React打造的一套ionic風格的可復用UI組件庫

          Zoomage.js

          Zoomage.js-一個通過手勢縮放圖片的庫

          touchSlider

          TouchSliderjQueryPlugin


          主站蜘蛛池模板: 国产精久久一区二区三区| 精品国产亚洲一区二区三区在线观看| 色系一区二区三区四区五区 | 久久国产三级无码一区二区| 香蕉视频一区二区三区| 国产伦一区二区三区高清| 亚洲老妈激情一区二区三区| 中文字幕乱码一区二区免费| 无码人妻精品一区二区三区66| 亚洲一区二区三区高清视频| 久久精品成人一区二区三区 | 久久99国产精品一区二区| 国产精品熟女一区二区| 久久一区二区三区精华液使用方法| 日韩美女视频一区| 国内国外日产一区二区| 波多野结衣久久一区二区| 视频在线一区二区| 99精品国产高清一区二区| 国产日韩视频一区| 无码精品人妻一区二区三区漫画| 国产精品视频分类一区| 亚洲国产一区二区三区| 亚洲一区二区免费视频| 一区二区三区四区无限乱码| 色欲精品国产一区二区三区AV| 日韩精品福利视频一区二区三区| 中文字幕久久亚洲一区| 影院成人区精品一区二区婷婷丽春院影视 | 日产一区日产2区| 精品一区二区三人妻视频| 免费无码一区二区三区蜜桃| 亚洲欧美日韩国产精品一区 | 亚洲AV无码一区二区三区牛牛| 极品少妇伦理一区二区| 国产韩国精品一区二区三区久久| 一区国严二区亚洲三区| 日韩欧美一区二区三区免费观看| 国产凹凸在线一区二区| 国产一区精品视频| 伊人色综合网一区二区三区|