该组件支持用户在具有路由功能的应用中(点击)导航,默认渲染成带有正确链接的标签,可以通过tag属性生成别的标签。
它本质上是通过在生成的标签上绑定了click事件,然后执行对应的VueRouter实例的push()实现的,对于router-link组件来说,可以传入以下props:
举个栗子:
writer by:大沙漠 QQ:22969969
<div id="app"><router-link to="/info/1">详情页1router-link> <router-link to="/info/2" event="mouseover">详情页2router-link> <router-link to="/info/3" tag="p">详情页3router-link> <hr/><router-view>router-view>div><script> const info = { template:'id:{{this.$route.params.id}}'} 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 classvar 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 }; //组件默认都支持的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 child and apply listener and href var a = findAnchor(this.$slots.default); //查找第一个标签 if (a) { //如果找到了一个a标签// in case the is a static nodea.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 child, apply listener to selfdata.on = on; //则监听自身 } }return h(this.tag, data, this.$slots.default) //最后调用$createElement去创建该Vnode } }
如果是a标签,在guardEvent函数内会执行preventDefault()函数通知浏览器不要执行与事件相关的动作,所有的动作比如设置hash都是通过VueRouter的内置代码来实现。
Copyright © 2004-2024 Ynicp.com 版权所有 法律顾问:建纬(昆明)律师事务所 昆明市网翼通科技有限公司 滇ICP备08002592号-4