• 前端框架撸起来——组件和路由


    框架只有一个html文件,html中只有一个id是app的div,如何点击一个按钮或者菜单来显示对应的页面呢?最初大家都是通过拼接html字符串,然后再绑定,这样写很不优雅,当系统功能模块庞大时,这样下来难以维护。如何实现模块化以及写出优雅的代码,接下来就是组件和路由的事情。

    组件(Component)

    组件是庞大系统的一个个小的零件,组件可以进行嵌套。系统有多个页面构成,页面有多个部件组成,页面和部件都可以称之为组件,他们都有共同的属性和方法。本框架我们约定组件有render、mounted、destroy三个方法。

    1)组件的定义

    function TestPage() {
        //这里写组件的私有变量、共有属性和方法、私有方法
        var component1 = new Component1();//私有变量component1
        var timer;//计时器
    }
    

    2)呈现方法(render)

    //这里是呈现TestPage组件的方法
    //dom是根节点app,也可以是其他页面中的节点
    this.render = function(dom) {
        $('<div>').html('Component1').appendTo(dom);//呈现一个div
        component1.render(dom);//呈现嵌套组件component1
    }
    

    3)挂载方法(mounted)

    //这里是加载组件的后端接口数据
    this.mounted = function() {
        component1.loadData();
        timer = setInterval(function() {...}, 1000);
    }
    

    4)销毁方法(destroy)

    //这里是销毁组件的资源,例如一个setInterval的对象
    this.destroy = function() {
        clearInterval(timer);
    }
    

    5)组件完整代码

    function TestPage() {
        var component1 = new Component1();
        var timer;
        
        this.render = function(dom) {
            $('<div>').html('Component1').appendTo(dom);
            component1.render(dom);
        }
        
        this.mounted = function() {
            component1.loadData();
            timer = setInterval(function() {...}, 1000);
        }
        
        this.destroy = function() {
            clearInterval(timer);
        }
    }
    

    路由(Router)

    路由是不同组件之前的转换器,起到组件自由切换的作用。路由可以进行嵌套,即页面是最顶级的组件,渲染在根节点下面,页面内部区块也可以呈现不同的组件。本框架路由只提供两个方法,即导航和回退,其实路由可以扩展更多的方法,如根据name或者模板来路由,这里暂不实现。本框架暂不支持浏览器地址路由,有兴趣的同学可以自己实现。

    1)路由的定义

    //elem是路由的节点对象
    //option是路由的配置选项
    function Router(elem, option) {
        //这里写路由的私有变量、共有属性和方法、私有方法
        var _current = {};//存储当前路由对象
    }
    

    2)导航方法(route)

    //路由到指定的组件
    //item为路由对象,必须包含component属性
    this.route = function(item) {
        //呈现前的验证,例如登录验证
        if (!_option.before(item))
            return;
        //销毁当前组件
        _destroyComponent();
        //设置当前组件
        _setCurrent(item);
        //执行组件
        var component = item.component;
        if (component) {
            _renderComponent(component);
            _mountComponent(item, component);
        }
    }
    

    3)回退方法(back)

    //回退到当前路由的上一个路由
    this.back = function() {
        _this.route(_current.previous);
    }
    

    4)路由完整代码

    function Router(elem, option) {
        //fields
        var _option = option || {},
            _elem = elem,
            _current = {},
            _this = this;
    
        //methods
        this.route = function (item) {
            if (!_option.before(item))
                return;
    
            _destroyComponent();
            _setCurrent(item);
    
            var component = item.component;
            if (component) {
                _renderComponent(component);
                _mountComponent(item, component);
            }
        }
    
        this.back = function () {
            _this.route(_current.previous);
        }
        
        //private
        function _destroyComponent() {
            var currComp = _current.component;
            currComp && currComp.destroy && currComp.destroy();
        }
        
        function _setCurrent(item) {
            if (!item.previous) {
                item.previous = _current; //存储上一个路由
            }
            _current = item;
        }
        
        function _renderComponent(component) {
            if (typeof component === 'string') {
                _elem.html(component);//字符串组件
            } else {
                _elem.html('');//清空节点
                component.render(_elem);//呈现组件
            }
        }
        
        function _mountComponent(item, component) {
            setTimeout(function () {
                _option.after && _option.after(item);//呈现后回调公共逻辑
                component.mounted && component.mounted();//调用后台数据
            }, 10);//延时执行,等dom呈现完成后
        }
    }
    

    下一章我们实现框架根组件App。

    Gitee: https://gitee.com/known/kui
    Github: https://github.com/known/kui

  • 相关阅读:
    c++类中比较重要的几个函数
    rosbag使用方法
    2.urllib库的使用
    什么叫做API?
    1.爬虫基础
    正则表达式

    time模块
    random模块
    日志处理
  • 原文地址:https://www.cnblogs.com/known/p/15595337.html
Copyright © 2020-2023  润新知