该组件支持用户在具有路由功能的应用中(点击)导航,默认渲染成带有正确链接的<a>标签,可以通过tag属性生成别的标签。
它本质上是通过在生成的标签上绑定了click事件,然后执行对应的VueRouter实例的push()实现的,对于router-link组件来说,可以传入以下props:
- to 表示目标路由的链接,当被点击后,内部会立刻把to的值传到router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象
- tag router-link组件渲染的标签名,默认为a
- exact 布尔类型,“是否激活”默认类名的依据是包含匹配
- append 布尔类型,设置append属性后,则在当前(相对)路劲前添加基路劲
- replace 布尔类型,设置replace后,当点击时会调用router.replace()而不是router.push(),这样导航后不会留下history记录
- activeClass 链接激活时使用的CSS类名
- exactActiveClass 配置当链接被精确匹配的时候应该激活的 class
- event 声明可以用来触发导航的事件。可以是一个字符串或是一个包含字符串的数组
举个栗子:
writer by:大沙漠 QQ:22969969
<div id="app">
<router-link to="/info/1">详情页1</router-link>
<router-link to="/info/2" event="mouseover">详情页2</router-link>
<router-link to="/info/3" tag="p">详情页3</router-link>
<hr/>
<router-view></router-view>
</div>
<script>
const info = { template:'<div>id:{{this.$route.params.id}}</div>'}
const routes = [
{path:'/info/:id',component:info,name:'info'},
]
const app = new Vue({
el:'#app',
router:new VueRouter({routes})
})
</script>
渲染后的DOM如下:

可以看到第二个routerlink组件渲染成了p标签,我们点击时效果如下:

可以看到详情页3上并没有点击,鼠标移动上去,就会自动切换路由了,这是因为我们传入了event,在上面绑定了onmouseover事件。
router-link组件自定义了render函数,如下:
var Link = {
name: 'RouterLink',
props: { //可以传入的props
to: {
type: toTypes,
required: true
},
tag: {
type: String,
default: 'a'
},
exact: Boolean,
append: Boolean,
replace: Boolean,
activeClass: String,
exactActiveClass: String,
event: {
type: eventTypes,
default: 'click' //默认为click事件
}
},
render: function render (h) { //router-link组件对应的render函数 h等于大vue上的$createElement函数
var this$1 = this;
var router = this.$router; //获取$router实例
var current = this.$route; //当前的路由对象
var ref = router.resolve(this.to, current, this.append);
var location = ref.location; //要跳转的地址,是一个对象 ;例如:{_normalized: true, path: "/login", query: {…}, hash: ""}
var route = ref.route; //路由对象
var href = ref.href; //href属性
var classes = {}; //这段代码和linkActiveClass、linkExactActiveClass的配置有关
var globalActiveClass = router.options.linkActiveClass;
var globalExactActiveClass = router.options.linkExactActiveClass;
// Support global empty active class
var activeClassFallback = globalActiveClass == null
? 'router-link-active'
: globalActiveClass;
var exactActiveClassFallback = globalExactActiveClass == null
? 'router-link-exact-active'
: globalExactActiveClass;
var activeClass = this.activeClass == null
? activeClassFallback
: this.activeClass;
var exactActiveClass = this.exactActiveClass == null
? exactActiveClassFallback
: this.exactActiveClass;
var compareTarget = location.path
? createRoute(null, location, null, router)
: route;
classes[exactActiveClass] = isSameRoute(current, compareTarget);
classes[activeClass] = this.exact
? classes[exactActiveClass]
: isIncludedRoute(current, compareTarget);
var handler = function (e) { //绑定的事件
if (guardEvent(e)) { //先调用该函数过滤掉一些和导航无关的事件
if (this$1.replace) { //如果设置了replace属性
router.replace(location); //则执行router.replace切换导航
} else {
router.push(location); //否则执行router.push更新导航
}
}
};
var on = { click: guardEvent }; //<router-link>组件默认都支持的click事件,下面会重置的
if (Array.isArray(this.event)) {
this.event.forEach(function (e) { on[e] = handler; });
} else {
on[this.event] = handler;
}
var data = { //一般情况下,这里会重置on.click为handler
class: classes
};
if (this.tag === 'a') { //如果tag是一个a标签
data.on = on;
data.attrs = { href: href };
} else { //如果是其它标签
// find the first <a> child and apply listener and href
var a = findAnchor(this.$slots.default); //查找第一个<a>标签
if (a) { //如果找到了一个a标签
// in case the <a> is a static node
a.isStatic = false;
var aData = a.data = extend({}, a.data);
aData.on = on;
var aAttrs = a.data.attrs = extend({}, a.data.attrs);
aAttrs.href = href;
} else { //如果没有找到a标签
// doesn't have <a> child, apply listener to self
data.on = on; //则监听自身
}
}
return h(this.tag, data, this.$slots.default) //最后调用$createElement去创建该Vnode
}
}
如果是a标签,在guardEvent函数内会执行preventDefault()函数通知浏览器不要执行与事件相关的动作,所有的动作比如设置hash都是通过VueRouter的内置代码来实现。
来源:https://www.cnblogs.com/greatdesert/p/12463333.html