實現(xiàn)一個vue插件步驟
//1.定義一個類
class VuePlugin{
}
//2.實現(xiàn)類的靜態(tài)方法install Vue.use的時候會調用靜態(tài)方法,并傳入Vue
VuePlugin.install = function(Vue){
}
//3.暴露類
export default VuePlugin;
實現(xiàn)一個vueRouter
- 實現(xiàn)組件router-link
- 實現(xiàn)組件router-view
- 實現(xiàn)插件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存儲一個數(shù)組,里面放著要渲染組件相關的按照層級順序的route對象,比如[{path:"/about",component:About組件,children:[...省略]},{path:"/about/info",component:Info組件}]
//注意:matched必須是響應式的,否則當matched改變的時候router-view的render函數(shù)不會重新觸發(fā)。
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函數(shù),三個參數(shù):tag標簽、屬性、子元素集合
// return h("a", { attrs: { href: "#" + this.to } }, [this.$slots.default]);
//jsx方式
return <a href={'#'+this.to}>{this.$slots.default}</a>
},
};
大功告成可以測試了