先来看看官网的介绍吧: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-width: 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/

Omi框架学习之旅 - 插件机制之omi-router及原理说明的更多相关文章

  1. Omi框架学习之旅 - 插件机制之omi-finger 及原理说明

    以前那篇我写的alloyfinger源码解读那篇帖子,就说过这是一个很好用的手势库,hammer能做的,他都能做到, 而且源码只有350来行代码,很容易看懂. 那么怎么把这么好的库作为omi库的一个插 ...

  2. Omi框架学习之旅 - 插件机制之omi-touch 及原理说明

    这个插件也能做好多好多的事,比如上拉下拉加载数据,轮播,等一切和运动有关的特效. 具体看我的allowTouch这篇博客,掌握了其用法,在来看它是怎么和omi结合的.就会很简单. 当然使用起来也比较方 ...

  3. Omi框架学习之旅 - 插件机制之omi-transform及原理说明

    给omi-transform插件做个笔记,使用起来也很爽. transform.js这个库,一直想写一篇帖子的,可是,数学不好,三维矩阵和二位矩阵理解的不好,所以迟迟没写了, 这也是一个神库,反正我很 ...

  4. Omi框架学习之旅 - 之开篇扯蛋

    说实话, 我也不知道Omi是干啥的, 只因此框架是alloyTeam出的, dntzhang写的, 也有其他腾讯大神参与了, 还有一些其他贡献者, 以上我也不太清楚, 当我胡说八嘎. 因其写法有人说好 ...

  5. Omi框架学习之旅 - Hello World 及原理说明

    学什么东西都从hello world开始, 我也不知道为啥. 恩,先上demo代码, 然后提出问题, 之后解答问题, 最后源码说明. hello world - demo: class Hello e ...

  6. Omi框架学习之旅 - 获取DOM节点 及原理说明

    虽然绝大部分情况下,开发者不需要去查找获取DOM,但是还是有需要获取DOM的场景,所以Omi提供了方便获取DOM节点的方式. 这是官网的话,但是我一直都需要获取dom,对dom操作,所以omi提供的获 ...

  7. Omi框架学习之旅 - 生命周期 及原理说明

    生命周期 name avatars company constructor 构造函数 new的时候 install 初始化安装,这可以拿到用户传进的data进行处理 实例化 installed 安装完 ...

  8. Omi框架学习之旅 - 通过omi-id来实现组件通讯 及原理说明

    这个demo是通过omi-id来获取子类的实例,然后更改data属性,之后updata一下就好了. 老规矩:先上demo代码, 然后提出问题, 之后解答问题, 最后源码说明. class Hello ...

  9. Omi框架学习之旅 - 通过对象实例来实现组件通讯 及原理说明

    组件通讯不是讲完了吗(上帝模式还没讲哈),怎么又多了种方式啊. 你484傻,多一种选择不好吗? 其实这个不属于组件通讯啦,只是当父组件实例安装和渲染完毕后,可以执行installed这个方法(默认是空 ...

随机推荐

  1. linux下安装mysql环境

    1.在安装apache的时候已经检查了本地没有安装centos自带的mysql,有的话一定要卸载掉,否则可能占用端口 2.准备mysql安装包(注意编译的时候,mysql5.5版本以上的编译和5.5一 ...

  2. linux -bash . startup.sh Permission denied

    在执行./startup.sh,或者./shutdown.sh的时候,爆出了Permission denied, 其实很简单,就是今天在执行tomcat的时候,用户没有权限,而导致无法执行, 用命令c ...

  3. 通过webpack2从0开始配置自己的vue项目 1

    PS 阅读者需要node基础.webpack原理知识.vue基础 安装node 这个网上很多教程 打开终端 创建项目 npm init 全局安装: cnpm i webpack webpack-dev ...

  4. ionic 项目签名

    一.ionic 自动签名的好处与坏处(ionic build android/ios)  好处在于:可以直接安装手机上进行安装测试,也可以上传Android或者iOS平台 不好的地方在于:你的电脑环境 ...

  5. 安卓开发之ScrollView

    当界面不足以将所有的内容显示出来的时候便导致下面的部分内容无法显示出来 所有加上ScrollView 来讲要显示的内容放入之中便可以实现上下滚动界面内容 但是当要显示多个控件的时候会出错  原因是Sc ...

  6. Android中使用progurad混淆代码

    第一步,取消project.properties中关于progurad的注释,开启progurad,默认的配置文件会被加载进来. proguard.config=${sdk.dir}/tools/pr ...

  7. springboot 学习之路 20 (整合RabbitMQ)

    整合RabbitMQ: 我的操作系统是window7 ,所以在整合ribbotMQ之前需要先安装rabbitMq服务:安装步骤请参考:window下安装RabbitMQ  这个详细介绍了安装步骤,请按 ...

  8. JavaScript大杂烩4 - 理解JavaScript对象的继承机制

    JavaScript是单根的完全面向对象的语言 JavaScript是单根的面向对象语言,它只有单一的根Object,所有的其他对象都是直接或者间接的从Object对象继承.而在JavaScript的 ...

  9. 自己搭建anki同步服务器

    最近帮孩子找学习的软件,发现了anki 不过同步速度太慢,但发现可以自己搭建同步服务器 具体方法见https://github.com/dsnopek/anki-sync-server 我的安装过程如 ...

  10. 转 让Python在Android系统上飞一会儿

    让Python在Android系统上飞一会儿 地址: http://blog.csdn.net/ccwwff/article/details/6208260