当前位置: 代码迷 >> 综合 >> vue-router实现路由变更监听
  详细解决方案

vue-router实现路由变更监听

热度:25   发布时间:2024-02-08 08:24:24.0

用户点击链接元素:

户点击链接交互,即点击了 <router-link>

props: {tag: {type: String,default: 'a'},  // 绑定的事件event: {type: eventTypes,default: 'click'}},render (h: Function) {const handler = e => {if (guardEvent(e)) {if (this.replace) {router.replace(location)} else {router.push(location)}}}const on = { click: guardEvent }if (Array.isArray(this.event)) {this.event.forEach(e => { on[e] = handler })} else { // 事件绑定处理函数on[this.event] = handler} return h(this.tag, data, this.$slots.default)   }

该组件主要是通过render函数,默认创建一个a标签,同时为标签绑定click事件

在绑定事件的函数中,值得注意guardEvent执行操作:

function guardEvent (e) { // 忽略带有功能键的点击if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) return
  // 调用preventDefault时不重定向if (e.defaultPrevented) return // 忽略右击if (e.button !== undefined && e.button !== 0) return // 如果 `target="_blank"` 也不进行if (e.currentTarget && e.currentTarget.getAttribute) {const target = e.currentTarget.getAttribute('target')if (/\b_blank\b/i.test(target)) return}// 判断是否存在`e.preventDefault`,在 weex 中没有这个方法if (e.preventDefault) {e.preventDefault()}return true
}

可以看到,这里主要对是否跳转进行了一些判断。再看看点击事件的处理函数:

const handler = e => {if (guardEvent(e)) {if (this.replace) {router.replace(location)} else {router.push(location)}}
}

可以看到其实他们只是代理而已,真正做事情的还是 history 来做:

浏览器本身的跳转动作

对于这种情况,先来看 hash的方式,当发生变得时候会判断当前浏览器环境是否支持 supportsPushState 来选择监听 popstate还是hashchange

window.addEventListener(supportsPushState ? 'popstate' : 'hashchange', () => {const current = this.currentif (!ensureSlash()) {return}this.transitionTo(getHash(), route => {if (supportsScroll) {handleScroll(this.router, route, current, true)}if (!supportsPushState) {replaceHash(route.fullPath)}})
})

对应的history其实也是差不多。只不顾既然是history模式了,默认也就只用监听popstate

window.addEventListener('popstate', e => {const current = this.currentconst location = getLocation(this.base)if (this.current === START && location === initLocation) {return}this.transitionTo(location, route => {if (supportsScroll) {handleScroll(router, route, current, true)}})
})
  相关解决方案