<thead id="kdfuf"><font id="kdfuf"></font></thead>
<samp id="kdfuf"></samp>
    <nav id="kdfuf"><strong id="kdfuf"></strong></nav>
      中文字幕无码一区二区三区在线,久久精品人人做人人爽,国产一级内射无挡观看,十八禁在线黄色网站,日韩欧美国产另类久久久精品 ,少妇人妻偷人精品一区二区,久久午夜视频,亚洲春色AⅤ无码专区

      封裝element-ui表格

      2020-7-30    seo達(dá)人

      表格需求

      一般管理系統(tǒng)對(duì)表格會(huì)有以下需求


      可以分頁(yè)(需要有分頁(yè)條)

      可以多選(表格帶復(fù)選框)

      頂部需要加一些操作按鈕(新增,刪除等等)

      表格每行行尾有操作按鈕

      表格行可以編輯

      如下圖為一個(gè)示例表格




      如果我們直接使用element-ui提供的組件的話,那么開發(fā)一個(gè)這樣的表格就需要使用到以下內(nèi)容


      需要使用表格的插槽功能,開發(fā)每一行的按鈕

      需要通過(guò)樣式調(diào)整頂部按鈕,表格,分頁(yè)條的布局樣式

      需要監(jiān)聽分頁(yè)的事件然后去刷新表格數(shù)據(jù)

      頂部按鈕或操作按鈕如果需要獲取表格數(shù)據(jù),需要調(diào)用表格提供的api

      對(duì)于有行編輯的需求,還需要通過(guò)插槽去渲染行編輯的內(nèi)容,同時(shí)要控制行編輯的開關(guān)

      不僅僅開發(fā)表格比較麻煩,而且還要考慮團(tuán)隊(duì)協(xié)作,如果每個(gè)人實(shí)現(xiàn)表格的方式存在差別,那么可能后期的維護(hù)成本也會(huì)變得很高。那怎么辦呢?


      項(xiàng)目安裝

      安裝插件

      在使用element-ui的項(xiàng)目中,可以通過(guò)以下命令進(jìn)行安裝


      npm install vue-elementui-table -S

      在項(xiàng)目中使用

      在main.js中添加以下代碼


      import ZjTable from 'vue-element-table'


      Vue.use(ZjTable)

      然后即可像下文中的使用方式進(jìn)行使用


      表格配置

      為了滿足團(tuán)隊(duì)快速開發(fā)的需要,小編對(duì)上面提出來(lái)的需求進(jìn)行了封裝,然后使用的時(shí)候,開發(fā)人員只需要配置一些JSON便可以完成以上功能的開發(fā)。


      基礎(chǔ)配置

      一個(gè)基礎(chǔ)的表格包含了數(shù)據(jù)和列信息,那么如何用封裝的表格去配置呢?


      <template>

       <zj-table

         :columns="columns"

         :data="data"

         :pagination="false"

       />

      </template>

      <script>

      export default {

       data() {

         return {

           // 表格的列信息, 數(shù)組每一項(xiàng)代表一個(gè)字段,可以使用element 列屬性的所有屬性,以下僅為示例

           columns: Object.freeze([

             {

               // 表頭顯示的文字

               label: '姓名',

               // 對(duì)應(yīng)數(shù)據(jù)里面的字段

               prop: 'name'

             },

             {

               label: '性別',

               prop: 'sex',

               // 格式化表格,與element-ui 的表格屬性相同

               formatter(row, column, cellValue) {

                 return cellValue === 1 ? '男' : '女'

               }

             },

             {

               label: '年齡',

               prop: 'age'

             }

           ]),

           data: [

             {

               name: '子君',

               sex: 1,

               age: 18

             }

           ]

         }

       }

      }

      </script>

      通過(guò)上面的配置,就可以完成一個(gè)基礎(chǔ)表格的開發(fā),完整代碼見 https://github.com/snowzijun/vue-element-table/blob/master/example/views/demo/base.vue,效果如下圖所示




      表格默認(rèn)會(huì)顯示復(fù)選框,也可以通過(guò)配置selectable屬性來(lái)關(guān)閉掉


      添加分頁(yè)

      簡(jiǎn)單的表格用封裝之后的或未封裝的開發(fā)工作量區(qū)別并不大,我們繼續(xù)為表格添加上分頁(yè)


      <template>

         <!--

         current-page.sync 表示頁(yè)碼, 添加上 .sync 在頁(yè)碼發(fā)生變化時(shí)自動(dòng)同步頁(yè)碼

         page-size.sync 每頁(yè)條數(shù)

         total  總條數(shù)

         height="auto" 配置height:auto, 表格高度會(huì)根據(jù)內(nèi)容自動(dòng)調(diào)整,如果不指定,表格將保持充滿父容器,同時(shí)表頭會(huì)固定,不跟隨滾動(dòng)條滾動(dòng)

         @page-change 無(wú)論pageSize currentPage 哪一個(gè)變化,都會(huì)觸發(fā)這個(gè)事件

       -->

       <zj-table

         v-loading="loading"

         :columns="columns"

         :data="data"

         :current-page.sync="currentPage"

         :page-size.sync="pageSize"

         :total="total"

         height="auto"

         @page-change="$_handlePageChange"

       />

      </template>

      <script>

      export default {

       data() {

         return {

           columns: Object.freeze([

             // 列字段與上例一樣,此處省略

           ]),

           data: [],

           // 當(dāng)前頁(yè)碼

           currentPage: 1,

           // 每頁(yè)條數(shù)

           pageSize: 10,

           // 總條數(shù)

           total: 0,

           // 是否顯示loading

           loading: false

         }

       },

       created() {

         this.loadData()

       },

       methods: {

         // 加載表格數(shù)據(jù)

         loadData() {

           this.loading = true

           setTimeout(() => {

             // 假設(shè)總條數(shù)是40條

             this.total = 40

             const { currentPage, pageSize } = this

             // 模擬數(shù)據(jù)請(qǐng)求獲取數(shù)據(jù)

             this.data = new Array(pageSize).fill({}).map((item, index) => {

               return {

                 name: `子君${currentPage + (index + 1) * 10}`,

                 sex: Math.random() > 0.5 ? 1 : 0,

                 age: Math.floor(Math.random() * 100)

               }

             })

             this.loading = false

           }, 1000)

         },

         $_handlePageChange() {

           // 因?yàn)樯厦嬖O(shè)置屬性指定了.sync,所以這兩個(gè)屬性會(huì)自動(dòng)變化

           console.log(this.pageSize, this.currentPage)

           // 分頁(yè)發(fā)生變化,重新請(qǐng)求數(shù)據(jù)

           this.loadData()

         }

       }

      }

      </script>

      完整代碼請(qǐng)參考 https://github.com/snowzijun/vue-element-table/blob/master/example/views/demo/pagination.vue


      通過(guò)封裝,表格將自帶分頁(yè)功能,通過(guò)上面代碼,實(shí)現(xiàn)效果如下所示,是不是變得簡(jiǎn)單了一些。接下來(lái)我們繼續(xù)給表格添加按鈕




      添加頂部按鈕

      表格上面可能會(huì)有新增,刪除等等按鈕,怎么辦呢,接下來(lái)我們繼續(xù)通過(guò)配置去添加按鈕


      <template>

       <zj-table

         :buttons="buttons"

       />

      </template>

      <script>

      export default {

       data() {

         return {

           buttons: Object.freeze([

             {

               // id 必須有而且是在當(dāng)前按鈕數(shù)組里面是唯一的

               id: 'add',

               text: '新增',

               type: 'primary',

               icon: 'el-icon-circle-plus',

               click: this.$_handleAdd

             },

             {

               id: 'delete',

               text: '刪除',

               // rows 是表格選中的行,如果沒有選中行,則禁用刪除按鈕, disabled可以是一個(gè)boolean值或者函數(shù)

               disabled: rows => !rows.length,

               click: this.$_handleRemove

             },

             {

               id: 'auth',

               text: '這個(gè)按鈕根據(jù)權(quán)限顯示',

               // 可以通過(guò)返回 true/false來(lái)控制按鈕是否顯示

               before: (/** rows */) => {

                 return true

               }

             },

             // 可以配置下拉按鈕哦

             {

               id: 'dropdown',

               text: '下拉按鈕',

               children: [

                 {

                   id: 'moveUp',

                   text: '上移',

                   icon: 'el-icon-arrow-up',

                   click: () => {

                     console.log('上移')

                   }

                 },

                 {

                   id: 'moveDown',

                   text: '下移',

                   icon: 'el-icon-arrow-down',

                   disabled: rows => !rows.length,

                   click: () => {

                     console.log('下移')

                   }

                 }

               ]

             }

           ])

         }

       },

       created() {},

       methods: {

         // 新增

         $_handleAdd() {

           this.$alert('點(diǎn)擊了新增按鈕')

         },

         // 頂部按鈕會(huì)自動(dòng)將表格所選的行傳出來(lái)

         $_handleRemove(rows) {

           const ids = rows.map(({ id }) => id)

           this.$alert(`要?jiǎng)h除的行id為${ids.join(',')}`)

         },

         // 關(guān)注作者公眾號(hào)

         $_handleFollowAuthor() {}

       }

      }

      </script>

      表格頂部可以添加普通的按鈕,也可以添加下拉按鈕,同時(shí)還可以通過(guò)before來(lái)配置按鈕是否顯示,disabled來(lái)配置按鈕是否禁用,上面完整代碼見 https://github.com/snowzijun/vue-element-table/blob/master/example/views/demo/button.vue


      通過(guò)上面的代碼就可以配置出下面的表格,是不是很簡(jiǎn)單呢?




      表格頂部可以有按鈕,行尾也是可以添加按鈕的,一起來(lái)看看


      行操作按鈕

      一般我們會(huì)將一些單行操作的按鈕放在行尾,比如編輯,下載等按鈕,那如何給行尾配置按鈕呢?


      <template>

       <zj-table

         :columns="columns"

       />

      </template>

      <script>

      export default {

       data() {

         return {

           columns: Object.freeze([

             {

               // 可以指定列的寬度,與element-ui原生用法一致

               width: 220,

               label: '姓名',

               prop: 'name'

             },

             // 行編輯按鈕,在表格末尾出現(xiàn),自動(dòng)鎖定右側(cè)

             {

               width: 180,

               label: '操作',

               // 通過(guò) actions 指定行尾按鈕

               actions: [

                 {

                   id: 'follow',

                   text: '關(guān)注作者',

                   click: this.$_handleFollowAuthor

                 },

                 {

                   id: 'edit',

                   text: '編輯',

                   // 可以通過(guò)before控制按鈕是否顯示,比如下面年齡四十歲的才會(huì)顯示編輯按鈕

                   before(row) {

                     return row.age < 40

                   },

                   click: this.$_handleEdit

                 },

                 {

                   id: 'delete',

                   text: '刪除',

                   icon: 'el-icon-delete',

                   disabled(row) {

                     return row.sex === 0

                   },

                   // 為了拿到this,這里需要用箭頭函數(shù)

                   click: () => {

                     this.$alert('女生被禁止刪除了')

                   }

                 }

               ]

             }

           ])

         }

       },

       methods: {

         // 關(guān)注作者公眾號(hào)

         $_handleFollowAuthor() {

                 console.log('微信搜索【前端有的玩】,這是對(duì)小編最大的支持')

         },

         /**

          * row 這一行的數(shù)據(jù)

          */

         $_handleEdit(row, column) {

           this.$alert(`點(diǎn)擊了姓名為【${row.name}】的行上的按鈕`)

         }

       }

      }

      </script>

      行操作按鈕會(huì)被凍結(jié)到表格最右側(cè),不會(huì)跟隨滾動(dòng)條滾動(dòng)而滾動(dòng),上面完整代碼見, https://github.com/snowzijun/vue-element-table/blob/master/example/views/demo/button.vue


      通過(guò)上面的代碼就可以完成以下效果




      最后再來(lái)一起看看行編輯


      行編輯

      比如上例,我希望點(diǎn)擊行尾的編輯按鈕的時(shí)候,可以直接在行上面編輯用戶的姓名與性別,如何配置呢?


      <template>

       <zj-table

         ref="table"

         :columns="columns"

         :data="data"

       />

      </template>

      <script>

      export default {

       data() {

         return {

           columns: Object.freeze([

             {

               label: '姓名',

               prop: 'name',

               editable: true,

               field: {

                 componentType: 'input',

                 rules: [

                   {

                     required: true,

                     message: '請(qǐng)輸入姓名'

                   }

                 ]

               }

             },

             {

               label: '性別',

               prop: 'sex',

               // 格式化表格,與element-ui 的表格屬性相同

               formatter(row, column, cellValue) {

                 return cellValue === '1' ? '男' : '女'

               },

               editable: true,

               field: {

                 componentType: 'select',

                 options: [

                   {

                     label: '男',

                     value: '1'

                   },

                   {

                     label: '女',

                     value: '0'

                   }

                 ]

               }

             },

             {

               label: '年齡',

               prop: 'age',

               editable: true,

               field: {

                 componentType: 'number'

               }

             },

             {

               label: '操作',

               actions: [

                 {

                   id: 'edit',

                   text: '編輯',

                   // 如果當(dāng)前行啟用了編輯,則不顯示編輯按鈕

                   before: row => {

                     return !this.editIds.includes(row.id)

                   },

                   click: this.$_handleEdit

                 },

                 {

                   id: 'save',

                   text: '保存',

                   // 如果當(dāng)前行啟用了編輯,則顯示保存按鈕

                   before: row => {

                     return this.editIds.includes(row.id)

                   },

                   click: this.$_handleSave

                 }

               ]

             }

           ]),

           data: [

             {

               // 行編輯必須指定rowKey字段,默認(rèn)是id,如果修改為其他字段,需要給表格指定row-key="字段名"

               id: '0',

               name: '子君',

               sex: '1',

               age: 18

             },

             {

               // 行編輯必須指定rowKey字段,默認(rèn)是id,如果修改為其他字段,需要給表格指定row-key="字段名"

               id: '1',

               name: '子君1',

               sex: '0',

               age: 18

             }

           ],

           editIds: []

         }

       },

       methods: {

         $_handleEdit(row) {

           // 通過(guò)調(diào)用 startEditRow 可以開啟行編輯

           this.$refs.table.startEditRow(row.id)

           // 記錄開啟了行編輯的id

           this.editIds.push(row.id)

         },

         $_handleSave(row) {

           // 點(diǎn)擊保存的時(shí)候,通過(guò)endEditRow 結(jié)束行編輯

           this.$refs.table.endEditRow(row.id, (valid, result, oldRow) => {

             // 如果有表單驗(yàn)證,則valid會(huì)返回是否驗(yàn)證成功

             if (valid) {

               console.log('修改之后的數(shù)據(jù)', result)

               console.log('原始數(shù)據(jù)', oldRow)

               const index = this.editIds.findIndex(item => item === row.id)

               this.editIds.splice(index, 1)

             } else {

               // 如果校驗(yàn)失敗,則返回校驗(yàn)的第一個(gè)輸入框的異常信息

               console.log(result)

               this.$message.error(result.message)

             }

           })

         }

       }

      }

      </script>

      不需要使用插槽就可以完成行編輯,是不是很開心。上述完整代碼見 https://github.com/snowzijun/vue-element-table/blob/master/example/views/demo/row-edit.vue


      效果如下圖所示:




      其他功能

      除了上面的功能之外,表格還可以配置其他許多功能,比如


      可以指定字段為鏈接列,需要給列配置link屬性

      可以通過(guò)插槽自定義頂部按鈕,行操作按鈕,行字段等

      可以在按鈕區(qū)域右側(cè)通過(guò)插槽配置其他內(nèi)容

      其他等等

      表格開發(fā)說(shuō)明

      通過(guò)上面的代碼示例,我們已經(jīng)知道了封裝之后的表格可以完成哪些事情,接下來(lái)一起來(lái)看看表格是如何實(shí)現(xiàn)的。完整代碼見 https://github.com/snowzijun/vue-element-table/tree/master/src/components/zj-table


      表格布局

      整個(gè)表格是通過(guò)JSX來(lái)封裝的,因?yàn)镴SX使用起來(lái)更加靈活。對(duì)于我們封裝的表格,我們從豎向可以分為三部分,分別是頂部按鈕區(qū),中間表格區(qū),底部分頁(yè)區(qū),如何去實(shí)現(xiàn)三個(gè)區(qū)域的布局呢,核心代碼如下


      render(h) {

         // 按鈕區(qū)域

         const toolbar = this.$_renderToolbar(h)

         // 表格區(qū)域

         const table = this.$_renderTable(h)

         // 分頁(yè)區(qū)域

         const page = this.$_renderPage(h)


         return (

           <div class="zj-table" style={{ height: this.tableContainerHeight }}>

             {toolbar}

             {table}

             {page}

           </div>

         )

       }

      通過(guò)三個(gè)render函數(shù)分別渲染對(duì)應(yīng)區(qū)域,然后將三個(gè)區(qū)域組合在一起。


      渲染表格列

      通過(guò)前文的講解,我們可以將表格的列分為以下幾種


      常規(guī)列

      行編輯列

      操作按鈕列

      插槽列

      鏈接列(文檔后續(xù)完善)

      嵌套列(文檔后續(xù)完善)

         $_renderColumns(h, columns) {

           // 整體是否排序

           let sortable = this.sortable ? 'custom' : false

           return columns

             .filter(column => {

               const { hidden } = column

               if (hidden !== undefined) {

                 if (typeof hidden === 'function') {

                   return hidden({

                     columns,

                     column

                   })

                 }

                 return hidden

               }

               return true

             })

             .map(column => {

               const {

                 useSlot = false,

                 // 如果存在操作按鈕,則actions為非空數(shù)組

                 actions = [],

                 // 是否可編輯列, 對(duì)于可編輯列需要?jiǎng)討B(tài)啟用編輯

                 editable = false,

                 // 是否有嵌套列

                 nests,

                 // 是否可點(diǎn)擊

                 link = false

               } = column

               let newSortable = sortable

               if (column.sortable !== undefined) {

                 newSortable = column.sortable ? 'custom' : false

               }

               column = {

                 ...column,

                 sortable: newSortable

               }

               if (nests && nests.length) {

                 // 使用嵌套列

                 return this.$_renderNestColumn(h, column)

               } else if (editable) {

                 // 使用編輯列

                 return this.$_renderEditColumn(h, column)

               } else if (useSlot) {

                 // 使用插槽列

                 return this.$_renderSlotColumn(h, column)

               } else if (actions && actions.length > 0) {

                 // 使用操作列

                 column.sortable = false

                 return this.$_renderActionColumn(h, column)

               } else if (link) {

                 // 使用鏈接列

                 return this.$_renderLinkColumn(h, column)

               } else {

                 // 使用默認(rèn)列

                 return this.$_renderDefaultColumn(h, column)

               }

             })

         },

      行編輯列

      當(dāng)前表格行編輯支持input,select,datepicker,TimeSelect,InputNumber等組件,具體渲染代碼如下所示


      // 編輯單元格

         $_renderEditCell(h, field) {

           const components = {

             input: Input,

             select: ZjSelect,

             date: DatePicker,

             time: TimeSelect,

             number: InputNumber

           }

           const componentType = field.componentType

           const component = components[componentType]

           if (component) {

             return this.$_renderField(h, field, component)

           } else if (componentType === 'custom') {

             // 如果自定義,可以通過(guò)component指定組件

             return this.$_renderField(h, field, field.component)

           }

           return this.$_renderField(h, field, Input)

         },

         $_renderField(h, field, Component) {

           // 編輯行的id字段

           const { rowId, events = {}, nativeEvents = {} } = field


           const getEvents = events => {

             const newEvents = {}

             Object.keys(events).forEach(key => {

               const event = events[key]

               newEvents[key] = (...rest) => {

                 const args = [

                   ...rest,

                   {

                     rowId,

                     row: this.editRowsData[rowId],

                     value: this.editRowsData[rowId][field.prop]

                   }

                 ]

                 return event(...args)

               }

             })

             return newEvents

           }

           // 事件改寫

           const newEvents = getEvents(events)

           const newNativeEvents = getEvents(nativeEvents)

           return (

             <Component

               size="small"

               on={newEvents}

               nativeOn={newNativeEvents}

               v-model={this.editRowsData[rowId][field.prop]}

               {...{

                 attrs: field,

                 props: field

               }}

             />

           )

         }

      藍(lán)藍(lán)設(shè)計(jì)www.tuitetiyu.cn )是一家專注而深入的界面設(shè)計(jì)公司,為期望卓越的國(guó)內(nèi)外企業(yè)提供卓越的UI界面設(shè)計(jì)、BS界面設(shè)計(jì) 、 cs界面設(shè)計(jì) 、 ipad界面設(shè)計(jì) 、 包裝設(shè)計(jì) 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計(jì)、 網(wǎng)站建設(shè) 平面設(shè)計(jì)服務(wù)


      日歷

      鏈接

      個(gè)人資料

      存檔

      主站蜘蛛池模板: 欧美日韩色欲色欲色欲XXXX| 亚洲熟妇在线视频观看| 久久99狠狠色精品一区| 国产日韩欧美综合| 国产品无码一区二区三区在线辣椒| 91久久香蕉囯产熟女线看麻豆 | 日日碰狠狠添天天爽五月婷| 亚洲av最新在线网址| 果冻传媒AV毛片无码蜜桃| 国产精品福利成人午夜精品视频 | 欧美人禽杂交18禁网站| 色偷偷av男人的天堂| 安吉县| 亚洲阿V天堂网2019无码| 日韩精品中文字幕无码专区| 国产欧美亚洲综合第一区| 亚洲精品揄拍自拍首页一| 国产午夜福利三级| 国产91麻豆免费观看| 国产尤物精品不卡| 免费 国产 无码久久久| 亚洲人成图片小说网站| 毛片内射久久久一区| 日韩不遮挡毛片免费| 国产又黄又大又粗视频| 欧美亚洲综合久久偷偷人人| 国产精品女人在线观看| 一本大道东京热无码| 国产精品天天在线看。| 亚洲va久久久噜噜噜久久天堂 | 亚洲人成精品久久久久 | 少妇性l交大片| 国产麻豆剧传媒精品国产av| 蜜臀久久99精品久久久久久| 国产精品va在线观看老妇女 | 一本大道久东京无一二三区| 内射人妻无码色AV| 丁香婷婷在线观看| 国产精品久久这里只有精品 | 国内精品视频一区二区| 国产剧情演绎系列丝袜高跟|