美文网首页
手写VueRouter简单实现hash路由

手写VueRouter简单实现hash路由

作者: Yezzle | 来源:发表于2020-03-28 19:04 被阅读0次

    vue-router用法

    首先简单看看vue-router简单用法:

    import VueRouter from 'vue-router'
    import Home from '../views/Home.vue'
    import Vue from 'vue'
    
    // route.js
    const routes = [
        { path: '/',component: Home },
        { path: '/about',component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
    ]
    
    Vue.use(VueRouter)
    
    export default route = new VueRouter({
        routes
    })
    
    // main.js
    new Vue({
      router,
      store,
      render: h => h(App)
    }).$mount('#app')
    
    // app.js
    <template>
      <div id="app">
        <div id="nav">
          <router-link to="/">Home</router-link> |
          <router-link to="/about">About</router-link>
        </div>
        <router-view/>
      </div>
    </template>
    
    <script>
    export default {
      name: 'app',
    }
    </script>
    

    从上面代码可以看到,在route.js中导出了实例化路由对象,通过vue.use之后便可以在所有组件中访问到$router,并且可以使用router--link、router-view,并且可以响应路由变化更新vue渲染,下面带大家手动录一个vue路由组件,来揭开vueRouter的神秘面纱

    动手撸一个VueHashRouter

    1.新建vueHashRouter.js文件,实现构造函数:

    // vueHashRouter.js
    export class VueHashRouter {
    
        constructor(options){
            this.$options = options // 保存一下传入的路由配置选项
            this.routeMap = {} // 映射路由和组件实例
        }
    

    2. 实现install接口:

    // vueHashRouter.js
    export class VueHashRouter {
       //some codes
    }
    
    // 实现install接口
    VueHashRouter.install = (Vue) => {
        // 混入
        Vue.mixin({
            //组件创建时注入实例
            beforeCreate:() => {
                // 仅在跟组件创建时 执行一次
                if(this.$options.router){
                    // 将跟组件options上面的router实例 挂在原型上
                    Vue.prototype.$router = this.$options.router
                    // 执行init方法
                    this.$router.init()
                }
            }
        })
    }
    

    调用Vue.use()就会执行install方法, 这里先混入beforeCreate生命周期,这样里面的代码就会随着生命周期一块执行,并且判断if(this.$options.router),因为创建跟组件时传入了router实例:

    new Vue({
        router,
        store,
        ...
    }).mount('#app')
    

    这个判断找到的就是这个实例, 我们只需要在这个组件创建时执行一次:

    • 把router实例挂在Vue原型上
    • 执行实例的初始化方法
      这里就解答了为啥每个vue组件内部都有个$router对象了

    3. 初始化router

    接下来我们来实现init方法,在init方法里面做了三件事情:

    • 绑定路由change事件
    • 解析路由配置
    • 注册全局组件router-link、router-view
      代码如下:
        // vueHashRouter.js
    export class VueHashRouter {
        ...
      
        init(){
            this.bindEvents() // 监听事件
            this.createRouteMap(this.$options) // 解析路由配置
            this.initComponent() // 初始化两个组件: router-view, router-link
        }
    
        bindEvents = () => {
            // 利用vue双向绑定 监听hash变化出发重新渲染
            this.app = new Vue({
                    data: { current: '/' }
            })
            window.addEventListener('load', this.onHashChange)
            window.addEventListener('hashchange', this.onHashChange)
        }
    
        onHashChange = () => {
            this.app.current = window.location.hash.slice(1)
        }
    
        createRouteMap = (options) => {
            options.routes.forEach(route => this.routeMap[route.path] = route.component)
        }
    
        initComponent = () => {
            // 直接全局注册组件  router-view, router-link
            Vue.component('router-link', {
                props: { to : String },
                render: function(h){
                    // this指向当前router-link实例
                    return h('a', { attrs: { href: '#' + this.to}}, [this.$slots.default])
                }
            })
    
            Vue.component('router-view', {
                // 注意这里是箭头函数
                render: (h) => {
                    let comp = this.routeMap[this.app.current]
                    return h(comp)
                }
            })
        }
    

    bindEvents就是进行了一个路由change事件的监听,并强制绑定vue的实例上, 然后让这个实例跟router-view关联, 只要hash发生变化, 就会触发router-view的渲染更新
    initComponent的作用就是全局注册两个路由组件,这样我们就可以直接在模板中使用了。

    注意:这里还没有处理路由嵌套,还不能使用嵌套路由

    到这里就已经完成了一个简单的vue的router组件,虽然只实现了hash路由,稍作修改也可以实现browser路由和更加复杂的路由配置

    相关文章

      网友评论

          本文标题:手写VueRouter简单实现hash路由

          本文链接:https://www.haomeiwen.com/subject/nrujuhtx.html