• Omi框架学习之旅


    先来看看官网的介绍吧:https://github.com/AlloyTeam/omi/tree/master/plugins/omi-router

    其实我推荐直接看官网的介绍。我所写的,主要给个人做的笔记。也许看的get不到点吧。所以强烈看官网

    文档:https://alloyteam.github.io/omi/website/docs-cn.html

    github: https://github.com/AlloyTeam/omi

    好了,该做笔记了。这次主要记录一下omi-router插件,关于路由,我想不用我多说,因为我也没怎么用其做个项目,实在惭愧。

    我的个人理解是:

    就是在同一个页面做多个页面的活。
    代码量可能多了(基本要用模块化了),但是可以共享一些公用的js代码,或者其他html,css。
    不同的组件可以根据hash值插入到指定dom中(omi是不同的组件然后实例化一个,然后omi.render一下就好了)。
    hash值可以无刷新前进和后退,这样就做到了页面高速渲染不同的内容,无需等待空白新页面.

    单页应用的好处可以直接看第一个链接。用过vue,react的我想都很清楚。只是我。。。

    先看下demo吧

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>router2</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
        <style type="text/css">
            * {
                margin: 0;
                padding: 0;
            } 
        </style>
    </head>
    <body>
        <div id="app"></div>
        
    
    
        <script type="text/javascript" src="./src/omi11.js"></script>
        <script>
            Omi.OmiFinger.init();
    
            class Home extends Omi.Component {
                constructor(data) {
                    super(data);
                }
    
                render() {
                    return     `
                        <div>
                            Home
                        </div>
                    `;
                }
            };
    
            Omi.tag('Home', Home);
    
            class About extends Omi.Component {
                constructor(data) {
                    super(data);
                }
    
                render() {
                    return     `
                        <div>
                            About
                        </div>
                    `;
                }
            };
    
            Omi.tag('About', About);
    
            class UserList extends Omi.Component {
                constructor(data) {
                    super(data);
                }
    
                render() {
    
                    return `
                        <ul>
                            <li>
                                <a omi-router to="/user/omi/category/html" href="">omi</a>
                            </li>
                            <li>
                                <a omi-router to="/user/dnt/category/css" href="">dnt</a>
                            </li>
                            <li>
                                <a omi-router to="/user/sorrowx/category/js" href="">sorrowx</a>
                            </li>
                        </ul>
                    `;
                }
            };
    
            Omi.tag('UserList', UserList);
    
            class User extends Omi.Component {
                constructor(data) {
                    super(data);
                }
    
                beforeRender() {
                    this.data.name = this.$store.$route.params.sName;
                    this.data.category = this.$store.$route.params.sType;
                    var info = this.queryInfo(this.data.name);
                    this.data.age = info.age;
                    this.data.sex = info.sex;
                }
    
                queryInfo(name) {
                    this.mockData = {
                        omi: {age: 1, sex: ''},
                        dnt: {age: 12, sex: ''},
                        sorrowx: {age: 13, sex: ''},
                    };
    
                    return this.mockData[name];
                }
    
                back() {
                    history.back();
                }
    
                render() {
                    return `
                        <div>
                            <button omi-finger tap="back">back</button>
                            <ul>
                                <li>name: {{name}}</li>
                                <li>age: {{age}}</li>
                                <li>sex: {{sex}}</li>
                                <li>category: {{category}}</li>
                            </ul>
                        </div>
                    `;
                }
            };
    
            Omi.tag('User', User);
    
            class App extends Omi.Component {
                constructor(data) {
                    super(data);
                }
    
                install() {
                    Omi.OmiRouter.init({
                        routes: [
                            { path: '/', component: Home },
                            { path: '/about', component: About },
                            { path: '/user-list', component: UserList },
                            { path: '/user/:sName/category/:sType', component: User }
                        ],
                        renderTo: "#view",
                        defaultRoute: '/about',    // 默认
                        root: this
                    });
                }
    
                style() {
                    return `
                        ul{
                            border-bottom: 1px solid #ccc;
                            padding-bottom:5px;
                        }
                        li{
                            display:inline-block;
                        }
                        ul li a {
                            text-decoration: none;
                        }
                        #view li{
                            display:block;
                        }
                        #view ul{
                            border- 0px;
                        }
                    `;
                }
    
                render() {
                    return `
                        <div>
                            <ul>
                                <li>
                                    <a omi-router to="/" href="">Home</a>
                                </li>
                                <li>
                                    <a omi-router to="/about" href="">About</a>
                                </li>
                                <li>
                                    <a omi-router to="/user-list" href="">用戶</a>
                                </li>
                            </ul>
                            <div id="view"></div>
                        </div>
                    `;
                }
            };
    
            var app = new App();
            Omi.render(app, '#app');
            
        </script>
    </body>
    </html>

    还是直接运行一把,看下结果吧,

    http://wx.indoorun.com/indoorun/wxtest/touch/router3.html#/user-list

    在手机上点击,或者浏览器f12进入模拟器查看,因为使用了tap事件。

    至于omi怎么实现的?

    答:我就大概的说一下其 实现原理吧,快下班了, 源码会贴在下面的。

    1. 入口: Omi.OmiRouter.init(option);

       option的参数如下: {

           routes:[{}, {}, {}...],    // {path:'路由映射的hash', component: '组件,需要实例化的组件然后渲染到指定dom'}

           renderTo: '#id',    // 渲染到哪个dom去啊,对吧

           defaultRoute: '默认路由hash',    // 打开链接时不同的用户看到的结果一样撒

           root: this    // 把组件实例顺便传进去

       }

    2. 当我们点击链接时,我们需要触发了,入口如下

                render() {
                    return `
                        <div>
                            <ul>
                                <li>
                                    <a omi-router to="/" href="">Home</a>
                                </li>
                                <li>
                                    <a omi-router to="/about" href="">About</a>
                                </li>
                                <li>
                                    <a omi-router to="/user-list" href="">用戶</a>
                                </li>
                            </ul>
                            <div id="view"></div>
                        </div>
                    `;
                }

    每个a标签都加了omi-router属性,说明被omi-router插件的一下这个方法注册了事件,代码如下

                Omi.extendPlugin('omi-router', function (dom, instance) {    // 给Omi.plugins 添加 omi-router 插件
                    dom.setAttribute('href', 'javascript:void(0)');
    
                    dom.addEventListener('click', function () {
                        hashMapping(dom.getAttribute('to'));
                    }, false);
                });

    里面的匿名函数,每当点击有omi-router属性的标签便会触发这个匿名函数。调用了这个关键的函数hashMapping(dom.getAttribute('to'));,代码如下

            function hashMapping(to) {    // to: 路径地址
                routerOption.routes.every(function (route) {    // route: 路由对象
                    var toArr = to.match(route.reg);    // to匹配route.reg正则返回匹配到的结果数组
                    if (toArr) {
                        var pathArr = route.path.match(route.reg);    // route.path匹配route.reg正则返回匹配到的结果数组
                        params = getParams(toArr, pathArr);
                        renderTo = route.renderTo || routerOption.renderTo;    // 渲染到哪去(显然每个路由对象也可以有renderTo属性)
                        store = route.store || routerOption.store;    // 数据存储
                        Component = route.component;    // route的组件
                        pushState(to);
                        return false;    // 只有匹配到结果后到达这里就跳出函数啦
                    };
                    return true;    // 否则继续遍历
                });
            };

    to: 路径地址指的是标签中的to属性的值,然后和配置选项中的routes数组,进行对比。主要获取store,Component,params的数值,然后pushState()方法会改变浏览器

    中的url地址,当然也给window注册了一个hashchange事件,所以当url改变时,会触发该事件,如下

            window.addEventListener('hashchange', function() {    // hashchange事件, url改变就触发
                hashMapping(window.location.hash.replace('#',''), renderTo);
                render();
            }, false);

    这里的render()方法比较重要哦,组件实例化,和渲染都在里面执行,如果已经有了对应的实例,还得从omi的instances删掉,在重新实例化一个,代码如下

            function render(){
                if(store){
                    store.$route = { };
                    store.$route.params = params;
                }else{
                    store = {
                        methods:{
                            install: function() {
                                this.$route = { };
                                this.$route.params = params;
                            }
                        }
                    };
                };
                if(preRenderTo === renderTo&&preInstance){
                    deleteInstance(preInstance);
                };
                var instance = new Component();    // 组件类
                Omi.render(instance, renderTo, {
                    store: store
                });
                preInstance = instance;
                preRenderTo = renderTo;
            };

    从omi的instances移除实例的代码如下:

            function deleteInstance(instance) {    // 删除存在的实例
                for (var key in Omi.instances) {
                    if(Omi.instances.hasOwnProperty(key)){
                        Omi.instances[key].id = instance.id;
                        delete  Omi.instances[key];
                        instance = null;
                        break;
                    };
                };
            };

    主要代码基本讲完了。

    ps:

    路由demo实战源码:https://github.com/SorrowX/resume_demo

    demo效果: https://sorrowx.github.io/resume_demo/

  • 相关阅读:
    依赖注入
    Java实现一个字符串的反转
    LRU缓存介绍与实现 (Java)
    Java中HashMap遍历的两种方法(转)
    java中判断字符串是否为只包含数字
    LeakCanary 的使用遇到的弯路
    转: BAT等研发团队的技术博客
    转: android 内存检测工具 LeakCanary 说明
    转:安桌开发开源库的推荐1
    转: 技术牛人博客
  • 原文地址:https://www.cnblogs.com/sorrowx/p/6690123.html
Copyright © 2020-2023  润新知