使用Vue.js怎么实现一个可排序的表格组件

这期内容当中小编将会给大家带来有关使用Vue.js怎么实现一个可排序的表格组件,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

html:

使用Vue.js怎么实现一个可排序的表格组件

<divid="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){
varthat=this;
/**
*创建列样式与表头
*/
varths=[];//<th>标签数组
varcols=[];//<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));
}
});
/**
*创建内容
*/
vartrs=[];//<tr>标签数组
this.currentData.forEach(function(row){//遍历行
vartds=[];//<td>标签数组
that.currentColumns.forEach(function(cell){//遍历单元格
tds.push(createElement('td',row[cell.key]));
});
trs.push(createElement('tr',tds));
});
returncreateElement('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;
returncol;
});
},
//初始化数据
initData:function(){
this.currentData=this.data.map(function(row,index){
//新建字段,标识当前行在数组中的索引
row.index=index;
returnrow;
});
},
//排序
order:function(index,type){
this.currentColumns.forEach(function(col){
col.sortType='normal';
});
//设置排序类型
this.currentColumns[index].sortType=type;
//设置排序函数
varsortFunction;
varkey=this.currentColumns[index].key;
switch(type){
default://默认为asc排序
case'asc':
sortFunction=function(a,b){
returna[key]>b[key]?1:-1;
};
break;
case'desc':
sortFunction=function(a,b){
returna[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();
//找出排序字段
varsortedColumn=this.currentColumns.filter(function(col){
returncol.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();
}
});
varapp=newVue({
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){
varthat=this;
/**
*创建列样式与表头
*/
varths=[];//<th>标签数组
varcols=[];//<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));
}
});
/**
*创建内容
*/
vartrs=[];//<tr>标签数组
this.currentData.forEach(function(row){//遍历行
vartds=[];//<td>标签数组
that.currentColumns.forEach(function(cell){//遍历单元格
tds.push(h('td',row[cell.key]));
});
trs.push(h('tr',tds));
});
returnh('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:1pxsolid#e9e9e9;
}
tableth{
font:bold14px"TrebuchetMS",Verdana,Arial,Helvetica,sans-serif;
background:#CAE8EA;
color:#5c6b77;
/*设置文本粗细*/
font-weight:600;
/*段落中的文本不进行换行*/
white-space:nowrap;
border-top:1pxsolid#C1DAD7;
}
tabletd,tableth{
padding:8px16px;
text-align:left;
border-right:1pxsolid#C1DAD7;
border-bottom:1pxsolid#C1DAD7;
}
tabletha{
/*不独占一行的块级元素*/
display:inline-block;
margin:04px;
cursor:pointer;
}
tabletha.on{
color:#3399ff;
}
tabletha:hover{
color:#3399ff;
}

上述就是小编为大家分享的使用Vue.js怎么实现一个可排序的表格组件了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注恰卡编程网行业资讯频道。

发布于 2021-04-15 01:56:25
收藏
分享
海报
0 条评论
173
上一篇:怎么在JavaScript中遍历DOM元素 下一篇:使用JavaScript怎么实现一个微博留言功能
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码