使用VirtualView渲染的前端UI组件开发模式

简介:

上篇文章中,我讲到我们的组件开发模式解决了以下几个问题

  1. 渲染逻辑,业务逻辑,事件分发,控制器彻底分离
  2. 组件内部只有一个状态
  3. 渲染逻辑只有一处
  4. 只绑定一次事件
  5. 没有任何学习成本

下面来看我们具体我们是通过什么方式解决的

  1. 渲染逻辑,业务逻辑,事件分发,控制器彻底分离,易于维护和重用

    我们在原来的开发中一般都是把这些代码都写在同一个文件中,整个文件上千行是常有的事。在维护代码或者根据需求的变化修改代码的时候会变得极其困难,从团队的角度来说,根本没法互相协作。为了解决这些问题我们把一个组件拆分为渲染逻辑,业务逻辑,时间分发,和控制器。下面是我们开发一个组件时的文件结构

    组件文件结构

    - index.js
    
        组件的控制器: 主要负责组件的变量的初始化,这些变量主要包括组件的container,template,event,store,initData;根据不同的状态拿到对应的模版;virtual dom的转换,diff,pattch;事件的绑定与解绑。
    
    - store.js
    
        业务逻辑: 主要负责在内存中对业务逻辑的处理,如add,remove,modify,query等的操作,处理完成后把最终的状态告诉组件的控制器,组件只会存在这样的一个唯一的状态;同时也负责从service中取得数据。
    
    - tempate.js
    
        渲染逻辑: 该文件中都是组件的不同的状态对应的模版方法,每个方法都会根据传入的组件状态参数,和相对应模版结构组合为最终的html.
    
    - actions.js
    
        事件分发: 该部分主要用于组件的对外通信,如果组件内部的变化需要通知其他组件,就需要该部分来协作完成。
    
  2. 组件内部只有一个状态

    组件内部只有一个状态是通过Store来维护的,这里所说的状态其实就是组件需要的数据。组件的初始化数据会传给store,在每次事件的操作会触发store中的对数据的处理方法,等数据更新完成会发出一个updateData的事件告诉组件控制器。具体的实现看下面的代码

    
            createStore: function(){
                var Store = this.get('store');
                var that = this;
    
                if(Store){
                    var initData = this.get('initData');
                    var storeObj = new Store({
                        data:initData
                    });
                    storeObj.on('updateData',function(e){
                        var data = e.data.data;
                        that.updateView(data);  
                    });
    
                    this.store = storeObj;
                }
            }
    
  3. 渲染逻辑只有一处

    组件的所有渲染都是通过一个render方法进行.在render方法中拿到最新的html字符串,通过VirtualHtml转换为VirtualDom,如果是首次渲染就直接附加到真正的dom树上;如果是以后渲染,需要拿最新的VirtualDom和上次的VirtualDom进行diff,把diff所产生的patches,patche到真正的dom树上。具体的实现看下面的代码

    
        render: function(data,cb){
            var that = this;
    
            var firstRender = !this.tree;
    
            this.renderedTemplate = this.buildHTML();
    
            //把字符串转换为dom
            VirtualHtml(this.renderedTemplate, function (err, dom) {
                if (err) {
                    if (cb) return cb(err);
                    throw err;
                }
    
                if (firstRender) {
                    that.tree = dom;
                    that.el = CreateElement(dom);
                } else {
                    var patches = Diff(that.tree, dom);
                    that.tree = dom;
                    that.el = Patch(that.el, patches);
                }
    
                if (cb) cb(null, that);
            });
        }
    
    
  4. 只绑定一次事件

    会在组件的容器上或者页面的body上绑定一次事件,以后组件内部的所有的事件操作都是基于这个事件代理外分发。具体的实现代码如下

        delegateEvents: function(events) {
            //默认通过参数传入,也可以通过配置属性传入
            events = events || this.get('events');
    
            if (!events) return this;
    
            //循环所有事件,并代理
            for (var key in events) {
                var method = events[key];
                if (!S.isFunction(method)) method = this[events[key]];
                if (!method) continue;
                var match = key.match(delegateEventSplitter);
    
                this.undelegate(match[1], match[2]);
                this.delegate(match[1], match[2], S.bind(method, this));
            }
            return this;
        }   
    
  5. 没有任何学习成本

    * 基于开发这都很熟悉的字符串模版
    * virtual dom的相关操作封装在所有组件的基类中,对开发者不透明
    

这里是源码文件http://g.tbcdn.cn/de/cicada/1.0.0/widget/base-widget/index.js,这篇文章其实是一篇对源码的解读。

最后我想说的是,我们数娱用到的ui组件开发模式,都不是最新的或者我们发明的[实际上大部分的框架也都是这样,没有发明什么新技术],我们做的只是把开发过程中的重复行为或者容易犯错误的地方封装在框架中,从根本上解决了开发人员的开发效率低,写的代码不易于维护和扩展的问题。

目录
相关文章
|
1天前
|
设计模式 前端开发
前端设计模式
前端设计模式
12 4
|
8天前
|
前端开发
前端web入门第四天】03 显示模式+综合案例热词与banner效果
本文档介绍了HTML中标签的三种显示模式:块级元素、行内元素与行内块元素,并详细解释了各自的特性和应用场景。块级元素独占一行,宽度默认为父级100%,可设置宽高;行内元素在同一行显示,尺寸由内容决定,设置宽高无效;行内块元素在同一行显示,尺寸由内容决定,可设置宽高。此外,还提供了两个综合案例,包括热词展示和banner效果实现,帮助读者更好地理解和应用这些显示模式。
|
30天前
|
设计模式 JavaScript 前端开发
Vue.js 组件设计模式:在前端热潮中找到归属感,打造可复用组件库,开启高效开发之旅!
【8月更文挑战第22天】Vue.js 以其高效构建单页应用著称,更可通过精良的组件设计打造可复用组件库。组件应职责单一、边界清晰,如一个显示文本并触发事件的按钮组件,通过 props 传递标签文本,利用插槽增强灵活性,允许父组件注入动态内容。结合 CSS 预处理器管理和封装独立模块,配以详尽文档,有效提升开发效率及代码可维护性。合理设计模式下,组件库既灵活又强大,持续实践可优化项目工作流。
40 1
|
1月前
|
JavaScript 算法 前端开发
"揭秘Vue.js的高效渲染秘诀:深度解析Diff算法如何让前端开发快人一步"
【8月更文挑战第20天】Vue.js是一款备受欢迎的前端框架,以其声明式的响应式数据绑定和组件化开发著称。在Vue中,Diff算法是核心之一,它高效计算虚拟DOM更新时所需的最小实际DOM变更,确保界面快速准确更新。算法通过比较新旧虚拟DOM树的同层级节点,递归检查子节点,并利用`key`属性优化列表更新。虽然存在局限性,如难以处理跨层级节点移动,但Diff算法仍是Vue高效更新机制的关键,帮助开发者构建高性能Web应用。
40 1
|
20天前
|
开发者 C# Android开发
明白吗?Xamarin与Native的终极对决:究竟哪种开发方式更适合您的项目需求,让我们一探究竟!
【8月更文挑战第31天】随着移动应用开发的普及,开发者面临多种技术选择。本文对比了跨平台解决方案Xamarin与原生开发方式的优势与劣势。Xamarin使用C#进行跨平台开发,代码复用率高,可大幅降低开发成本;但因基于抽象层,可能影响性能。原生开发则充分利用平台特性,提供最佳用户体验,但需维护多套代码库,增加工作量。开发者应根据项目需求、团队技能和预算综合考量,选择最适合的开发方式。
59 0
|
22天前
|
JavaScript 前端开发 开发者
决战前端之巅!Element UI与Vuetify谁才是Vue.js组件界的霸主?一场关于颜值与实力的较量!
【8月更文挑战第30天】本文对比了两款热门的Vue.js组件库——Element UI与Vuetify。Element UI由饿了么团队打造,提供多种高质量UI组件,设计简洁大方。Vuetify基于Material Design规范,支持Vue.js 2.0及3.0版本,具备前瞻性。两者均涵盖表单、导航、数据展示等组件,Element UI配置选项丰富,而Vuetify则提供了更深层的样式定制功能。开发者可根据项目需求及个人偏好选择合适的组件库。
68 0
|
30天前
|
前端开发 JavaScript 机器人
中后台前端开发问题之动态标注组件渲染到界面上如何解决
中后台前端开发问题之动态标注组件渲染到界面上如何解决
25 0
|
2月前
|
编解码 前端开发 UED
UI/UX设计在前端开发中的重要性
【7月更文挑战第27天】综上所述,UI/UX设计在前端开发中具有不可替代的重要性。它们不仅决定了产品的视觉呈现和交互体验,还影响了用户的满意度、品牌形象、转化率和技术创新等多个方面。因此,在前端开发过程中,我们应该高度重视UI/UX设计的作用和价值,与设计师紧密合作共同打造出优秀的产品。
|
2月前
|
前端开发 JavaScript 开发者
条件判断的模式问题之为什么不建议在前端日常业务开发中使用OOP的责任链模式实践
条件判断的模式问题之为什么不建议在前端日常业务开发中使用OOP的责任链模式实践
|
2月前
|
设计模式 编解码 API
Flutter UI设计模式与实现:深入探索与实践
【7月更文挑战第20天】Flutter以其独特的声明式UI模式和丰富的UI组件库,为移动应用开发提供了强大的支持。通过深入理解Flutter的UI设计模式和实现技巧,开发者可以构建出高性能、可维护性强的UI界面。同时,随着Flutter生态的不断完善和发展,相信未来Flutter将在移动应用开发领域发挥更加重要的作用。