共计 1829 个字符,预计需要花费 5 分钟才能阅读完成。
前言
【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
}
正文完