【vue-router源码】十三、RouterLink源码分析

【vue-rouer源码】系列文章

  1. 【vue-router源码】一、router.install解析
  2. 【vue-router源码】二、createWebHistory、createWebHashHistory、createMemoryHistory源码解析
  3. 【vue-router源码】三、理解Vue-router中的Matcher
  4. 【vue-router源码】四、createRouter源码解析
  5. 【vue-router源码】五、router.addRoute、router.removeRoute、router.hasRoute、router.getRoutes源码分析
  6. 【vue-router源码】六、router.resolve源码解析
  7. 【vue-router源码】七、router.push、router.replace源码解析
  8. 【vue-router源码】八、router.go、router.back、router.forward源码解析
  9. 【vue-router源码】九、全局导航守卫的实现
  10. 【vue-router源码】十、isReady源码解析
  11. 【vue-router源码】十一、onBeforeRouteLeave、onBeforeRouteUpdate源码分析
  12. 【vue-router源码】十二、useRoute、useRouter、useLink源码分析
  13. 【vue-router源码】十三、RouterLink源码分析
  14. 【vue-router源码】十四、RouterView源码分析


前言

【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
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MAXLZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值