上文说到router-view和router-link。这块就重点说下router-view, router-link就不说了
router-view和router-link都是全局组件,routerView的代码如下
// 这里是router-view的组件
// router-view 用函数式组件写,特点:没有this 没有状态
export default {
functional: true, // 函数式组件的标志。必须要有这个
/*
data(){ -- 函数式组件没有data这个玩应
return {}
}
*/
render(h,context){
// console.log(this) -- 函数式组件中没有this这玩应...
/*
context
可以理解为router-view的this(和正常的.vue的组件中的this类似)或者理解为就是router-view
注意!!!
为啥要写 let parent = context.parent 呢?
因为context 不可以像 context.$route 调用vue原型/实例上的属性,只能通过context.parent
找到router-view 父组件, router-view父组件就是正常的.vue的组件。
每一个.vue这种组件都是一个vue实例。这个需要特别清楚下,所以这样就可以调用vue原型/实例上的
属性
*/
let parent = context.parent;// context.parent 为 router-view的父组件
/* 这个之前在install.js中全局定义过,
$route 值:{path: '/a/b', matched:[abouta组件, aboutb组件]}
就是 baseClass.js 中 this.current的值
*/
let route = parent.$route;
let matched = route.matched;
/*
context.data 是绑定在router-view上的数据
例如:
<router-view a=1></router-view>
a=1就在router-view的data中
类似这种写法
data = {
attr:{
a:1
}
}
*/
let data = context.data;
data.routerView = true; // <router-view routerView = true></router-view> 相当于在router-view添加了一个自定义属性
/* 渲染 matched {path: '/a/b', matched:[abouta组件, aboutb组件]}
第一个router-view渲染abouta组件
第二个router-view 渲染aboutb组件
*/
let depth = 0;
console.log('parent.$vnode')
console.log(parent.$vnode)
console.log(depth)
while(parent){
// $vnode 是虚拟节点
if(parent.$vnode && parent.$vnode.data.routerView){
console.log(parent.$vnode.data.routerView)
depth++;
}
parent = parent.$parent;
}
let record = matched[depth];
// 从matched中没有取到组件
if(!record){
return h(); // 什么也不渲染
}
let component = record.component;
return h(component,data);
}
}
在install.js中注册一个全局组件。router-view就可以用了
现在我想重点讲routerView.js中其中一段代码:我觉得蛮重要的
这段代码大家可能有点陌生,parent.$vnode是啥意思?
我举个例子:地址栏中地址为:localhost:8080/#/a/b/c