You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
constdata: any={class: classes}if(this.tag==='a'){data.on=ondata.attrs={ href }}else{// find the first <a> child and apply listener and hrefconsta=findAnchor(this.$slots.default)if(a){constaData=a.data||(a.data={})aData.on=onconstaAttrs=aData.attrs||(aData.attrs={})aAttrs.href=href}else{// doesn't have <a> child, apply listener to selfdata.on=on}}
这里有一个判断,如果 tag 不是 <a> 标签的话,就会递归使用 findAnchor 函数去找 slots 里面的 <a> 标签。最后还是没有的话,就只能给 router-link 自己赋值 on 点击事件。
开头
最后来了解了解 vue-router 的两个组件
<router-link>
和<router-view>
。这两个组件的使用方式如下:
在打开源码之前,先来简单思考一下,组件可以怎样去实现。
<router-link>
可以是一个<a>
标签,to 是它的 props,然后绑定一个点击事件。还记得 编程式的导航 吗?在之前的源码中,我们也看到 this.history 实现了 push、replace 等方法,通过点击触发这些方法即可触发路由的改变。
路由的改变,会修改到
this.$route
,利用 Vue 的响应式,在<router-view>
里使用到this.$route
,便能够及时的获取到相应的组件并渲染出来。这只是最简单的猜想,实现实现的代码远比上面的要复杂得多。下面就来真正的看看它们的具体实现吧。
router-link
router-link
组件的写法是 渲染函数 的写法。主要实现了几块功能:
router-link
的大体框架是这样的:render 里就是实现的几块功能。
定义正确的跳转 url
最后得到 href 作为
<a>
标签的跳转属性,具体细节不展开了。定义切换的高亮样式
这里可以看到,高亮样式默认就是 'router-link-active'。
定义点击事件
点击事件里其实就是调用触发 router 的 push 或 replace,跟编程式导航类似。
设置 data 对象
这里有一个判断,如果 tag 不是
<a>
标签的话,就会递归使用findAnchor
函数去找 slots 里面的<a>
标签。最后还是没有的话,就只能给 router-link 自己赋值 on 点击事件。最后,将 createElement 函数返回,即完成
router-link
组件的实现。router-view
router-view
是一个 函数式组件,专门只做渲染的工作。最主要就是找到要显示的组件,期间会优先取已经缓存的组件,其次是取嵌套了的组件。
router-view
的大体框架是这样的:路由触发
其中使用到了 $route。
回到 install,当时使用了 Vue 将 $route 进行了响应式处理:
然后还记得路由初始化时的监听:
一旦修改了 _route,即修改到了 $route,也会同时触发到
route-view
的 render,从而实现了路由的跳转(即路由的切换)。嵌套路由处理
route-view
通过 depth 和 route.matched 来找到嵌套的路由,从而实现嵌套路由的渲染。keep-alive 处理
使用到了 keep-alive,那就会有 cache 缓存,那么组件就直接用缓存的即可。
最后,找到对应的要渲染的组件,将 createElement 函数返回,即完成
router-view
组件的实现。最后
以上只是简略得对
<router-link>
和<route-view>
的解读,想更加深入了解代码实现,可以移动到 vue-router源码分析-整体流程。至此,vue-router 的源码解读告一段落,鼓掌。
The text was updated successfully, but these errors were encountered: