使用vue自定義指令合併iview表格單元格,html
咱們在開發過程當中發現iview表格組件,官網只提供了合併表頭的demo,並無合併表格中的單元格。vue
ivew表頭分組:https://www.iviewui.com/components/table#BTFZexpress
效果圖以下:app
具體實現思路,經過vue自定義屬性來操做dom,達到咱們想要的效果:iview
代碼以下: demo.vue 表格頁面dom
<template> <div class="demo"><Table :columns="columns1" :data="data1" border ></Table> <!-- <input v-focus='666' />--> </div> </template> <script> export default { name: 'demo', /* // 說明:我在寫這個demo的時候發現 render 函數中 使用指令時 使用局部指令 沒有效果,使用全家指令有效果 //使用指令操做 dom directives: { focus: { // 指令的定義 bind: function(el, bind){ console.dir(el); console.log(el, bind, 'bind'); }, inserted: function (el, bind) { //el.focus() console.dir(el); console.log(el, bind, 'dom元素'); } } }, */ data () { return { columns1: [ { title: 'Name', key: 'name', // align: 'center', render: (h, params)=>{ return h('div', { style: { color: 'green', textAlign: 'center', }, // 自定義指令。注意,你沒法對 `binding` 中的 `oldValue` // 賦值,由於 Vue 已經自動爲你進行了同步。 directives: [ { name: 'cell', arg: 'colSpan', value: 2, //合併列數 //value: '2' //expression: '1 + 1', //modifiers: { //bar: true //} },{ name: 'rmcell', arg: 'colSpan', value: 2, } ], }, params.row.name); } }, { title: '演示合併列', key: '' }, { title: 'Age', key: 'age' }, { title: 'Address', key: 'address' }, { title: '愛好', key: 'hobby', className: 'no-hover', //加在 td 上 render: (h, params)=>{ let dir = null; //第一個tr 元素 中的 td 合併,其餘tr 多出的 td刪除 if(params.index === 0){ dir = [ { name: 'cell', arg: 'rowSpan', //合併類型 value: this.data1.length, //合併行數 //value: '2' //expression: '1 + 1', //modifiers: { //bar: true //} } ]; }else{ dir = [ { name: 'rmcell', arg: 'rowSpan', // value: '', //value: '2' //expression: '1 + 1', //modifiers: { //bar: true //} } ]; } return h('span', { style: { color: 'red' }, // 自定義指令。注意,你沒法對 `binding` 中的 `oldValue` // 賦值,由於 Vue 已經自動爲你進行了同步。 directives: dir, }, params.row.hobby); } }, ], data1: [ { name: 'John Brown', age: 18, address: 'New York No. 1 Lake Park', date: '2016-10-03', hobby: '編碼', }, { name: 'Jim Green', age: 24, address: 'London No. 1 Lake Park', date: '2016-10-01', hobby: '編碼', }, { name: 'Joe Black', age: 30, address: 'Sydney No. 1 Lake Park', date: '2016-10-02', hobby: '編碼', }, { name: 'Jon Snow', age: 26, address: 'Ottawa No. 2 Lake Park', date: '2016-10-04', hobby: '編碼', } ] } }, } </script> <style scoped> .demo>>> div.ivu-table-wrapper tr:hover td.no-hover { background: #fff; } </style>
html結構:ide
在main.js裏註冊全局指令(或你把指令抽離出去最後引入main.js便可 經過 import './directives'; //全局的指令 你的指令文件 ):函數
/** * // 註冊一個全局自定義指令 `v-cell` 動態指令 * /動態內容 rowSpan 合併行 * colSpan 合併列 * 詳見:https://cn.vuejs.org/v2/guide/custom-directive.html * render 函數中 動態內容 傳遞參數 給 arg * { name: 'my-custom-directive', arg: 'foo', //動態 rowSpan或colSpan value: '2', expression: '1 + 1', modifiers: { bar: true } } 詳見:https://cn.vuejs.org/v2/guide/render-function.html */ Vue.directive('cell', { // bind:只調用一次,指令第一次綁定到元素時調用。在這裏能夠進行一次性的初始化設置。 bind: function(el, binding){ console.dir(el); console.log(el, binding, '指令綁定'); }, // 當被綁定的元素插入到 DOM 中時…… inserted: function (el, binding) { console.dir(el); console.log(el, binding, '指令插入'); //找到td 元素 添加 更改 合併 rowSpan 或 colSpan el.parentNode.parentNode[binding.arg] = binding.value; console.dir(el.parentNode.parentNode.rowSpan); } }); /** * rmcell 指令移除 表格單元格 * /動態內容 rowSpan 合併行 * colSpan 合併列 * 當動態內容爲 rowSpan 移除的是當前元素 * 爲 colSpan 移除的是緊跟其後的 td元素 * * */ Vue.directive('rmcell', { // bind:只調用一次,指令第一次綁定到元素時調用。在這裏能夠進行一次性的初始化設置。 bind: function(el, binding){ console.dir(el); console.log(el, binding, '指令綁定'); }, // 當被綁定的元素插入到 DOM 中時…… inserted: function (el, binding) { console.dir(el.parentNode.parentNode); console.log(el, binding, '移除指令插入'); //找到td 元素 移除 if(binding.arg === 'rowSpan'){ el.parentNode.parentNode.remove(); }else { let parent = null; //合併n列 刪除 n-1 次 單元格 的 下一個元素 for(let i = 0; i < binding.value - 1; i++){ el.parentNode.parentNode.nextSibling.remove(); console.log('執行次數'); } } } });
代碼中用到了動態指令:ui
詳見:https://cn.vuejs.org/v2/guide/custom-directive.htmlthis
render函數中使用指令:
詳見:https://cn.vuejs.org/v2/guide/render-function.html