前言
【vue-router源码】系列文章将带你从0开始理解vue-router
的具体实现。该系列文章源码参考vue-router v4.0.15
。
源码地址:https://github.com/vuejs/router
浏览该文章的前提是你最好理解vue-router
的根本应用,如果你没有应用过的话,可通过vue-router官网学习下。
该篇文章将剖析RouterLink
组件的实现。
应用
<RouterLink to="/inex" reaplace custom activeClass="active" exactActiveClass="exact-active" ariaCurrentValue="page">To Index Page</RouterLink>
RouterLink
export const RouterLinkImpl = /*#__PURE__*/ defineComponent({ name: 'RouterLink', props: { // 指标路由的链接 to: { type: [String, Object] as PropType<RouteLocationRaw>, required: true, }, // 决定是否调用router.push()还是router.replace() replace: Boolean, // 链接被激活时,用于渲染a标签的class activeClass: String, // inactiveClass: String, // 链接精准激活时,用于渲染a标签的class exactActiveClass: String, // 是否不应该将内容包裹在<a/>标签中 custom: Boolean, // 传递给aria-current属性的值。https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current ariaCurrentValue: { type: String as PropType<RouterLinkProps['ariaCurrentValue']>, default: 'page', }, }, useLink, setup(props, { slots }) { // 应用useLink创立router-link所需的一些属性和行为 const link = reactive(useLink(props)) // createRouter时传入的options const { options } = inject(routerKey)! // class对象 const elClass = computed(() => ({ [getLinkClass( props.activeClass, options.linkActiveClass, 'router-link-active' )]: link.isActive, // 被激活时的class [getLinkClass( props.exactActiveClass, options.linkExactActiveClass, 'router-link-exact-active' )]: link.isExactActive, // 被精准激活的class })) return () => { // 默认插槽 const children = slots.default && slots.default(link) // 如果设置了props.custom,间接显示chldren,反之须要应用a标签包裹 return props.custom ? children : h( 'a', { 'aria-current': link.isExactActive ? props.ariaCurrentValue : null, href: link.href, onClick: link.navigate, class: elClass.value, }, children ) } },})export const RouterLink = RouterLinkImpl as unknown as { new (): { $props: AllowedComponentProps & ComponentCustomProps & VNodeProps & RouterLinkProps $slots: { default: (arg: UnwrapRef<ReturnType<typeof useLink>>) => VNode[] } } useLink: typeof useLink}