资讯专栏INFORMATION COLUMN

怎么写好组件

wow_worktile / 2579人阅读

摘要:我们为什么要写组件呢这里不细分组件插件控件,追究其原因无非让代码,能够复用,追求更快的开发效率。最终解决在写组件的时候,业务逻辑部分,现预留配置项,以便后面业务发生改变,通过配置项来重置。

我们为什么要写组件呢?这里不细分组件、插件、控件,追究其原因无非让代码,能够复用,追求更快的开发效率。其实还有个重要的原因,项目大了之后,难以维护。这个时候就会把项目中重复的部分抽取出来,形成一个组件。但是组件也会有些"缺点",这个最后讲。

组件需求

要实现如图的一个条件选择器

有的时候,项目时间紧张,就会直接切图,通过jquery的dom选择器实现这个"简单的功能"。

需求分析

为了更好的维护,以及更好的复用此组件,就要做些抽象。

数据层:用来决定按钮个数以及按钮是否选择

表现层:按钮使用现有的ui组件

逻辑层:按钮事件等逻辑处理

数据层
data: null,
choseT: 0,
choseF: 0,
getDataStatistics: function() {
    var list = this.data;
    var choseT = 0;
    var choseF = 0;
    var len = list.length;
    for (var i = 0; i < list.length; i++) {
        if(list[i].checked == "checked") {
            choseT++;
        }else {
            choseF++;
        }
    }
    return {
        choseT: choseT,
        choseF: choseF,
        len: len
    };
},
dataChangeAll: function(checked) {
    var list = this.data;
    var len = list.length;
    checked = checked || "";
    if(checked == "checked") {
        this.choseT = len;
        this.choseF = 0;
    }else {
        this.choseT = 0;
        this.choseF = len;
    }

    for (var i = 0; i < len; i++) {
        list[i].checked = checked;
    }
},
dataChangeSingle: function(index, checked) {
    var list = this.data;
    var choseT = this.choseT;
    var choseF = this.choseF;
    if(checked == "checked") {
        choseT++;
        choseF--;
    }else {
        choseT--;
        choseF++;
    }
    this.choseT = choseT;
    this.choseF = choseF;
    list[index].checked = checked;
}

数据层主要对原始数据做些CURD的一些操作,具体的操作看具体的业务需求,但是要具有这个意识。

表现层

说白了表现层也就是template层或者view层,就是用户所看到的,一般会用一个比较成熟的ui库,比如bootstrap。

getHtml: function(list, statistic) {
    var html = 
        ["
", "
", "
", this.getChoseNav(statistic), "
", "
", this.getChoseItem(list), "
", "
", "
"].join(""); return html; }, getChoseNav: function(statistic) { var checkAll = ""; var checkNone = ""; var len = statistic.len; if(statistic.choseT == len) { checkAll = "checked"; } if(statistic.choseF == len) { checkNone = "checked"; } return [ "", "" ].join(""); }, getChoseItem: function(list) { var inputs = ""; var doInputFunc = function(i, detail) { return [ "
", "", "
", ].join(""); }; for (var i = 0; i < list.length; i++) { inputs += doInputFunc(i, list[i]); } return inputs; }, domAction: function($el, type, data) { var html = ""; type = type || "all"; if(type == "item") { html = this.getChoseItem(data); $el.find(".J_view_checkItems").html(html); }else if(type == "all") { html = this.getChoseNav(data); $el.find(".J_view_checkNav").html(html); } }

众所周知,template就是根据数据渲染成html,在spa项目尤其重要。

逻辑层

这层主要做 调用template方法将数据渲染到页面上;将页面上的一些事件结果,映射到数据层。其实现在流行的MVVM模式,就是在逻辑层这里做了更多的事情,只是开发者们不用去关心细节处理,更专注业务的开发。

eventBind: function($el) {
    var _this = this;
    var $target = "";
    
    // 全选
    $el.on("change", ".J_view_checkAll", function() {
        if(!$(this).parent().hasClass("checked")) {
            _this.module.dataChangeAll("checked");
            _this.view.domAction($el, "all", _this.module.getDataStatistics());
            _this.view.domAction($el, "item", _this.module.data);
        }
    });
    
    // 全不选
    $el.on("change", ".J_view_checkNone", function() {
        if(!$(this).parent().hasClass("checked")) {
            _this.module.dataChangeAll("");
            _this.view.domAction($el, "all", _this.module.getDataStatistics());
            _this.view.domAction($el, "item", _this.module.data);
        }
    });
    
    // 单个
    $el.on("click", ".J_view_checkItem", function() {
        $target = $(this);
        var index = $target.val();
        var checked = "";
        if($target.prop("checked")) {
            checked = "checked";
        }
        _this.module.dataChangeSingle(index, checked);
        _this.view.domAction($el, "all", _this.module.getDataStatistics());
    });
},
eventUnbind: function($el) {
    $el.off("change");
    $el.off("click");
},

完整案例

总结

这样子写能更好的抽象出公共部分,在其它模块就只要传入数据就可以了,不用重复拷贝代码了。

一开始说到组件会有‘缺点’?尤其是业务组件?

分析

项目版本迭代是一个很正常的事情,第一版的时候,比如这个数据选择项这个组件,在每个模块都有这样的需求。但是在下一个版本的时候,产品经理在其中一个模块更改了业务需求,这就导致这个模块的数据选择项,跟其它模块的数据选择项不一样了,但是又有80%甚至90%的相似度,这个时候就非常困扰,到底是重新写个,还是再对原来的组件,增加个兼容配置项?

重新写会有很多重复的代码。新增配置项,又必须保证之前所有的模块都要正确,得必须都验证过去。有人就会觉得直接去验证好了啊,但是项目大了之后,一个一个去验证不是解决问题的办法。

最终解决

在写组件的时候,业务逻辑部分,现预留配置项,以便后面业务发生改变,通过配置项来重置。尤其是觉得产品经理会更改频繁的部分。

实在是觉得更改逻辑较大,那就重新写个吧,因为一个一个去验证之前的模块的成本还是很大的。

原文地址 http://tostring.site/2016/07/16/%E6%80%8E%E4%B9%88%E5%86%99%E5%A5%BD%E7%BB%84%E4%BB%B6/

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/87795.html

相关文章

  • 如何写好前端业务代码?

    摘要:前言如何写出可维护和可读性高的代码,这一直是一个困扰很多人的问题。总结在开始写业务之前,理应先想清楚需求和业务逻辑,设计出合理的数据结构,对代码进行好的分层,这样在一定程度上可以写出可维护性更高的代码。 前言 如何写出可维护和可读性高的代码,这一直是一个困扰很多人的问题。关于变量如何起名、如何优化if else之类的小技巧,这里就不做介绍了,推荐去看《代码大全2》,千书万书,都不如一本...

    kbyyd24 评论0 收藏0
  • Vue.js新手入门指南[转载]

    摘要:就是一个用于搭建类似于网页版知乎这种表单项繁多,且内容需要根据用户的操作进行修改的网页版应用。单页应用程序顾名思义,单页应用一般指的就是一个页面就是应用,当然也可以是一个子应用,比如说知乎的一个页面就可以视为一个子应用。 最近在逛各大网站,论坛,以及像SegmentFault等编程问答社区,发现Vue.js异常火爆,重复性的提问和内容也很多,楼主自己也趁着这个大前端的热潮,着手学习了一...

    MartinHan 评论0 收藏0
  • React

    摘要:而我只知道有自己的虚拟,它会对比虚拟和真实的差别,然后在适当的时机更新页面。函数的第一个参数只能是一个标签,不能是并列的两个标签。第一个添加了的属性,该属性值指向,意思是该组件名为的静态属性。 网页总是一个链接着另一个的,React一大优势在于每次链接到另一个页面上去的时候,不需要向传统页面一样,得销毁所有代码,重新渲染新页面的代码,而只在一个页面上展现新的内容——单页页面。 Reac...

    ningwang 评论0 收藏0
  • React

    摘要:而我只知道有自己的虚拟,它会对比虚拟和真实的差别,然后在适当的时机更新页面。函数的第一个参数只能是一个标签,不能是并列的两个标签。第一个添加了的属性,该属性值指向,意思是该组件名为的静态属性。 网页总是一个链接着另一个的,React一大优势在于每次链接到另一个页面上去的时候,不需要向传统页面一样,得销毁所有代码,重新渲染新页面的代码,而只在一个页面上展现新的内容——单页页面。 Reac...

    tain335 评论0 收藏0
  • 代码质量把控和项目进度之间的平衡

    摘要:所以这中间需要一个取舍,哪些是要严格要求的,哪些是可以不管的。首先,好代码可能是聊出来的。比如需求确认这一块,多问多画流程图少动手。在这个过程中不断整理和梳理原有的概念。代码的直接修改。最后,好代码是改出来的。 作为前端负责人,很多时候发愁的不是写好代码,而是怎么让身边水平较差的小伙伴能写出好的代码 另外,你还要保证项目的进度,所以代码质量和项目进度之间有着天然的矛盾,怎么去平衡值得我...

    gplane 评论0 收藏0

发表评论

0条评论

wow_worktile

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<