前言
moon-router是Moon提供的路由工具,Moon官网对于moon-router的功能有相关的说明,虽然比起vue-router还差很多,但是基本的路由功能还是实现了,本文旨在分析moon-router的处理逻辑以及组件化加载的实现。
具体分析
还是通过moon实例结合moon-router来分析,具体的实例代码如下:
// script.js
const Moon = require("moonjs");
const store = require('./store').store;
const router = require('./router').router;
const mn = new Moon({
el: "#app",
template: `<div id="app"><router-view></router-view></div>`,
store: store,
router: router,
hooks: {
mounted() {
router.install(this);
}
}
});
// router.js
const Router = require("moon-router");
const Moon = require("moonjs");
// 创建组件header
require('./components/header.moon')(Moon);
Moon.use(Router);
const router = new Router({
map: {
'/': 'header'
}
});
exports.router = router;
实例效果:
在具体分析其处理逻辑之前,需要说明的有下面几点:
- moon项目中创建组件的形式:require(组件)(Moon)
- moon项目中不支持ES6的import机制,请使用CommonJs的模块机制
- router需要调下install方法,该方法就是设置instance属性的值
首先看看上面生成的router实例的对象组成:
moon-router的结构组成如下:
MoonRouter构造函数的处理逻辑如下:
可以从上面的处理逻辑中看出,主要的处理就是map函数以及run函数的处理。
map
run
该函数的功能是处理路由中params以及query,并调用Moon实例的build函数,主要的处理情况如下:
- /:named
- /*
- /hello?key=value
Moon官网对于路由这边也有简要的说明,具体如下:
run函数中主要的功能就两点:处理参数、调用Moon实例build函数,Moon实例build函数是创建虚拟DOM并处理转换浏览器DOM的过程。
整个路由功能的实现通过router-view组件以及router-link,而在MoonRouter构造函数中会调用Moon.component构建router-view以及router-link组件,它们内部都会调用m函数,而m函数的作用就是构建虚拟DOM相关。
下面是router-view相关主要代码:
MoonRouter.Moon.component("router-view", {
functional: true,
render: function(m) {
return m(self.current.component,
{attrs: {route: self.route}}, {shouldRender: true}, []);
}
});
可以看出router-view构建的始终是当前路由对应的组件,而不同路由的视图切换确是要通过onhashchange事件来处理的,具体代码如下:
window.onhashchange = function() {
run(self,
window.location.hash.slice(1) || window.location.pathname);
}
当窗口hash变化就会调用回调函数run,在run中处理参数并设置当前路由组件的值,之后会调动Moon实例的build函数从而实现路由切换。
总结
Moon-router实现路由切换:Moon实例build函数 + onhashchange事件 + router-view组件构建m函数的处理(传入当前路由组件)。