zoukankan      html  css  js  c++  java
  • 手写router(简单实现嵌套路由)

    手写router(简单实现嵌套路由)

    需求分析: 简单实现嵌套路由

    • ① 记录当前路由的深度depth
    • ② 路由匹配,得到深度对应的组件

    代码实现

    // 简单实现嵌套路由
    // ① 记录当前路由router-view的深度
    // ② 路由匹配,得到深度对应的组件
    
    let Vue;
    
    class Router {
      constructor(options) {
        this.$options = options;
        this.routeMap = {};
        // options.routes.forEach((route) => {
        //   this.routeMap[route.path] = route;
        // });
        // Vue.util.defineReactive(this, "current", window.location.hash.slice(1) || "/");
        this.current = window.location.hash.slice(1) || "/";
        window.addEventListener("hashchange", this.onHashchange.bind(this));
        window.addEventListener("load", this.onHashchange.bind(this));
    	// 响应式数组
        Vue.util.defineReactive(this, "matched", []);
        this.match();
      }
    
      onHashchange() {
        this.current = window.location.hash.slice(1);
    	// 页面刷新时,需要将matched数组置空,重新匹配路由
        this.matched = [];
        this.match();
      }
      // 通过 this.current 来匹配路由
      match(routes) {
        routes = routes || this.$options.routes;
        for (const route of routes) {
          if (route.path === "/" && this.current === "/") {
            this.matched.push(route);
            return;
          }
          // this.current : /about/info , route.path : /about 、 /about/info
          if (route.path !== "/" && this.current.includes(route.path)) {
            this.matched.push(route);
            if (route.children) {
              this.match(route.children);
            }
            return;
          }
        }
        console.log(this.matched)
      }
    
      static install(_Vue) {
        Vue = _Vue;
        Vue.mixin({
          beforeCreate() {
            if (this.$options.router) {
              Vue.prototype.$router = this.$options.router;
            }
          },
        });
        Vue.component("router-link", {
          props: {
            to: {
              type: String,
              default: "",
            },
          },
          render(h) {
            return h("a", { attrs: { href: "#" + this.to } }, this.$slots.default);
          },
        });
    
        Vue.component("router-view", {
          render(h) {
            // const { routeMap, current } = this.$router;
            // console.log(current);
            // const comp = (routeMap[current] && routeMap[current].component) || null;
    		
    	// 计算出路由的深度
            this.$vnode.data.routerView = true;
            let depth = 0;
            let parent = this.$parent;
            while (parent) {
              const vnodeData = parent.$vnode && parent.$vnode.data;
              // parent的$vnode.data.routerView存在,即该parent组件也是一个router-view,那么组件的深度就要➕1
              if (vnodeData && vnodeData.routerView) {
                depth++;
              }
              parent = parent.$parent;
            }
    
            const route = this.$router.matched[depth]
            const comp = route && route.component || null
            return h(comp);
          },
        });
      }
    }
    
    export default Router;
  • 相关阅读:
    ✨Synchronized底层实现---偏向锁
    🌞LCP 13. 寻宝
    ✨Synchronized底层实现---概述
    ⛅104. 二叉树的最大深度
    c++多线程之顺序调用类成员函数
    C++ STL实现总结
    C#小知识
    C#中HashTable和Dictionary的区别
    WPF的静态资源(StaticResource)和动态资源(DynamicResource)
    WPF之再谈MVVM
  • 原文地址:https://www.cnblogs.com/shine-lovely/p/14872846.html
Copyright © 2011-2022 走看看