前言

【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}