Open
Description
手写Vue-router核心原理,再也不怕面试官问我Vue-router原理
如何开发 Vue 插件?
Vue.use( plugin ) 注册插件
//引自官方api
Vue.use( plugin )
参数:
{Object | Function} plugin
用法:
安装 Vue.js 插件。如果插件是一个对象,必须提供 install 方法。
如果插件是一个函数,它会被作为 install 方法。
install 方法调用时,会将 Vue 作为参数传入。
该方法需要在调用 new Vue() 之前被调用。
当 install 方法被同一个插件多次调用,插件将只会被安装一次。
然后我们可以在我们的项目中进行应用。
vue-router原理
大体步骤:
1.根据mode通过hashChange事件或者popState事件得到 链接变化 (即跳转)
2.上述的变化变量设置成响应式
3.通过routesMap映射,得到 链接变化 映射的组件,使用h(routesMap[链接变化])重新渲染即达到目的。
//myVueRouter.js
let Vue = null;
class HistoryRoute {
constructor(){
this.current = null
}
}
class VueRouter{
constructor(options) {
this.mode = options.mode || "hash"
this.routes = options.routes || [] //你传递的这个路由是一个数组表
this.routesMap = this.createMap(this.routes)
this.history = new HistoryRoute();
this.init()
}
init(){
if (this.mode === "hash"){
// 先判断用户打开时有没有hash值,没有的话跳转到#/
location.hash? '':location.hash = "/";
window.addEventListener("load",()=>{
this.history.current = location.hash.slice(1)
})
window.addEventListener("hashchange",()=>{
this.history.current = location.hash.slice(1)
})
} else{
location.pathname? '':location.pathname = "/";
window.addEventListener('load',()=>{
this.history.current = location.pathname
})
window.addEventListener("popstate",()=>{
this.history.current = location.pathname
})
}
}
createMap(routes){
return routes.reduce((pre,current)=>{
pre[current.path] = current.component
return pre;
},{})
}
}
VueRouter.install = function (v) {
Vue = v;
Vue.mixin({
beforeCreate(){
if (this.$options && this.$options.router){ // 如果是根组件
this._root = this; //把当前实例挂载到_root上
this._router = this.$options.router;
Vue.util.defineReactive(this,"xxx",this._router.history)
}else { //如果是子组件
this._root= this.$parent && this.$parent._root
}
Object.defineProperty(this,'$router',{
get(){
return this._root._router
}
});
Object.defineProperty(this,'$route',{
get(){
return this._root._router.history.current
}
})
}
})
Vue.component('router-link',{
props:{
to:String
},
render(h){
let mode = this._self._root._router.mode;
let to = mode === "hash"?"#"+this.to:this.to
return h('a',{attrs:{href:to}},this.$slots.default)
}
})
Vue.component('router-view',{
render(h){
let current = this._self._root._router.history.current
let routeMap = this._self._root._router.routesMap;
return h(routeMap[current])
}
})
};
export default VueRouter
相关
Metadata
Metadata
Assignees
Labels
No labels