主要功能

  1. 升、降按钮class相互排斥,这里使用了三目运算符进行处理,代码如下:
<span v-on:click="upclick(index)" :class="[list.classes==='shang'?'open':'',]">上升</span><span v-on:click="downclick(index)" :class="[list.classes==='xia'? 'open' :'',]">下降</span>

2.模板中存在多重的引号,故使用了模板字符串`` 代码如下:

  template:`<table><thead><tr><th v-for="(list,index) in currentcolumn" v-if="list.sortable===false">{{list.title}}</th><th v-else>{{list.title}}<span v-on:click="upclick(index)" :class="[list.classes==='shang'?'open':'',]">上升</span><span v-on:click="downclick(index)" :class="[list.classes==='xia'? 'open' :'',]">下降</span></th></tr></thead>`

另外需要注意的是vue2之后的版本,index索引是位于list之后的也就是(list,index)

3.模板操作的数据不应该是父元素的数据,需要把这些数据赋予组件所以应用了mounted()函数:

  mounted(){
            this.makeColumn();
            this.makeRow();
        },

4.应用watch函数实时监听数据row的变化,改变则立即进行排序:

watch:{
            row: function(){
                this.makeRow();
                var _this=this
                this.currentcolumn.forEach(function(item){
                   if(item.biaoji==='up'){
                    //    console.log('上升')
                       _this.upclick(item.indexs)
                   }else if(item.biaoji==='down'){
                       _this.downclick(item.indexs)
                   }else{
                       return false;
                   }
                })
            }
        },

功能图:
在这里插入图片描述
完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>可排序的表格组件</title>
    <style>
    .open{
        color: red;
    }
    </style>
</head>
<body>
    <div id="app">
        <ele :column='column' :row='row'></ele>
        <button @click="add()">添加数据</button>
    </div>

<script>
    Vue.component('ele',{
        //第一行使用了模板字符串``。这样引号包含问题就可以解决了
        template:`<table><thead><tr><th v-for="(list,index) in currentcolumn" v-if="list.sortable===false">{{list.title}}</th><th v-else>{{list.title}}<span v-on:click="upclick(index)" :class="[list.classes==='shang'?'open':'',]">上升</span><span v-on:click="downclick(index)" :class="[list.classes==='xia'? 'open' :'',]">下降</span></th></tr></thead>`+
            '<tr v-for="(lists,index) in currentrow"><td v-for="list in lists">{{list}}</td></tr>'+
            '</table>',
        props:['column','row'],
        data: function(){
            return {
                currentcolumn:[],
                   currentrow:[]
            }
        },
        methods:{
            makeColumn: function(){
                this.currentcolumn = this.column.map(function(item,index){
                    // 这里给元素添加属性indexs是为了watch监听到row 发生变化后,给点击事件传参。
                    item.indexs=index;
                    //classes属性的作用是控制'上升','下降'按钮的class,他么两个的class是相反的,所以使用了三目运算符
                    item.classes='';
                    return item;
                })
            },
            makeRow: function(){
                this.currentrow = this.row.map(function(item){
                    return item
                })
            },
            upclick: function(index){
                this.currentcolumn.forEach(function(item,indexs){
                    if(indexs===index){
                        item.biaoji='up'
                        item.classes='shang'
                    }else{
                        item.biaoji='normal'
                        item.classes=''
                    }
                });
                this.currentrow.sort(function(a,b){
                    return a[index]>b[index]? 1: -1;
                })
             
            },
            downclick: function(index){
                this.currentcolumn.forEach(function(item,indexs){
                    if(indexs===index){
                        //这里给元素添加标记的原因是新增数据后,根据这个标记来自动排一次序。
                        item.biaoji='down';
                        item.classes='xia'
                    }else{
                        item.biaoji='normal'
                        item.classes=''
                    }
                })
                this.currentrow.sort(function(a,b){
                    return b[index]>a[index]?1:-1
                })
               
            },
        },
        mounted(){
            this.makeColumn();
            this.makeRow();
        },
        watch:{
            row: function(){
                this.makeRow();
                var _this=this
                this.currentcolumn.forEach(function(item){
                   if(item.biaoji==='up'){
                    //    console.log('上升')
                       _this.upclick(item.indexs)
                   }else if(item.biaoji==='down'){
                       _this.downclick(item.indexs)
                   }else{
                       return false;
                   }
                })
            }
        },
    })
var app = new Vue({
    el: '#app',
    data:{
        column:[
            {title:'姓名',sortable: false},{title: '年龄',sortable: true},{title: '出生日期',sortable: true},{title: '暂住地',sortable: false}
        ],
        row:[
            ['张三',22,'1994-1-2','河南周口1'],['李四',19,'1993-1-2','河南周口2'],['王五',33,'1992-1-2','河南周口3'],['赵六',21,'1991-1-2','河南周口4']
        ]
    },
    methods: {
        add: function(){
            this.row.push(['新增',100,'1952-01-01','河南周口001'])
        }
    }
})
</script>    
</body>
</html>
Logo

前往低代码交流专区

更多推荐