实现一个vue插件步骤
//1.定义一个类
class VuePlugin{
}
//2.实现类的静态方法install Vue.use的时候会调用静态方法,并传入Vue
VuePlugin.install = function(Vue){
}
//3.暴露类
export default VuePlugin;
实现一个vueRouter
- 实现组件router-link
- 实现组件router-view
- 实现插件MyRouter
// MyRouter.js
import Link from "@/components/KRouterLink";
import View from "@/components/KRouterView";
let Vue;
class MyRouter{
constructor(options){
this.$options = options;
window.addEventListener("hashchange",this.onHashChange.bind(this,"hashchange"))
window.addEventListener("load",this.onHashChange.bind(this,"load"))
//matched存储一个数组,里面放着要渲染组件相关的按照层级顺序的route对象,比如[{path:"/about",component:About组件,children:[...省略]},{path:"/about/info",component:Info组件}]
//注意:matched必须是响应式的,否则当matched改变的时候router-view的render函数不会重新触发。
Vue.util.defineReactive(this,"matched",[]);
}
onHashChange(eventType){
this.matched = [];
this.match()
}
match(routes){
routes = routes || this.$options.routes;
let current = location.hash.slice(1);
for(const route of routes){
if(current==="/" && route.path==="/"){
this.matched.push(route);
return;
}
//about/info
if(current!=="/" && current.includes(route.path)){
this.matched.push(route);
if(route.children){
this.match(route.children);
}
return;
}
}
}
}
MyRouter.install = function(_Vue){
Vue = _Vue;
//挂载$router到Vue的原型上
//怎么获取根实例的router配置呢,此时还没有生成根实例呢。
//利用全局混入
Vue.mixins({
beforeCreate(){
if(this.$options.router){
Vue.prototype.$router = this.$options.router;
}
}
});
//全局注册组件
Vue.component("router-link",Link)
Vue.component("router-view",View)
}
export MyRouter;
//router-view组件
export default {
render(h) {
//标明当前组件是router-view
this.$vnode.data.routerView = true;
//记录深度
let depth = 0;
let parent = this.$parent;
while (parent) {
if (
parent.$vnode &&
parent.$vnode.data &&
parent.$vnode.data.routerView
) {
depth++;
}
parent = parent.$parent;
}
//组件配置对象
let comp = null;
const route = this.$router.matched[depth];
if (route) {
comp = route.component;
}
return h(comp);
},
};
//router-link组件
export default {
//接收to路径
props: {
to: {
type:String,
required:true
},
},
render(h) {
//createElement函数,三个参数:tag标签、属性、子元素集合
// return h("a", { attrs: { href: "#" + this.to } }, [this.$slots.default]);
//jsx方式
return <a href={'#'+this.to}>{this.$slots.default}</a>
},
};
大功告成可以测试了