zoukankan      html  css  js  c++  java
  • 手写vue-router

    main.js

    import Vue from "vue";
    import App from "./App.vue";
    // 手动封装的krouter
    import router from './krouter'
    new Vue({
        router,
        render: h => h(App)
    }).$mount("#app");

    krouter.js

    import Vue from 'vue'
    //组件引入
    import Home from "./views/Home";
    import About from "./views/About";
    import VueRouter from './kvue-router'
    // 插件注册
    Vue.use(VueRouter);
    
    export default new VueRouter({
      routes: [
          { path: "/", component: Home }, 
          { path: "/about", component: About }
      ]
    });

    kvue-router

    let Vue;
    class VueRouter {
        constructor(options) {
            //接收到krouter.js传过来的配置项
            this.$options = options;
    
            // 创建一个路由path和route映射
            this.routeMap = {};
            // 利用Vue响应式原理将当前路径current做成响应式
            this.app = new Vue({
                data: {
                    current: '/'
                }
            })
        }
    
        init() {
            // 绑定浏览器事件
            this.bindEvents();
    
            // 解析路由配置
            this.createRouteMap(this.$options);
    
            // 创建router-link和router-view
            this.initComponent();
        }
    
        bindEvents() {
              //监听浏览器hash值的变化和加载事件
            window.addEventListener('hashchange', this.onHashChange.bind(this))
            window.addEventListener('load', this.onHashChange.bind(this))
        }
        onHashChange() {
            //例如: http://localhost/#/home
            this.app.current = window.location.hash.slice(1) || '/';
        }
        createRouteMap(options) {
            options.routes.forEach(item => {
                // ['/home']: {path:'/home',component:Home}
                this.routeMap[item.path] = item;
            })
        }
        initComponent() {
            // 声明两个全局组件
            Vue.component('router-link', {
                props: {
                    to: String
                },
                render(h) {
                    // 目标是:<a :href="to">xxx</a>
                    return h('a', {
                        attrs: {
                            href: '#' + this.to
                        }
                    }, this.$slots.default)
                    // return <a href={this.to}>{this.$slots.default}</a>
                }
            });
    
            // hash -> current -> render
            Vue.component('router-view', {
                // 箭头函数能保留this指向,这里指向VueRouter实例
                render: (h) => {
                    const Comp = this.routeMap[this.app.current].component;
                    return h(Comp);
                }
            })
    
        }
    }
    
    // 把VueRouter变为插件
    VueRouter.install = function (_Vue) {
        Vue = _Vue; // 这里保存,上面使用
    
        // 混入任务
        Vue.mixin({ // 混入:就是扩展Vue
            beforeCreate() {
                // 这里的代码将来会在外面初始化的时候被调用
                // 这样我们就实现了Vue扩展
                // 但是这里只希望根组件执行一次
                if (this.$options.router) {
                    // Vue.prototype.$router = this.$options.router;
                    this.$options.router.init();
                }
    
            }
        })
    }
    
    export default VueRouter
    请用今天的努力,让明天没有遗憾。
  • 相关阅读:
    创业4
    创业3
    PowerBI开发 第十四篇:使用M公式添加列
    PowerBI开发 第十三篇:增量刷新
    PowerBI开发 第十二篇:钻取
    SSIS 连接数据
    SSIS 调试和故障排除
    SQL Server 日志和代理的错误日志
    SSIS 检查点(CheckPoint)内幕
    SSIS 如何处理逻辑类型的转换?
  • 原文地址:https://www.cnblogs.com/cupid10/p/15291749.html
Copyright © 2011-2022 走看看