V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
18510047382
V2EX  ›  React

使用 ale.js 制作一个小而美的表格编辑器(2)

  •  
  •   18510047382 · 2019-01-16 17:05:30 +08:00 · 1749 次点击
    这是一个创建于 2168 天前的主题,其中的信息可能已经有所发展或是发生改变。

    今天来教大家如何使用 ale.js 制作一个小而美的表格编辑器,首先先上 gif:

    是不是还是有一点非常 cool 的感觉的?那么我们现在开始吧!

    这是我们这篇文章结束后完成的效果(如果想继续完成请访问第三篇文章):

    ok,那继续开始吧**(本篇文章是表格编辑器系列的第二篇文章,如果您还没有看过第一篇,请访问 第一篇文章(开源中国)):**

    首先我们写一个名叫 staticData 的 object,里面添加 2 个属性,分别是 sortBy 和 sortType:(关于 staticData 这里不做阐述,如果有需要请访问 cn.alejs.org

    staticData: {
        sortBy: -1, //排序列索引,默认没有,所以为-1
        sortType: 'down' //排序类型,默认为降序
    }
    

    之后我们在 th 标签里面增加一个 onclick 属性,指向 methods 里面的 handleTheadOnclick 函数,并传递一个 event 作为参数:

    (之前的代码)

    this.data.bookHeader.forEach(function(val, i, arr) {
        returnVal += "<th>" + val + "</th>";
    })
    

    (改进后的代码)

    this.data.bookHeader.forEach(function(val, i, arr) {
        returnVal += "<th onclick='this.methods.handleTheadOnclick(event)'>" + val + "</th>";
    })
    

    为了让他显示排序时的小箭头,我们需要再改进这行代码为这样:

    this.data.bookHeader.forEach(function(val, i, arr) {
        returnVal += "<th onclick='this.methods.handleTheadOnclick(event)'>" + val + (sortBy === i ? getSortSign() : '') + "</th>";
    })
    

    由于 sortBy 变量和 getSortSign 函数变量还未定义,所以我们要在之前的代码里引用一下:

    (原来的代码)

    var returnVal = "<table><thead><tr>";
    

    (改进后的代码)

    var returnVal = "<table><thead><tr>",
        getSortSign = this.methods.getSortSign,
        sortBy = this.staticData.sortBy;
    

    其中,sortBy 变量指向的是静态 data 里的 sortBy 变量,这个我们已经定义了,所以先不管他。而另一个 getSortSign 函数还没有定义,所以我们在 methods 里面定义一下他:

    getSortSign() {
        if (this.staticData.sortType === "up") {
            return '\u2191';
        } else {
            return '\u2193';
        }
    }
    

    其功能主要就是判断是正序还是倒叙,并分别输出正反小箭头。

    之后我们就需要完成 handleTheadOnclick 函数了。它分别引用了 changeSortType 和 sortList 函数:

    handleTheadOnclick(e) {
        this.methods.changeSortType(e);
        this.methods.sortList(e);
    }
    

    其中 changeSortType 函数是用来改变排序类型的,而 sortList 函数使用来排序的。

    那么我们先完成 changeSortType 函数吧:

    changeSortType(e) {
        this.staticData.sortBy = e.target.cellIndex;
        if (this.staticData.sortType === "up") {
            this.staticData.sortType = "down";
        } else {
            this.staticData.sortType = "up";
        }
    }
    

    ok,这个函数的功能和实现都非常简单,其中 cellIndex 是用来获取这是属于表格中那一列的。

    那么 sortList 函数的实现则稍微有些复杂:

    sortList(e) {
        //获取列索引值
        var index = e.target.cellIndex;
        //判断排序类型
        if (this.staticData.sortType === "up") {
            //使用数组的 sort 函数进行排序,分别按 charCode 进行排序
            this.data.bookData.sort(function(a, b) {
                return a[index].charCodeAt(0) > b[index].charCodeAt(0) ? 1 : -1;
            })
        } else {
            this.data.bookData.sort(function(a, b) {
                return a[index].charCodeAt(0) < b[index].charCodeAt(0) ? 1 : -1;
            })
        }
    
        this.data.bookData = this.data.bookData;
    }
    

    这是我们目前的全部 js 代码:

    Ale("excel", {
        template() {
            return this.methods.handleTemplateRender();
        },
        methods: {
            handleTemplateRender() {
                //定义 DOM 基本结构
                var returnVal = "<table><thead><tr>",
                    getSortSign = this.methods.getSortSign,
                    sortBy = this.staticData.sortBy;
    
                //循环遍历 bookHeader 数据并输出
                this.data.bookHeader.forEach(function(val, i, arr) {
                    returnVal += "<th onclick='this.methods.handleTheadOnclick(event)'>" + val + (sortBy === i ? getSortSign() : '') + "</th>";
                })
                returnVal += "</thead></tr><tbody>";
    
                //循环遍历 bookData 数据并输出
                this.data.bookData.forEach(function(thisBook, i, arr) {
                    //输出一行
                    returnVal += "<tr>";
                    thisBook.forEach(function(val, i, arr) {
                        //输出一列
                        returnVal += "<td>" + val + "</td>";
                    })
                    returnVal += "</tr>";
                })
                returnVal += "</tbody></table>";
    
                //返回 DOM 结构
                return returnVal;
            },
            handleTheadOnclick(e) {
                this.methods.changeSortType(e);
                this.methods.sortList(e);
            },
            changeSortType(e) {
                this.staticData.sortBy = e.target.cellIndex;
                if (this.staticData.sortType === "up") {
                    this.staticData.sortType = "down";
                } else {
                    this.staticData.sortType = "up";
                }
            },
            sortList(e) {
                var index = e.target.cellIndex;
                if (this.staticData.sortType === "up") {
                    this.data.bookData.sort(function(a, b) {
                        return a[index].charCodeAt(0) > b[index].charCodeAt(0) ? 1 : -1;
                    })
                } else {
                    this.data.bookData.sort(function(a, b) {
                        return a[index].charCodeAt(0) < b[index].charCodeAt(0) ? 1 : -1;
                    })
                }
    
                this.data.bookData = this.data.bookData;
            },
            getSortSign() {
                if (this.staticData.sortType === "up") {
                    return '\u2191';
                } else {
                    return '\u2193';
                }
            }
        },
        data: {
            bookHeader: [
                "Book", "Author", "Language", "Published", "Sales"
            ],
            bookData: [
                ["The Lord of the Rings", "	J. R. R. Tolkien", "English", "1954-1955", "150 million"],
                ["The Little Prince", "Antoine de Saint-Exupéry", "French", "1943", "140 million"],
                ["Dream of the Red Chamber", "Cao Xueqin", "Chinese", "1791", "100 million"]
            ]
        },
        staticData: {
            sortBy: -1,
            sortType: 'down'
        }
    })
    Ale.render("excel", {
        el: "#app"
    })
    

    然后效果就如下图所示啦:

    如果想了解更多,欢迎关注我在明天推出的第三篇教程,同时也关注一下 alejs 哦,感谢各位!

    (非常重要:如果有能力的话不妨去 Github 或 码云 上 star 一下我们吧!不过如果您特别喜欢 alejs 的话也可以 watch 或 fork 一下哦!十分感谢!)

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2949 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 00:36 · PVG 08:36 · LAX 16:36 · JFK 19:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.