<body>
<div id="app">
<v-table :data="data" :columns="columns"></v-table>
<button @click="handleAddData">添加数据</button>
</div>
</body>
<script>
Vue.component('v-table',{
props:{
columns:{
type:Array,
default:function(){
return []
}
},
data:{
type:Array,
default:function(){
return []
}
}
},
data:function(){
return {
currentColumns:[],
currentData:[]
}
},
render:function(h){
const that = this
let ths = []
this.currentColumns.forEach((col,index)=>{
if(col.sortable){
ths.push(h('th',[
h('span',col.title),
h('a',{
class:{
on:col._sortType === 'asc'
},
on:{
click:function(){
that.handleSortByAsc(index)
}
}
},'上'),
h('a',{
class:{
on:col._sortType === 'desc'
},
on:{
click:function(){
that.handleSortByAsc(index)
}
}
},'下')
]))
}else{
ths.push(h('th',col.title))
}
});
let trs = []
this.currentData.forEach(row=>{
let tds = []
that.currentColumns.forEach(cell=>{
tds.push(h('td',row[cell.key]))
})
trs.push(h('tr',tds))
});
return h('table',[
h('thead',[
h('tr',ths)
]),
h('tbody',trs)
])
},
methods:{
makeColumns:function(){
this.currentColumns = this.columns.map((col,index)=>{
col._sortType = 'normal'
col._index = index
return col
})
},
makeData:function(){
this.currentData = this.data.map((row,index)=>{
row._index = index
return row
})
},
handleSortByAsc:function(index){
const key = this.currentColumns[index].key
this.currentColumns.forEach(col=>{
col._sortType = 'normal'
})
this.currentColumns[index]._sortType = 'asc'
this.currentData.sort((a,b)=>{
return a[key]>b[key]?1:-1
})
},
handleSortByDesc:function(index){
const key = this.currentColumns[index].key
this.currentColumns.forEach(col=>{
col._sortType = 'normal'
})
this.currentColumns[index]._sortType = 'desc'
this.currentData.sort((a,b)=>{
return a[key]<b[key]?1:-1
})
}
},
watch:{
data:function(){
this.makeData();
const sortedColumn = this.currentColumns.filter(col=>{
return col._sortType !== 'noraml'
})
if(sortedColumn.length > 0){
if(sortedColumn[0]._sortType === 'asc'){
this.handleSortByAsc(sortedColumn[0]._index)
}else{
this.handleSortByAsc(sortedColumn[0]._index)
}
}
}
},
mounted(){
this.makeColumns()
this.makeData()
}
})
const app=new Vue({
el:'#app',
data:{
columns:[
{
title:'姓名',
key:'name'
},
{
title:'年龄',
key:'age',
sortable:true
},
{
title:'出生日期',
key:'birthday',
sortable:true
},
{
title:'地址',
key:'address'
}
],
data:[
{
name:'王小明',
age:18,
birthday:'1999-02-21',
address:'北京市朝阳区狗药居'
},
{
name:'张小刚',
age:15,
birthday:'1992-02-21',
address:'北京市朝阳区狗药居'
},
{
name:'周伟',
age:25,
birthday:'1991-02-21',
address:'北京市朝阳区狗药居'
},
{
name:'李小红',
age:30,
birthday:'1997-02-21',
address:'北京市朝阳区狗药居'
}
]
},
methods:{
handleAddData:function(){
this.data.push({
name:'刘小天',
age:18,
birthday:'1997-02-21',
address:'广东广州
})
}
}
})
</script>
table{
width:100%;
margin-bottom:24px;
border-collapse:collapse;
border-spacing: 0;
empty-cells: show;
border:1px solid #e9e9e9;
}