【源码工具审核基准】【opengl架构源码】【epr系统源码】vue router源码

时间:2024-11-15 00:06:21 分类:feign 源码分析 来源:全民闯天下2源码

1.Vue Router 源码学习笔记4 - pushState和replaceState的实现
2.vue-router源码三、理解Vue-router中的Matcher
3.vue路由,二级路由及跳转
4.vue-router源码六、router.resolve源码解析

vue router源码

Vue Router 源码学习笔记4 - pushState和replaceState的实现

       在Vue Router中,HTML5History的push和replace操作主要通过util/push-state.js中的相应函数来执行,它们依赖window.history.pushState和window.history.replaceState API。对于HTML5History,源码工具审核基准如果浏览器支持,就按照标准流程进行,即利用pushState或replaceState改变浏览器的历史记录,而不会导致页面刷新。

       对于HashHistory,浏览器支持与否对操作方式有影响。opengl架构源码若支持,同样采用类似方法,通过pushState设置hash部分,replaceState则调用window.location.replace替换当前URL。然而,如果浏览器不支持pushState,会直接操作window.location更改URL,以#符号为标志。

       MDN文档中提到,pushState需要三个参数:状态对象、标题(通常忽略)和可选的epr系统源码URL。而replaceState与pushState类似,只是替换当前历史项,而非新增,尽管它会在浏览器历史中生成新的记录。

       当路由更改后,紧接着是视图的同步更新。详细了解这两个方法的使用,可以参考MDN文档:developer.mozilla.org/zh-CN/docs/Web/API/History/pushState。

       继续深入学习,确保在实际项目中正确运用这些原理,实现无缝的更名器 源码路由切换。

vue-router源码三、理解Vue-router中的Matcher

       在深入探究vue-router的内部机制时,我们关注的重点是Matcher的实现。这个系列文章基于vue-router v4.0.的源码,如果你尚未熟悉vue-router的基本用法,建议先通过官网学习。

       Matcher在vue-router中的角色至关重要,它是每个定义路由的转换器,负责路由的创建、修改和删除。createRouter函数通过createRouterMatcher生成Matcher,jetty源码解读它接收路由表routes和全局选项globalOptions作为输入。

       在createRouterMatcher中,首先创建matchers和matcherMap来存储处理后的RouteRecordMatcher。遍历routes,调用addRoute方法对每个路由进行处理。addRoute处理新路由时,会标准化路由信息,如果新路由是别名,则将其关联到原始记录的aliasOf属性。

       addRoute还会处理路由的别名,生成新的matcher,并递归处理子路由。最后,它返回一个删除原始matcher的方法。createRouteRecordMatcher是addRoute的重要部分,它根据token数组(如/:id(\\d+)new)生成正则表达式和解析器。

       token是解析路径的关键,它定义了路径的结构,包括静态部分和动态参数。tokenizePath函数通过有限状态机将路径转换成token数组。tokensToParser则根据token构建正则表达式和处理函数,用于解析和生成路径。

       createRouteRecordMatcher利用上述工具,构建最终的matcher,包含了路径信息、动态参数处理、权重计算等功能。Matcher的存储机制也值得注意,matchers数组按照权重排序,而matcherMap则只保存原始路由的记录,便于按名称查询。

       总的来说,Matcher是vue-router实现路由匹配和管理的核心组件,它通过token数组和相关函数,实现了路由的高效管理和解析。

vue路由,二级路由及跳转

       â˜…router文件下的index.js文件:

        /* 导入Vue构造函数 */

        import Vue from 'vue'

        /* 导入路由VueRouter构造函数 */

        import VueRouter from 'vue-router'

        /* 导入HomeView页面 */

        import HomeView from '../views/HomeView.vue'

        //调用构造函数Vue的use方法 传入VueRouter构造函数

        //作用是把VueRouter作为一个插件 全局插入到Vue中

        Vue.use(VueRouter)

        /* 定义一个路由数组对象 */

        const routes = [

          /* 一个对象就对应了一个路由

          path就是路由的地址

          name给路由起的名字

          component 具体跳转的页面

          */

          {

            /* path: '/' 根页面,表示已进入就显示的页面 */

            path: '/',

            name: 'home',

            /* 这种方式一进入页面就会全部加载,不是用到的时候再加载

               æ€§èƒ½æ²¡æœ‰æ‡’加载的方式好 */

            component: HomeView,

            /* 可以使用redirect 重定向 已进入主页就展示第一个子页面

             redirect 后面跟的是路径名 并不是name */

             /* 因为/是根路径 所有可以直接写one */

            redirect:'one',

            children:[{

              path:'one',

              name:'one',

              component: () => import('../views/OneView.vue')

            }]

          },

          {

            /* 这里是一级目录所以可以加/ 表示根目录 */

            path: '/about',

            name: 'about',

            // route level code-splitting

            // this generates a separate chunk (about.[hash].js) for this route

            // which is lazy-loaded when the route is visited.

            /* 懒加载功能 : 一开始不加载,当你切换路由的时候再加载 */

            component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue'),

            /* about不是根路径 所以redirect后面要写全 '/about/aboutchild', */

            redirect:'/about/aboutchild',

            children:[{

              path:'aboutchild',

              name:'aboutchild',

              component: () => import('../views/AboutChild.vue')

            }]

          },

          {

            path:'/ChildA',

            name:'ChildA',

            component: () => import('../components/ChildA.vue')

          },

          {

            /* path:'*' 必须要放最后 */

            /* path:'*' 表示上面的路由没有匹配到 则进入下面的页面 */

            path:'*',

            name:'notfound',

            component: () => import('../components/NotFound.vue')

          }

        ]

        /* 实例化构造函数 VueRouter 产生一个实例化对象

           å¹¶æŠŠä¸Šé¢çš„路由数组对象routes当作参数 以对象的方式传给构造函数 VueRouter*/

        const router = new VueRouter({

          routes

        })

        /* 把实例化路由对象 router默认导出  */

        export default router

        main.js文件:

        /* 导入Vue构造函数 */

        import Vue from 'vue'

        /* 导入App.vue入口页面 */

        import App from './App.vue'

        /* 导入router文件夹中的index.js中的router实例化对象 */

        /* 一个文件夹里面只有一个index.js文件在脚手架中可以把./router/index.js简写为./router  */

        import router from './router'

        /* 生产提示 */

        /* 改成false是用来关闭开发者提示 */

        Vue.config.productionTip = false

        /* 在Vue的对象参数里面配置 el:"#app" 等于 .$mount('#app')

           éƒ½æ˜¯ç”¨æ¥æŒ‚载到id为#app的div上的*/

           /* 把路由实例化对象router配置在Vue中,作用是保证项目中

            所有的vue文件都可以使用router路由的属性和方法 */

        new Vue({

          router,

          /* 会把所有vue文件渲染到App组件上 */

          render: h => h(App)

        }).$mount('#app')/* 等同于 el:"#app" */

        viwes文件下:

        App.vue文件:

        <template>

          <div id="app">

            <nav>

              <!-- router-link 组件是负责跳转的 to属性是用来写跳转路径的

                  router-link组件本质上是有a标签来实现的 路由跳转的原理是根据

                  锚点来的 -->

              <router-link to="/">Home</router-link> |

              <router-link to="/about">About</router-link> |

              <router-link to="/ChildA">点我跳转ChildA</router-link> |

              <router-link to="/ChildB">点我跳转ChildB</router-link> |

            </nav>

            <!-- router-view 组件是用来展示组件的容器 -->

            <router-view/>

            <!-- 创建两个组件ChildA 和ChildB 并写两个 router-link 可以实现跳转

                 ç»„件显示在 router-view 容器中 -->

          </div>

        </template>

        <style>

        #app {

          font-family: Avenir, Helvetica, Arial, sans-serif;

          -webkit-font-smoothing: antialiased;

          -moz-osx-font-smoothing: grayscale;

          text-align: center;

          color: #2c3e;

        }

        nav {

          padding: px;

        }

        nav a {

          font-weight: bold;

          color: #2c3e;

        }

        /* .router-link-exact-active 跳转链接被激活的时候加载到router-link身上 */

        nav a.router-link-exact-active {

          color: #b;

        }

        </style>

        AboutView.vue文件:

        <template>

          <div class="about">

            <h1>This is an about page</h1>

            <!-- to后面写的是路径 -->

            <!-- <router-link to="/about/aboutchild">我是aboutchild</router-link> -->

            <!-- to 后面要加: 作用是把后面解析成一个对象而不是字符串 -->

            <router-link :to="{ name:'aboutchild'}">我是aboutchild</router-link>

            <!-- 二级路由显示的容器 -->

            <router-view></router-view>

          </div>

        </template>

        AboutChild.vue文件:

        <template>

          <div>

              <h1>AboutChild</h1>

          </div>

        </template>

        <script>

        export default {

        }

        </script>

        <style>

        </style>

        HomeView.vue文件:

        <template>

          <div class="home">

            <h1>KW冲冲冲</h1>

            <router-link to="/one">ONEview</router-link>

            <!-- 二级路由对应的组件容器 -->

            <router-view></router-view>

          </div>

        </template>

        <script>

        // @ is an alias to /src

        export default {

          name: 'HomeView',

          components: {

          }

        }

        </script>

        OneView.vue文件:

        <template>

          <div>

              <h1>我是ONEVIwe</h1>

          </div>

        </template>

        <script>

        export default {

        }

        </script>

        <style>

        </style>

        components文件下:

        ChildA.vue文件:

        <template>

          <div>

              <h1>我是CHildA</h1>

          </div>

        </template>

        <script>

        export default {

        }

        </script>

        <style>

        </style>

        ChildB.vue文件:

        <template>

          <div>

              <h1>我是ChildB</h1>

          </div>

        </template>

        <script>

        export default {

        }

        </script>

        <style>

        </style>

        NotFound.vue文件:

        <template>

          <div>

              <h1>我是notfound</h1>

          </div>

        </template>

        <script>

        export default {

        }

        </script>

        <style>

        </style>

        左边文件目录:

vue-router源码六、router.resolve源码解析

       vue-router源码系列带你深入了解v4.0.版本的实现,前提是对基本用法有一定了解,可通过官网学习。本文焦点是router.resolve的解析过程。

       router.resolve的核心任务是将给定的路由地址标准化。它接受两个参数:rawLocation(可能为对象或字符串)和currentLocation(可选,默认为currentRoute)。解析过程分为两个分支:

       parseURL函数接收query解析函数、location和currentLocation,负责处理相对路径。例如,当to='cc',from='/aa/bb'时,经过一系列resolveRelativePath操作,最终可能转换为'/aa/cc','/aa/bb/cc'等。特别地,如果from路径以'/ '开始,无论to如何,resolveRelativePath始终返回'/cc'。

       解析完rawLocation后,调用matcher.resolve进一步处理,这个阶段会根据匹配规则进行更复杂的路径处理。

       最终,router.resolve返回一个标准化后的路由对象,包含了处理后的路径信息和其他相关数据,为后续的导航操作提供依据。