美文网首页【vue-rouer源码】
【vue-router源码】十三、RouterLink源码分析

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

作者: MAXLZ | 来源:发表于2022-06-14 15:39 被阅读0次

    前言

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

    相关文章

      网友评论

        本文标题:【vue-router源码】十三、RouterLink源码分析

        本文链接:https://www.haomeiwen.com/subject/cvyzmrtx.html