本文實例講述了Vue.js實現可排序的表格組件功能。分享給大家供大家參考,具體如下:
我們基于 Vue.js 實現一個可根據某列進行排序的表格組件。
一個表格包含表頭和數據兩部分內容。因此,我們定義兩個數組,columns 表示表頭信息,在 <thread> 中渲染,并可在此指定某一列是否需要排序;data 表示數據。
html:
<div id="app" v-cloak> <v-table :data="data" :columns="columns"></v-table> <button @click="add">新增</button></div>
把父組件中定義的 data 與 columns 傳入 v-table 組件。
js:
Vue.component('vTable', { props: { //表頭列名稱 columns: { type: Array, default: function () { return []; } }, //數據 data: { type: Array, default: function () { return []; } } }, //為了不影響原始數據,這里定義了相應的需要操作的數據對象 data: function () { return { currentColumns: [], currentData: [] } }, //render 實現方式 render: function (createElement) { var that = this; /** * 創建列樣式與表頭 */ var ths = [];//<th> 標簽數組 var cols = [];//<cols> 標簽數組 this.currentColumns.forEach(function (col, index) { if (col.width) {//創建列樣式 cols.push(createElement('col', { style: { width: col.width } })) } if (col.sortable) { ths.push(createElement('th', [ createElement('span', col.title), //升序 createElement('a', { class: { on: col.sortType === 'asc' }, on: { click: function () { that.sortByAsc(index) } } }, '↑'), //降序 createElement('a', { class: { on: col.sortType === 'desc' }, on: { click: function () { that.sortByDesc(index); } } }, '↓') ])); } else { ths.push(createElement('th', col.title)); } }); /** * 創建內容 */ var trs = [];//<tr> 標簽數組 this.currentData.forEach(function (row) {//遍歷行 var tds = [];//<td> 標簽數組 that.currentColumns.forEach(function (cell) {//遍歷單元格 tds.push(createElement('td', row[cell.key])); }); trs.push(createElement('tr', tds)); }); return createElement('table', [ createElement('colgroup', cols), createElement('thead', [ createElement('tr', ths) ]), createElement('tbody', trs) ]) }, methods: { //初始化表頭 initColumns: function () { this.currentColumns = this.columns.map(function (col, index) { //新建字段,標識當前列排序類型;默認為“不排序” col.sortType = 'normal'; //新建字段,標識當前列在數組中的索引 col.index = index; return col; }); }, //初始化數據 initData: function () { this.currentData = this.data.map(function (row, index) { //新建字段,標識當前行在數組中的索引 row.index = index; return row; }); }, //排序 order: function (index, type) { this.currentColumns.forEach(function (col) { col.sortType = 'normal'; }); //設置排序類型 this.currentColumns[index].sortType = type; //設置排序函數 var sortFunction; var key = this.currentColumns[index].key; switch (type) { default://默認為 asc 排序 case 'asc': sortFunction = function (a, b) { return a[key] > b[key] ? 1 : -1; }; break; case 'desc': sortFunction = function (a, b) { return a[key] < b[key] ? 1 : -1; }; break; } this.currentData.sort(sortFunction); }, //升序 sortByAsc: function (index) { this.order(index, 'asc'); }, //降序 sortByDesc: function (index) { this.order(index, 'desc'); } }, watch: { data: function () { this.initData(); //找出排序字段 var sortedColumn = this.currentColumns.filter(function (col) { return col.sortType !== 'normal'; }); if (sortedColumn.length > 0) { if (sortedColumn[0].sortType === 'asc') { this.sortByAsc(sortedColumn[0].index); } else { this.sortByDesc(sortedColumn[0].index); } } } }, mounted() { this.initColumns(); this.initData(); }});var app = new Vue({ el: '#app', data: { //title 、key 與 width 必填;sortable 選填 columns: [ { title: '名稱', key: 'name', width:'60%' }, { title: '數量', key: 'num', width:'20%', sortable: true }, { title: '單價', key: 'unitPrice', width:'20%', sortable: true } ], data: [ { name: '真果粒牛奶飲品', num: 2, unitPrice: 59.9 }, { name: '蘇泊爾(SUPOR)電壓力鍋 ', num: 1, unitPrice: 378.0 }, { name: '樂事(Lay/'s)薯片', num: 3, unitPrice: 63.0 } ] }, methods:{ add:function () { this.data.push( { name: '良品鋪子 休閑零食大禮包', num: 5, unitPrice: 59.80 }); } }});
新聞熱點
疑難解答
圖片精選