亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

Vue.js實現可排序的表格組件功能示例

2019-11-19 12:07:10
字體:
來源:轉載
供稿:網友

本文實例講述了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      });    }  }});

為了讓排序后的 columns 與 data 不影響原始數據,我們在組件的 data 中定義了相應的當前數據對象。因此在 method 中使用傳入的值,初始化這些數據對象,最后在 mounted() 調用這些初始化方法。

columns 中的每一項都是包含 title(列名)、key(對應 data 中的字段名)、width(寬度) 以及 sortable(是否可排序) 的對象。其中,只有 sortable 為可選項,如果設定為 true,則表示該列可點擊排序。

map() 會對數組的每一項運行給定函數,返回每次函數調用的結果組成的數組。

排序分為升序與降序,因為只能對某一列進行排序,所以是互斥操作。我們為每一列新增一個 sortType ,用于標識該列的排序類型,初始值為 normal,表示不排序。

因為排序字段可能是任意列,所以我們為每一列新增一個 index,用于標識當前列在數組中的索引。

在 Render 函數中,首先創建列樣式與表頭,接著創建內容。

Render 函數中的 createElement 可以簡寫為 h,這樣代碼會變得更簡潔:

render: function (h) {  var that = this;  /**   * 創建列樣式與表頭   */  var ths = [];//<th> 標簽數組  var cols = [];//<cols> 標簽數組  this.currentColumns.forEach(function (col, index) {    if (col.width) {//創建列樣式      cols.push(h('col', {        style: {          width: col.width        }      }))    }    if (col.sortable) {      ths.push(h('th', [        h('span', col.title),        //升序        h('a', {          class: {            on: col.sortType === 'asc'          },          on: {            click: function () {              that.sortByAsc(index)            }          }        }, '↑'),        //降序        h('a', {          class: {            on: col.sortType === 'desc'          },          on: {            click: function () {              that.sortByDesc(index);            }          }        }, '↓')      ]));    } else {      ths.push(h('th', col.title));    }  });  /**   * 創建內容   */  var trs = [];//<tr> 標簽數組  this.currentData.forEach(function (row) {//遍歷行    var tds = [];//<td> 標簽數組    that.currentColumns.forEach(function (cell) {//遍歷單元格      tds.push(h('td', row[cell.key]));    });    trs.push(h('tr', tds));  });  return h('table', [    h('colgroup', cols),    h('thead', [      h('tr', ths)    ]),    h('tbody', trs)  ])}

創建內容時,我們首先遍歷所有行,然后在循環內部遍歷所有列,得出 <td> 與 <tr> 內容。

創建表頭時,對是否排序做了相應的處理,并綁定了相應的點擊事件。

點擊事件定義在 methods 中,因為升序與降序邏輯大體相同,所以又封裝了一層 order() 排序函數。

order() 排序函數內部使用了數組的 sort() 方法。sort() 方法會調用每個數組項的 toString() 方法,然后比較得到的字符串,即使數組中的每一項是數值,比較的也是字符串。這里傳入了一個比較函數作為參數。為了兼容所有瀏覽器,在比較函數中,我們返回的是 1 或者 -1。

排序之前,先把所有列的排序類型都設置為不排序,然后再更新當前列的排序狀態。這就會對應到 render 函數里綁定 <a> 標簽的 class 中的 on 樣式,即當前列排序狀態會被高亮顯示。

表格被初始化渲染之后,如果 data 發生變化,那么表格組件數據應該也要同步更新。因此,我們在 watch 中做了數據更新以及數據重排操作。

css:

[v-cloak] {  display: none;}table {  width: 100%;  margin-bottom: 24px;  /*合并邊框模型*/  border-collapse: collapse;  border-spacing: 0;  /*在空單元格周圍繪制邊框*/  empty-cells: show;  border: 1px solid #e9e9e9;}table th {  font: bold 14px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;  background: #CAE8EA;  color: #5c6b77;  /*設置文本粗細*/  font-weight: 600;  /*段落中的文本不進行換行*/  white-space: nowrap;  border-top: 1px solid #C1DAD7;}table td, table th {  padding: 8px 16px;  text-align: left;  border-right: 1px solid #C1DAD7;  border-bottom: 1px solid #C1DAD7;}table th a {  /*不獨占一行的塊級元素*/  display: inline-block;  margin: 0 4px;  cursor: pointer;}table th a.on {  color: #3399ff;}table th a:hover {  color: #3399ff;}

效果:

點擊此處查看本文示例代碼

PS:感興趣的朋友還可以使用如下在線工具測試上述代碼:

在線HTML/CSS/JavaScript前端代碼調試運行工具:
http://tools.VeVB.COm/code/WebCodeRun

在線HTML/CSS/JavaScript代碼運行工具:
http://tools.VeVB.COm/code/HtmlJsRun

希望本文所述對大家vue.js程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久欧美精品| 国产精品99久久久久久白浆小说| 欧美日韩国产成人| 国产精品久久一| 精品综合久久久久久97| 国产精品美女久久久久av超清| 欧美激情啊啊啊| 91亚洲精品视频| 久久综合国产精品台湾中文娱乐网| 日韩欧美亚洲一二三区| 久久久久中文字幕2018| 亚洲欧洲成视频免费观看| 亚洲欧洲日产国码av系列天堂| 亚洲激情久久久| 欧美日韩国产999| 欧美激情精品久久久久久黑人| 欧美精品在线免费| 日韩大胆人体377p| 国产精品7m视频| 久久精品久久久久久国产 免费| 亚洲精品一区二区网址| 国外成人免费在线播放| 国产精品成人一区二区三区吃奶| 91精品久久久久久久久久久久久| 欧美精品videosex牲欧美| 九九热精品视频国产| 欧美在线视频免费播放| 国产成人亚洲综合| 91av在线精品| 日韩免费在线观看视频| 国内精久久久久久久久久人| 91国产精品电影| 在线精品播放av| 麻豆国产va免费精品高清在线| 成人黄色av网站| 久久综合伊人77777| 韩剧1988在线观看免费完整版| 这里只有精品视频在线| 欧美高清视频在线播放| 日韩av在线天堂网| 26uuu亚洲国产精品| 国产精品视频午夜| 欧美成人免费观看| 亚洲精品乱码久久久久久金桔影视| 91精品在线一区| 欧美成人激情图片网| 亚洲日本成人网| 欧美在线视频免费播放| 性色av一区二区三区在线观看| 在线播放国产一区中文字幕剧情欧美| 国产成人小视频在线观看| 蜜臀久久99精品久久久久久宅男| 日本久久久久久| 国产精品青青在线观看爽香蕉| 一区二区三欧美| 成人精品一区二区三区电影黑人| 国产99在线|中文| xxxxx成人.com| 精品爽片免费看久久| 综合av色偷偷网| 一级做a爰片久久毛片美女图片| 日韩电影免费观看中文字幕| 欧美日韩在线第一页| 欧美亚洲视频在线看网址| 国产日韩欧美中文在线播放| 91免费综合在线| 欧美疯狂性受xxxxx另类| 国产精品普通话| 久久精品国产99国产精品澳门| 欧美成人h版在线观看| 91极品女神在线| 成人午夜黄色影院| 久久久在线视频| 亚洲人免费视频| 国产午夜精品美女视频明星a级| 久久人91精品久久久久久不卡| 一区二区av在线| 在线国产精品播放| 欧美激情精品久久久久久久变态| 久久久久久久一| 久久人91精品久久久久久不卡| 国产一区二区三区在线看| 国产精品海角社区在线观看| 亚洲sss综合天堂久久| 久久亚洲国产精品| 国产精品黄页免费高清在线观看| 欧美性猛交xxxx免费看久久久| 81精品国产乱码久久久久久| 久久久久久亚洲精品不卡| 精品在线观看国产| 91精品久久久久久久久久久| 亚洲一级一级97网| 欧美色图在线视频| 精品久久久久人成| 国产在线高清精品| 成年人精品视频| 亚洲男人的天堂在线播放| 欧美精品做受xxx性少妇| 91精品国产91久久久| 国产日韩在线一区| 成人黄色片网站| 精品中文字幕在线观看| 韩国19禁主播vip福利视频| 亚洲va久久久噜噜噜久久天堂| 亚洲色图第三页| 欧美精品一区在线播放| 欧美性生交xxxxx久久久| 久久久久久久香蕉网| 午夜精品一区二区三区在线播放| 久久免费精品日本久久中文字幕| 欧美一级电影免费在线观看| 久久夜色精品国产欧美乱| 成人黄色生活片| 中文字幕av一区二区三区谷原希美| 91色在线观看| 国产精品1234| 色综合男人天堂| 最近中文字幕mv在线一区二区三区四区| 亚洲成人精品视频在线观看| 色综合视频网站| 亚洲a级在线观看| 国产va免费精品高清在线观看| 亚洲成人在线视频播放| 欧美精品在线网站| 国产69精品久久久久久| 国产精品久久中文| 日韩欧美中文第一页| 久久不射热爱视频精品| 国产视频久久久久| 久久精品一区中文字幕| 久久精品视频99| 91久久国产婷婷一区二区| 久久精品亚洲一区| 精品香蕉一区二区三区| 97在线观看视频国产| 国产精品永久免费视频| 国产午夜精品视频| 国产日韩精品在线观看| 日韩免费在线观看视频| 国产亚洲精品美女久久久| 7777精品视频| 亚洲国产精久久久久久久| 97人人做人人爱| 最近2019年中文视频免费在线观看| 国产极品jizzhd欧美| 欧美国产日韩xxxxx| 8090理伦午夜在线电影| 91av视频在线免费观看| 亚洲一区二区自拍| 久久久日本电影| 不卡av电影在线观看| 日韩av色综合| 日韩欧美一区视频| 国产精品久久久久秋霞鲁丝| 在线看日韩欧美| 亚洲精品免费一区二区三区| 中文字幕日韩av综合精品| 2019中文字幕在线观看| 欧美午夜精品久久久久久人妖| 8x拔播拔播x8国产精品| 国产999在线观看| 亚洲天堂影视av| 欧美激情久久久久久| 亚洲欧美一区二区三区四区|