微信公众号: [大前端驿站]
关注大前端驿站。问题或建议,欢迎公众号留言。 这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战
Vue Router是Vue官方的路由管理器。它和Vue.js深度集成,让构建单页面应用变得易如反掌。
使用vue-router
Vue cli创建的vue项目中安装:vue add router
核心步骤:
- 步骤一:创建router.js, 使用vue-router插件
import Router from 'vue-router'
Vue.use(Router)
- 步骤二:创建Router实例
export default new Router({...})
- 步骤三:main.js中的根组件上添加该实例
import router from './router'
new Vue({
router,
}).$mount('#app')
- 步骤四:在APP.vue中添加路由视图
<router-view></router-view>
- 导航
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
或者
this.$router.push('/')
this.$router.push('/about')
手写vue-router
实现⼀个插件:创建VueRouter类和install⽅法
我们先创建一个简单的vue-cli项目,然后来开始我们的手写过程
创建my-vue-router.js
let Vue
class VueRouter {
constructor(options) {
this.$options = options // 保存选项
}
}
// 实现install方法,注册$router
VueRouter.install = function(_Vue) {
Vue = _Vue // 引用构造函数
// 使用混入方式是因为调用use的时间非常之早
Vue.mixin({
beforeCreate() {
// 只有根组件拥有router选项
if(this.$options.router) {
Vue.prototype.$router = this.$options.router // 挂载$router
}
}
})
Vue.component('router-link', Link)
Vue.component('router-view', View)
}
export default VueRouter
创建my-router-link.js
export default {
props: {
to: String,
required: true
},
render(h) {
// <a href={'#'+this.to}>{this.$slots.default}</a>
return h('a', {
attrs: {
href: '#' + this.to
}
},[
this.$slots.default
])
}
}
创建my-router-view.js
export default {
render(h) {
return h(null) // 暂时先不渲染任何内容
}
}
监控url变化
定义一个响应式的属性current,监听hashonchange事件
import Link from './my-router-link.js'
import View from './my-router-view.js'
let Vue
class VueRouter {
constructor(options) {
this.$options = options // 保存选项
const initial = window.location.hash.slice(1) || '/'
Vue.util.defineReactive(this, 'current', initial)
// 监听hashchange事件
window.addEventListener('hashchange', this.onHashChange.bind(this))
window.addEventListener('load', this.onHashChange.bind(this))
// 优化:提前创建路由表,减少循环查询次数
this.routeMap = {}
this.$options.routes.forEach(route => {
this.routeMap[route.path] = route
})
}
onHashChange(){
this.current = window.location.hash.slice(1)
}
}
// 实现install方法,注册$router
VueRouter.install = function(_Vue) {
Vue = _Vue // 引用构造函数
// 使用混入方式是因为调用use的时间非常之早
Vue.mixin({
beforeCreate() {
// 只有根组件拥有router选项
if(this.$options.router) {
Vue.prototype.$router = this.$options.router // 挂载$router
}
}
})
Vue.component('router-link', Link)
Vue.component('router-view', View)
}
export default VueRouter
动态获取对应组件
// my-router-view.js
export default {
render(h) {
// 从注册的路由表中动态查询当前的组件
// let component = null
// const route = this.$router.$options.routes.find(route => route.path === this.$router.current)
// if(route) {
// component = route.component
// }
const {routeMap, current} = this.$router
const component = routeMap[current] ? routeMap[current].component : null
return h(component)
}
}
更改router/index.js中的router引用
// import VueRouter from 'vue-router'
import VueRouter from '../myRouter/my-vue-router'
启动项目看效果
~~感谢观看
关注下方【大前端驿站】
让我们一起学,一起进步
【分享、点赞、在看】三连吧,让更多的人加入我们~~