El-Table的二次封裝

記錄一下在對el-tabel進行簡單封裝并實現行內編輯,單元格合并等功能


? ? <el-table

? ? ? id="iTable"

? ? ? v-loading.iTable="options.loading"http://是否添加表格loading加載動畫

? ? ? :data="list"http://數據列

? ? ? :stripe="options.stripe"http:// 是否添加表格loading加載動畫

? ? ? ref="multipleTable"http:// 是否支持列表項選中功能

? ? ? border

? ? ? :default-sort="{order: 'descending'}"

? ? ? @selection-change="handleSelectionChange"

? ? ? @filter-change="filterchange"

? ? ? :header-cell-style="rowClass"http://多級表頭控制樣式

? ? ? :header-cell-class-name="headerStyle"http://表頭樣式

? ? ? :row-class-name="tableRowClassName"http://行樣式

? ? ? :span-method="objectSpanMethod"http://合并單元格

? ? ? :height="height"http://高度

? ? ? size="small"

? ? ? :row-style="{height:'30px'}"

? ? ? :cell-style="{padding:'0px'}"

? ? ? @row-click="rowclick"http://行點擊事件

? ? ? @row-dblclick="dblclick"http://雙擊

? ? ? @row-contextmenu="contmenuclick"http://右鍵

? ? ? @cell-click="cellclick"http://單元格事件

? ? >

? ? ? <template v-if="columns.show">//是否為多級,如果為多級,另一個組件循環(代碼放下面)

? ? ? ? <my-column v-for="(item,index) incolumns.data" :key="index" :col="item">

? ? ? <template v-else>

? ? ? ? <template v-for="(column, index) incolumns">

? ? ? ? ? ? :prop="column.prop"

? ? ? ? ? ? :key="column.label"

? ? ? ? ? ? :label="column.label"

? ? ? ? ? ? :align="column.align"

? ? ? ? ? ? :min-width="column.width"

? ? ? ? ? ? :fixed="column.fixed"

? ? ? ? ? ? :filters="column.filters"

? ? ? ? ? ? sortable

? ? ? ? ? >

? ? ? ? ? ? <template slot-scope="scope">

? ? ? ? ? ? ? <template v-if="!column.render">

? ? ? ? ? ? ? ? <template v-if="column.formatter">


? ? ? ? ? ? ? ? ? <span v-if="scope.row.isEdit&&column.isEdit&&!column.isSelect">

? ? ? ? ? ? ? ? ? ? <el-input size="mini" placeholder="請輸入內容" @click.stop.native="" v-model="scope.row[column.prop]">


? ? ? ? ? ? ? ? ? <span v-else-if="scope.row.isEdit&&column.isEdit&&column.isSelect">

? ? ? ? ? ? ? ? ? ? <el-select v-model="scope.row[column.prop]" placeholder="請輸入">

? ? ? ? ? ? ? ? ? ? ? ? v-for="item in column.SelectObj"

? ? ? ? ? ? ? ? ? ? ? ? :key="item.value"

? ? ? ? ? ? ? ? ? ? ? ? :label="item.label"

? ? ? ? ? ? ? ? ? ? ? ? :value="item.value">


? ? ? ? ? ? ? ? ? <span v-else-if="scope.row.isEdit&&column.isEdit&&column.isDate">

? ? ? ? ? ? ? ? ? ? ? v-model="scope.row[column.prop]"

? ? ? ? ? ? ? ? ? ? ? type="datetime"

? ? ? ? ? ? ? ? ? ? ? placeholder="Select date and time"

? ? ? ? ? ? ? ? ? ? ? default-time="12:00:00">


? ? ? ? ? ? ? ? ? <span v-else="!scope.row.isEdit" :style="column.style!=null||''?column.style:''" v-html="column.formatter(scope.row, column)">

? ? ? ? ? ? ? ? <template v-else>


? ? ? ? ? ? ? ? ? <span v-if="scope.row.isEdit&&column.isEdit&&!column.isSelect&&!column.isDate">

? ? ? ? ? ? ? ? ? ? <el-input size="mini" placeholder="請輸入內容" @click.stop.native="" v-model="scope.row[column.prop]">


? ? ? ? ? ? ? ? ? <span v-else-if="scope.row.isEdit&&column.isEdit&&column.isSelect">

? ? ? ? ? ? ? ? ? ? <el-select v-model="scope.row[column.prop]" placeholder="請輸入">

? ? ? ? ? ? ? ? ? ? ? ? v-for="item in column.SelectObj"

? ? ? ? ? ? ? ? ? ? ? ? :key="item.value"

? ? ? ? ? ? ? ? ? ? ? ? :label="item.label"

? ? ? ? ? ? ? ? ? ? ? ? :value="item.value">


? ? ? ? ? ? ? ? ? <span v-else-if="scope.row.isEdit&&column.isEdit&&column.isDate">

? ? ? ? ? ? ? ? ? ? ? v-model="scope.row[column.prop]"

? ? ? ? ? ? ? ? ? ? ? type="date"

? ? ? ? ? ? ? ? ? ? ? placeholder="Pick a day"

? ? ? ? ? ? ? ? ? ? >


? ? ? ? ? ? ? ? ? <span v-else="!scope.row.isEdit" :style="column.style!=null||''?column.style:''">{{scope.row[column.prop]}}

? ? ? ? ? ? ? <template v-else>

? ? ? ? ? ? ? ? ? :column="column"

? ? ? ? ? ? ? ? ? :row="scope.row"

? ? ? ? ? ? ? ? ? :render="column.render"

? ? ? ? ? ? ? ? ? :index="index"

? ? ? ? ? ? ? ? >

? ? ? ? ref="fixedColumn"

? ? ? ? label="操作"

? ? ? ? align="center"

? ? ? ? :width="operates.width"

? ? ? ? :fixed="operates.fixed"

? ? ? ? v-if="operates.list.filter(_x=>_x.show=== true).length > 0"

? ? ? >

? ? ? ? <template slot-scope="scope">

? ? ? ? ? <div class="operate-group">

? ? ? ? ? ? ? v-if="!scope.row.isEdit"

? ? ? ? ? ? ? type="primary"

? ? ? ? ? ? ? size="mini"

? ? ? ? ? ? ? icon="el-icon-edit"

? ? ? ? ? ? ? plain

round

? ? ? ? ? ? ? @click.stop="EditButtonEvent(scope.$index, scope.row)">編輯

? ? ? ? ? ? ? v-if="!scope.row.isEdit"

? ? ? ? ? ? ? size="mini"

? ? ? ? ? ? ? type="danger"

? ? ? ? ? ? ? icon="el-icon-delete"

? ? ? ? ? ? ? plain

round

? ? ? ? ? ? ? @click.stop="DeleteButtonEvent(scope.$index, scope.row)">刪除

? ? ? ? ? ? ? v-if="scope.row.isEdit"

? ? ? ? ? ? ? size="mini"

? ? ? ? ? ? ? type="info"

? ? ? ? ? ? ? icon="el-icon-refresh-right"

? ? ? ? ? ? ? plain

round

? ? ? ? ? ? ? @click.stop="CancelButtonEvent(scope.$index, scope.row)">取消

? ? ? ? ? ? ? v-if="scope.row.isEdit"

? ? ? ? ? ? ? size="mini"

? ? ? ? ? ? ? type="success"

? ? ? ? ? ? ? icon="el-icon-refresh"

? ? ? ? ? ? ? plain

round

? ? ? ? ? ? ? @click.stop="SaveButtonEvent(scope.$index, scope.row)">保存
































? ? <div class="pagination" v-show="pageShow">

? ? ? ? @size-change="handleSizeChange"

? ? ? ? @current-change="handleIndexChange"

? ? ? ? :page-size="pageSize"

? ? ? ? :page-sizes="[5,10,20,30,50,100]"

? ? ? ? :current-page="pageIndex"

? ? ? ? layout="total,sizes, prev, pager, next,jumper"

? ? ? ? :total="total"

? ? ? >


import MyColumnfrom "./MyColumn";

export default {

props: {

// 數據列表

? ? list: {

type: Array,

? ? ? default: []

},

? ? //表格高度

? ? height: {

type: Number,

? ? ? default:400

? ? },

? ? // 需要展示的列 === prop:列數據對應的屬性,label:列名,align:對齊方式,width:列寬

? ? columns: {

type: [Array, Object],

? ? ? default: []

},

? ? // 總數

? ? total: {

type: Number,

? ? ? default:0

? ? },

? ? // 每頁顯示的數量

? ? pageSize: {

type: Number,

? ? ? default:10

? ? },

? ? // 操作按鈕組 === label: 文本,type :類型(primary / success / warning / danger / info / text),

// show:是否顯示,icon:按鈕圖標,plain:是否樸素按鈕,disabled:是否禁用,method:回調方法

? ? operates: {},

? ? // table 表格的控制參數

? ? options: {

type: Object,

? ? ? default: {

// 是否為斑馬紋 table

? ? ? ? stripe:false,

? ? ? ? // 是否要高亮當前行

? ? ? ? highlightCurrentRow:false

? ? ? }

},

? ? //需要合并的數據源

? ? mergeData:{

type: [Array,Object],

? ? ? default: ()=>({

data:[],//要合并的數據源

? ? ? ? columnIndex:[],//要合并的列的索引

? ? ? ? columnName:[],//要合并的列的名稱

? ? ? }),

? ? },

? ? //需要表示狀態行的標識

? ? rowSign:{

type:[Array,Object],

? ? ? default:()=>({

index:[],//比較字段在對象中的索引

? ? ? ? type:'',//判斷是什么操作(狀態值、正負值、區間值比)

? ? ? ? data:[],//需要比較的值、以及返回表格類樣式

? ? ? })

},

? ? //是否需要分頁部分

? ? pageShow:{

type:Boolean,

? ? ? default:true

? ? }

},

? //組件

? components: {

MyColumn,

? ? expandDom: {

functional:true,

? ? ? props: {

row: Object,

? ? ? ? render: Function,

? ? ? ? index: Number,

? ? ? ? column: {

type: Object,

? ? ? ? ? default:null

? ? ? ? },

? ? ? },

? ? ? render:(h, ctx) =>{

const params = {

row: ctx.props.row,

? ? ? ? ? index: ctx.props.index,

? ? ? ? ? size: ctx.props.size,

? ? ? ? ? round: ctx.props.round,

? ? ? ? ? circle: ctx.props.circle,

? ? ? ? ? plain: ctx.props.plain,

? ? ? ? ? show: ctx.props.show

? ? ? ? };

? ? ? ? if (ctx.props.column) params.column = ctx.props.column;

? ? ? ? //實現下拉框

? ? ? ? if(ctx.props.row.isEdit&&ctx.props.column.isSelect)

{

return h('el-select',{

props:{

value:ctx.props.row.state

? ? ? ? ? ? },

? ? ? ? ? ? on: {

'change':(event) => {

ctx.props.row.state=event;

? ? ? ? ? ? ? }

},

? ? ? ? ? },[ctx.props.column.SelectObj.map((val) => {// 下拉框里的內容,optionList下拉框數據

? ? ? ? ? ? ? return h('el-option', {

props: {

value: val.value,

? ? ? ? ? ? ? ? ? label: val.label

? ? ? ? ? ? ? ? }

})

})

]);

? ? ? ? }

//實現輸入框

? ? ? ? if(ctx.props.column.isEdit&&!ctx.props.column.isSelect)

{

debugger;

? ? ? ? ? return h('input',{

style:{

height:'28px !important',

? ? ? ? ? ? ? 'border-radius':'4px !important',

? ? ? ? ? ? ? border:'1px solid #DCDFE6',

? ? ? ? ? ? },

? ? ? ? ? ? domProps: {

value:params.row.state

? ? ? ? ? ? },

? ? ? ? ? ? props:{

value:params.row.state

? ? ? ? ? ? },

? ? ? ? ? ? on: {

click(event){

event.stopPropagation();

? ? ? ? ? ? ? },

? ? ? ? ? ? ? input(event) {

params.row.state=event.target.value;

? ? ? ? ? ? ? }

}

})

}

return ctx.props.render(h, params);

? ? ? }

}

},

? // 數據

? data() {

return {

position:0,

? ? ? rowSpanArr: [],

? ? ? pageIndex:1,

? ? ? multipleSelection:[],

? ? ? rowInfo: [],//選中行數據

? ? };

? },

? created(){

this.getRowSpan();

? },

? mounted() {},

? computed: {},

? methods: {

//切換每頁顯示的條數

? ? handleSizeChange(size) {

this.pageIndex =1;

? ? ? this.$emit("handleSizeChange", size);

? ? },

? ? // 切換頁碼

? ? handleIndexChange(index) {

this.$emit("handleIndexChange", index);

? ? ? this.pageIndex = index;

? ? },

? ? // 多行選中

? ? handleSelectionChange(val) {

this.multipleSelection = val;

? ? ? this.$emit("handleSelectionChange", val);

? ? },

? ? //table行樣式設置

? ? tableRowClassName({ row, rowIndex }) {

switch (this.rowSign.type) {

case 'state':

for(let i=0;i

{

if(Object.values(row)[this.rowSign.index]===this.rowSign.data[i].Id)

return this.rowSign.data[i].className;

? ? ? ? ? }

break;

? ? ? ? case 'bool':

if(Object.values(row)[this.rowSign.index[0]]>0)

return 'success-row';

? ? ? ? ? else if(Object.values(row)[this.rowSign.index[0]]<0)

return 'warning-row';

break;

? ? ? ? case 'section':

let num=Object.values(row)[this.rowSign.index[0]];

? ? ? ? ? for(let i=0;i

{

if(num>=this.rowSign.data[i].Number1&&num<=this.rowSign.data[i].Number2)

return this.rowSign.data[i].className;

? ? ? ? ? }

break;

? ? ? ? default:

break;

? ? ? }

return "";

? ? },

? ? //合并單元格

? ? objectSpanMethod({ row, column, rowIndex, columnIndex }) {

if(this.mergeData.columnIndex.length>0)

{

for(let i=0;i

{

if (columnIndex ===this.mergeData.columnIndex[i]) {

const _row =this.rowSpanArr['rowSpanArr'+i][rowIndex];

? ? ? ? ? ? const _col = _row >0 ?1 :0;

? ? ? ? ? ? return {

rowspan: _row,

? ? ? ? ? ? ? colspan: _col

}

}

}

}

},

? ? // 獲取合并的數組

? ? getRowSpan() {

let that=this;

? ? ? this.rowSpanArr = {};

? ? ? let data_=that.mergeData.data;

? ? ? for(let i=0;i

{

let name=that.mergeData.columnName[i];

? ? ? ? that.mergeData.data.forEach((item, index) => {

if (index===0) {

that.rowSpanArr['rowSpanArr'+i] =[];

? ? ? ? ? ? that.rowSpanArr['rowSpanArr'+i].push(1);

? ? ? ? ? ? that.position =0;

? ? ? ? ? }else {

if (data_[index][name]===data_[index -1][name]) {

that.rowSpanArr['rowSpanArr'+i][that.position] +=1; //項目名稱相同,合并到同一個數組中

? ? ? ? ? ? ? that.rowSpanArr['rowSpanArr'+i].push(0);

? ? ? ? ? ? ? data_[index][name] = data_[index -1][name];

? ? ? ? ? ? }else {

that.rowSpanArr['rowSpanArr'+i].push(1);

? ? ? ? ? ? ? that.position = index;

? ? ? ? ? ? }

}

});

? ? ? }

},

? ? //篩選方法

? ? filterchange(value) {

this.$emit("filterchange", value);

? ? ? return value;

? ? },

? ? //table單擊事件

? ? rowclick(row, col, event) {

this.$emit("rowclick", row, col, event);

? ? },

? ? //雙擊事件

? ? dblclick(val) {

this.$emit("dblclick", val);

? ? },

? ? //右鍵事件

? ? contmenuclick(val) {

this.$emit("contmenuclick", val);

? ? },

? ? //單元格點擊事件

? ? cellclick(row, col, cell, event) {

this.$emit("cellclick", row, col, cell, event);

? ? },

? ? rowClass({ row, rowIndex}){

return "background:rgba(236,240,245,0.4)";

? ? },

? ? headerStyle ({row, column, rowIndex, columnIndex}) {

if(row&&row[0].children)

{

return 'speHeader';

? ? ? }

},

? ? //編輯按鈕事件

? ? EditButtonEvent(index,row)

{

this.$emit("EditButtonEvent", index, row);

? ? },

? ? //刪除按鈕事件

? ? DeleteButtonEvent(index,row)

{

this.$emit("DeleteButtonEvent", index, row);

? ? },

? ? //取消按鈕事件

? ? CancelButtonEvent(index,row)

{

this.$emit("CancelButtonEvent", index, row);

? ? },

? ? //保存按鈕事件

? ? SaveButtonEvent(index,row)

{

this.$emit("SaveButtonEvent", index, row);

? ? }

},

? watch:{

mergeData:{

handler(newVal,oldVal){

this.getRowSpan();

? ? ? },

? ? ? deep:true,

? ? ? immediate:true

? ? },

? }

};

.el-table .warning-row {

background:#fd9165;

}

.el-table .success-row {

background:#94f987;

}

.el-table .danger-row {

background:#f9400b;

}

.el-table .primary-row {

background:#abb7f9;

}

.speHeader{

color:blue

}

.el-input__inner{

height:28px !important;;

}

? ? :prop="col.prop"

? ? :label="col.label"

? ? :min-width="col.width"

? ? :fixed="col.fixed"

? ? align="center"

? ? :filters="col.filters"

? >

? ? <template slot-scope="scope">

? ? ? <template v-if="!col.render">

? ? ? ? <template v-if="col.formatter">

? ? ? ? ? <span v-if="scope.row.isEdit&&col.isEdit&&!col.isSelect">

? ? ? ? ? ? <el-input size="mini" placeholder="請輸入內容" @click.stop.native="" v-model="scope.row[col.prop]">

? ? ? ? ? <span v-else-if="scope.row.isEdit&&col.isSelect">

? ? ? ? ? ? <el-select v-model="scope.row[col.prop]" placeholder="請輸入">

? ? ? ? ? ? ? ? v-for="item incol.SelectObj"

? ? ? ? ? ? ? ? :key="item.value"

? ? ? ? ? ? ? ? :label="item.label"

? ? ? ? ? ? ? ? :value="item.value">

? ? ? ? ? <span v-else="!scope.row.isEdit" :style="col.style!=null||''?col.style:''" v-html="col.formatter(scope.row,col)">

? ? ? ? <template v-else>

? ? ? ? ? <span v-if="scope.row.isEdit&&col.isEdit&&!col.isSelect">

? ? ? ? ? ? <el-input size="mini" placeholder="請輸入內容" @click.stop.native="" v-model="scope.row[col.prop]">

? ? ? ? ? <span v-else-if="scope.row.isEdit&&col.isEdit&&col.isSelect">

? ? ? ? ? ? <el-select v-model="scope.row[col.prop]" placeholder="請輸入">

? ? ? ? ? ? ? ? v-for="item incol.SelectObj"

? ? ? ? ? ? ? ? :key="item.value"

? ? ? ? ? ? ? ? :label="item.label"

? ? ? ? ? ? ? ? :value="item.value">

? ? ? ? ? <span v-else="!scope.row.isEdit" :style="col.style!=null||''?col.style:''">{{scope.row[col.prop]}}

? ? ? <template v-else>

? ? ? ? ? :column="col"

? ? ? ? ? :row="scope.row"

? ? ? ? ? :render="col.render"

? ? ? ? ? :index="index">

? ? <template v-if="col.children">

? ? ? ? v-for="(item, index) incol.children"

? ? ? ? :key="index"

? ? ? ? :col="item"

? ? ? >

? ? export default {

name:"MyColumn",

? ? ? props: {

col: {

type: Object

}

},

? ? ? methods:{

myclass(){

return 'MyHeader'

? ? ? ? },

? ? ? }

}

<style scoped>

? .el-table thead tr:nth-child(1) {

color:blue !important;

? }

</style>

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380