首页IT科技vue路由的实现原理是什么(Vue学习:路由)

vue路由的实现原理是什么(Vue学习:路由)

时间2025-05-02 08:51:05分类IT科技浏览5343
导读:2. 路由 2.1 前端路由的发展历程 2.1.1 认识前端路由...

2. 路由

2.1 前端路由的发展历程

2.1.1 认识前端路由

路由其实是网络工程中的一个术语:

在架构一个网络时            ,非常重要的两个设备就是路由器和交换机

              。

​ 当然                    ,目前在我们生活中路由器也是越来越被大家所熟知        ,因为我们生活中都会用到路由器:

事实上         ,路由器主要维护的是一个映射表;映射表会决定数据的流向;

前端路由: 就是一组key-value的映射(通俗的讲:就是一个url与组件/function的映射)

前端路由器: 管理多个路由的,就称为路由器

2.1.2 路由的发展历程

​ 路由的概念在软件工程中出现                   ,最早是在后端路由中实现的            ,原因是web的发展主要经历了这样一些阶段:

后端路由阶段; 前后端分离阶段; 单页面富应用(SPA);

阶段一: 后端路由阶段:

早期的网站开发整个HTML页面是由服务器来渲染的. 服务器直接生产渲染好对应的HTML页面, 返回给客户端进行展示. 但是, 一个网站, 这么多页面服务器如何处理呢? 一个页面有自己对应的网址, 也就是URL; URL会发送到服务器, 服务器会通过正则对该URL进行匹配, 并且最后交给一个Controller进行处理; Controller进行各种处理, 最终生成HTML或者数据, 返回给前端. 上面的这种操作, 就是后端路由: 当我们页面中需要请求不同的路径内容时, 交给服务器来进行处理, 服务器渲染好整个页面, 并且将页面返回给客户端. 这种情况下渲染好的页面, 不需要单独加载任何的js和css, 可以直接交给浏览器展示, 这样也有利于SEO的优化. 后端路由的缺点: 一种情况是整个页面的模块由后端人员来编写和维护的; 另一种情况是前端开发人员如果要开发页面, 需要通过PHP和Java等语言来编写页面代码; 而且通常情况下HTML代码和数据以及对应的逻辑会混在一起, 编写和维护都是非常糟糕的事情;

阶段二: 前后端分离阶段

前端渲染的理解: 每次请求涉及到的静态资源都会从静态资源服务器获取      ,这些资源包括HTML+CSS+JS                  ,然后在前端对这些请求回来的资源进行渲染; 需要注意的是               ,客户端的每一次请求   ,都会从静态资源服务器请求文件; 同时可以看到                  ,和之前的后端路由不同                  ,这时后端只是负责提供API了; 前后端分离阶段: 随着Ajax的出现, 有了前后端分离的开发模式; 后端只提供API来返回数据,前端通过Ajax获取数据               ,并且可以通过JavaScript将数据渲染到页面中; 这样做最大的优点就是前后端责任的清晰                     ,后端专注于数据上    ,前端专注于交互和可视化上; 并且当移动端(iOS/Android)出现后            ,后端不需要进行任何处理                    ,依然使用之前的一套API即可;

阶段三: 单页面富应用阶段:

SPA(single page web application): 单页面富应用, 整个应用只有一个完整的页面.

其实SPA最主要的特点就是在前后端分离的基础上加了一层前端路由.

也就是前端来维护一套路由规则.

前端路由的核心是什么呢?改变URL        ,但是页面不进行整体的刷新                    。

2.2 路由的基本使用

使用步骤:

安装vue-router插件

npm i vue-router

在src目录下创建router目录,再在router目录下创建一个index.js(该文件用于创建整个应用的路由器)

在main.js文件中使用vue-router

//引入vue-router import router from ./router //使用VueRouter createApp(App).use(router).mount(#app)

在router目录下的index.js文件创建路由器对象,并进行相关的路由规则的设置

//引入函数 import { createRouter,createWebHistory } from vue-router //引入组件 import Home from ../components/Home import About from ../components/About const routes = [ //配置路由规则 { path:/home, component:Home }, { path:/about, component:About }, ] //创建路由器实例并传递 `routes` 配置 const router = createRouter({ history: createWebHistory(process.env.BASE_URL), routes }) //导出router export default router 编写Home和About组件

About.vue

<template> <div> <p class="lead">About内容...</p> </div> </template> <script> export default { name: About, }; </script>

Home.vue

<template> <div> <p class="lead">Home内容...</p> </div> </template> <script> export default { name: Home, }; </script>

编写App.vue

<template> <nav class="nav"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Home</a></li> <li><a href="#">About</a></li> </ul> </nav> <div style="margin-top: 60px;"> 组件内容展示区域 </div> </template> <script> import Home from ./components/Home.vue import About from ./components/About.vue export default { name: App, data() { return { }; }, components: { Home, About, }, }; </script> <style lang="css" scoped> li{ list-style-type: none; } .nav{ height: 50px; line-height: 50px; background-color: #999; } .nav ul{ display: flex; } .nav ul li{ margin-right: 20px; display: flex; } .active{ background-color : skyblue; padding:0px 10px; color: #FFF; } </style>

使用router-link替换App.vue中的<a>标签

<li class="active"><router-link to="/home">Home</router-link></li> <li><router-link to="/about">About</router-link></li>

使用router-view替换组件内容展示区

测试

我们发现.当我们点击不同的导航,但是导航的样式没有跟着变,那是因为我们把active类样式写死在Home上,如果想做到,点击不同的导航,样式也跟着切换,我们可以在标签上添加active-class=‘类名’

如果我们的导航很多,那我们就需要在每个<router-link>标签上添加active-class=类名’很繁琐,其实我们也可以在创建router对象,进行设置linkActiveClass属性,而需要在每个<router-link>设置:

router-link的其他属性:

to属性:

是一个字符串         ,或者是一个对象

replace属性:

设置 replace 属性的话                   ,当点击时            ,会调用 router.replace()      ,而不是 router.push()[默认模式];

active-class属性:

设置激活a元素后应用的class                  ,默认是router-link-active

exact-active-class属性:

链接精准激活时               ,应用于渲染的 的 class   ,默认是router-link-exact-active; 路由的默认路径

​ 上面的案例还有一个不太好的实现:默认情况下, 进入网站的首页, 我们希望渲染首页的内容,但是我们的实现中, 默认没有显示首页组件, 必须让用户点击才可以,如何可以让路径默认跳到到首页, 并且渲染首页组件呢?

我们在routes中又配置了一个映射: - path配置的是根路径: / - redirect是重定向, 也就是我们将根路径重定向到/home的路径下, 这样就可以得到我们想要的结果了 ```javascript { //路由默认路径 path:/, redirect:/home } ``` [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HdNQQYP9-1667816366247)(assets/image-20221029204811975.png)]

注意:

在实际开发中,我们会把组件分为两类, 一类是路由组件,一类是普通组件, 我们会把普通组件放在components目录下, 而路由组件则放在views或者pages目录下 通过调用 app.use(router)                  ,我们可以在任意组件中以 this.$router 的形式访问它                  ,并且以 this.$route 的形式访问当前路由      。this.$router 与直接使用通过 createRouter 创建的 router 实例完全相同          。

2.3 嵌套路由

​ 目前我们匹配的Home            、About等都属于第一层路由,我们在它们之间可以来回进行切换                     。但是呢               ,我们Home页面本身                     ,也可能会在多个组件之间来回切换:比如Home中包括Product                    、Ad    ,它们可以在Home内部来回切换;这个时候我们就需要使用嵌套路由            ,在Home中也使用 router-view 来占位之后需要渲染的组件         。

HomeProduct.vue

<template> <ul> <li v-for=" p in productList">{{p}}</li> </ul> </template> <script> export default { name: HomeProduct, data() { return { productList:["小米手机","华为电脑","康佳相机"], }; }, }; </script> <style lang="css" scoped></style>

HomeAd.vue

<template> <ul> <li v-for=" ad in adList">{{ad}}</li> </ul> </template> <script> export default { name: HomeAd, data() { return { adList:["全场商品打5折","为了回馈老客户,让利大行动","你还在等什么!心动不如行动"], }; }, }; </script> <style lang="css" scoped></style>

Home.vue

<template> <h2>Home内容...</h2> <nav class="nav"> <ul> <li ><router-link to="/home/product" >Product</router-link></li> <li ><router-link to="/home/ad" >Ad</router-link></li> </ul> </nav> <div> <router-view></router-view> </div> </template> <script> export default { name: Home, data() { return { }; }, methods: { }, }; </script> <style lang="css" scoped></style>

修改router/index.js

{ path:/home, component:Home, children:[ { path:, component:HomeProduct }, { path:product, component:HomeProduct }, { path:ad, component:HomeAd } ] },

注意:

子级的path不需要加/

2.4 路由懒加载

​ 当打包构建应用时                    ,JavaScript 包会变得非常大        ,影响页面加载      。如果我们能把不同路由对应的组件分割成不同的代码块         ,然后当路由被访问的时候才加载对应组件                   ,这样就会更加高效                     。

​ Vue Router 支持开箱即用的动态导入            ,这意味着你可以用动态导入代替静态导入:这是因为component可以传入一个组件      ,也可以接收一个函数                  ,该函数 需要放回一个Promise;

而import函数就是返回一个Promise;

2.5 动态路由匹配

2.5.1 带参数的动态路由匹配

​ 很多时候               ,我们需要将给定匹配模式的路由映射到同一个组件            。例如   ,我们可能有一个 User 组件                  ,它应该对所有用户进行渲染                  ,但用户 ID 不同   。在 Vue Router 中,我们可以在路径中使用一个动态字段来实现               ,我们称之为 路径参数

User.vue

<template> <h2>用户:</h2> </template> <script> export default { name: User, data() { return { }; }, }; </script> <style lang="css" scoped></style>

配置路由:

{ path: /users/:id, component: ()=>import(../views/User) },

现在像 /users/johnny 和 /users/jolyne 这样的 URL 都会映射到同一个路由                     。

获取动态路由的值:

路径参数用冒号 : 表示               。当一个路由被匹配时                     ,它的 params 的值将在每个组件中以 this.$route.params 的形式暴露出来。因此    ,我们可以通过更新 User 的模板来呈现当前的用户 ID:

<template> <h2>用户:{{$route.params.id}}</h2> </template>

在template中            ,直接通过 $route.params获取值;

在created中                    ,通过 this.$route.params获取值;

在setup中        ,我们要使用 vue-router库给我们提供的一个hook的useRoute;

该Hook会返回一个Route对象         ,对象中保存着当前路由相关的值

你可以在同一个路由中设置有多个 路径参数                   ,它们会映射到 $route.params 上的相应字段                  。例如:

匹配模式 匹配路径 $route.params /users/:username /users/eduardo { username: eduardo } /users/:username/posts/:postId /users/eduardo/posts/123 { username: eduardo, postId: 123 }

注意:

使用 $route 会与路由紧密耦合            ,这限制了组件的灵活性      ,因为它只能用于特定的 URL                   。虽然这不一定是件坏事                  ,但我们可以通过 props 配置来解除这种行为:

我们可以将下面的代码

替换成:

当 props 设置为 true 时               ,route.params 将被设置为组件的 props

2.5.2 404 Not found 路由

​ 对于哪些没有匹配到的路由   ,我们通常会匹配到固定的某个页面   。比如NotFound的错误页面中                  ,这个时候我们可编写一个动态路由用于匹配所有的页面;

​ 常规参数只匹配 url 片段之间的字符                  ,用 / 分隔              。如果我们想匹配任意路径,我们可以使用自定义的路径参数正则表达式               ,在 路径参数后面的括号中加入 正则表达式 :

// 将匹配所有内容并将其放在 `$route.params.pathMatch` 下 { path: /:pathMatch(.*), component: ()=>import(../views/NotFound) },

我们可以通过 $route.params.pathMatch获取到传入的参数:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aSgJ2PKi-1667816366266)(assets/image-20221030103501207.png)]

注意:

这里还有另外一种写法:

{ path: /:pathMatch(.*)*, component: ()=>import(../views/NotFound) },

在/:pathMatch(.*)后面又加了一个 *

它们的区别在于解析的时候                     ,是否解析 /:

path: /:pathMatch(.*)写法

path: /:pathMatch(.*)*写法

2.6 query方式的参数

​ 我们使用动态路由的方式可以传递数据, 但是我们也可以像url传递参数的方式,在to的后面使用?传递参数                    。

​ 我们修改ad的路由,把广告的id和标题作为参数传递给HomeAd组件, 并在HomeAd组件展示.

HomeAd.vue

<template> <ul> <li v-for=" ad in adList"> <router-link to="/home/ad/detail?id=ad.id&title=ad.title">{{ad.title}}</router-link> </li> </ul> <hr/> <router-view/> </template> <script> export default { name: HomeAd, data() { return { adList:[ {id:1,title:全场商品打5折}, {id:2,title:为了回馈老客户,让利大行动}, {id:3,title:你还在等什么!心动不如行动} ], }; }, }; </script> <style lang="css" scoped></style>

我们发现 <router-link to="/home/ad/detail?id=ad.id&title=ad.title">{{ad.title}}</router-link>使用?给组件传递的id和title数据      。

接下来,我们创建一个AdDetail组件,用于展示

AdDetial.vue

<template> <div> <p>编号:{{$route.query.id}}</p> <p>标题:{{$route.query.title}}</p> </div> </template> <script> export default { name: AdDetial, data() { return { }; }, mounted(){ //console.log(this.$route); } }; </script> <style lang="scss" scoped></style>

我们可以使用this.$route获取当前路由的配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zCLEoWjU-1667816366276)(assets/image-20221030113537866.png)]

在template标签中可以使用{{$route.query.title}}获取传递的参数

但是我们会发现,不管我们点击那个广告导航,AdDetail组件显示都是ad.id和ad.title

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ipsde6pa-1667816366277)(assets/image-20221030113746315.png)]

为什么会是这样呢? 原来是我们的 <router-link to="/home/ad/detail?id=ad.id&title=ad.title">{{ad.title}}</router-link>使用的是to属性,所以双引号的只作为普通字符串. 那怎么把ad.id与ad.title作为一个变量呢?

我们可以使用模板字符串:

<router-link :to="`/home/ad/detail?id=${ad.id}&title=${ad.title}`">{{ad.title}}</router-link>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NcI0yw9X-1667816366278)(assets/image-20221030114134117.png)]

虽然我们使用to的模板字符串的写法,进行传参,但是如果我们需要传递多个参数,那模板字符串的写法就很不美观,那我们可以使用to的对象写法:

<li v-for=" ad in adList"> <!-- to的对象写法:--> <router-link :to="{ path:/home/ad/detail, query:{ id:ad.id, title:ad.title } }">{{ad.title}}</router-link> </li>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FBsiNNhG-1667816366283)(assets/image-20221030115012707.png)]

我们可以关闭TypeScript的验证,然后重启vscode

2.7 命名路由

除了 path 之外    ,你还可以为任何路由提供 name          。这有以下优点:

没有硬编码的 URL params 的自动编码/解码                     。 防止你在 url 中出现打字错误         。 绕过路径排序(如显示一个)

要链接到一个命名的路由            ,可以向 router-link 组件的 to 属性传递一个对象:

<li><router-link :to="{ name: user, params: { id: 101 }}">User</router-link></li>

注意:

如果使用params传递参数, 不能写path,只能写name

2.8 编程式导航

​ 除了使用 <router-link> 创建 a 标签来定义导航链接                    ,我们还可以借助 router 的实例方法        ,通过编写代码来实现      。

2.8.1 导航到不同的位置

在 Vue 实例中         ,你可以通过 $router 访问路由实例                     。因此你可以调用 this.$router.push            。

想要导航到不同的 URL                   ,可以使用 router.push 方法   。这个方法会向 history 栈添加一个新的记录            ,所以      ,当用户点击浏览器后退按钮时                  ,会回到之前的 URL                     。

当你点击 <router-link> 时               ,内部会调用这个方法   ,所以点击 <router-link :to="..."> 相当于调用 router.push(...) :

声明式 编程式 <router-link :to="..."> router.push(...)

该方法的参数可以是一个字符串路径                  ,或者一个描述地址的对象               。例如:

// 字符串路径 router.push(/users/eduardo) // 带有路径的对象 router.push({ path: /users/eduardo }) // 命名的路由                  ,并加上参数,让路由建立 url router.push({ name: user, params: { username: eduardo } }) // 带查询参数               ,结果是 /register?plan=private router.push({ path: /register, query: { plan: private } }) // 带 hash                     ,结果是 /about#team router.push({ path: /about, hash: #team })

注意:如果提供了 path    ,params 会被忽略            ,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法                    ,你需要提供路由的 name 或手写完整的带有参数的 path :

const username = eduardo // 我们可以手动建立 url        ,但我们必须自己处理编码 router.push(`/user/${username}`) // -> /user/eduardo // 同样 router.push({ path: `/user/${username}` }) // -> /user/eduardo // 如果可能的话         ,使用 `name` 和 `params` 从自动 URL 编码中获益 router.push({ name: user, params: { username } }) // -> /user/eduardo // `params` 不能与 `path` 一起使用 router.push({ path: /user, params: { username } }) // -> /user 2.8.2 替换当前位置

它的作用类似于 router.push                   ,唯一不同的是            ,它在导航时不会向 history 添加新记录      ,正如它的名字所暗示的那样——它取代了当前的条目                  。

声明式 编程式 <router-link :to="..." replace> router.replace(...)

也可以直接在传递给 router.push 的 routeLocation 中增加一个属性 replace: true :

router.push({ path: /home, replace: true }) // 相当于 router.replace({ path: /home }) 2.8.3 页面的前进后退

router的go方法

该方法采用一个整数作为参数                  ,表示在历史堆栈中前进或后退多少步               ,类似于 window.history.go(n)                   。

// 向前移动一条记录   ,与 router.forward() 相同 router.go(1) // 返回一条记录                  ,与 router.back() 相同 router.go(-1) // 前进 3 条记录 router.go(3) // 如果没有那么多记录                  ,静默失败 router.go(-100) router.go(100)

router也有back:

通过调用 history.back() 回溯历史   。相当于 router.go(-1);

router也有forward:

通过调用 history.forward() 在历史中前进              。相当于 router.go(1); 2.8.4 动态管理路由的其他方法

删除路由有以下三种方式:

方式一:添加一个name相同的路由;

方式二:通过removeRoute方法,传入路由的名称;

方式三:通过addRoute方法的返回值回调;

路由的其他方法补充:

router.hasRoute():检查路由是否存在                    。 router.getRoutes():获取一个包含所有路由记录的数组      。

2.9 路由守卫

vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航          。路由守卫就是路由跳转过程中的一些钩子函数               ,在路由跳转的时候                     ,做一些判断或其它的操作                     。 类似于组件生命周期钩子函数         。

​ 所谓的路由守卫可以简单的理解为一座房子的门口的保安    ,想要进入这个房子就必须通过保安的检查            ,要告诉路由守卫你**从哪里来(from)?要到哪里去(to)?然后保安再告诉你下一步该怎么做(next())?**如果你的确是这个房子主人允许进入的人                    ,那就让你进入        ,否则就要打电话给房子主人         ,跟房主商量(登录注册)                   ,给你权限      。

分类: 全局的            ,单个路由独享的      ,或者组件级的                     。

2.9.1 全局守卫

​ 所谓全局路由守卫                  ,就是小区大门               ,整个小区就这一个大门   ,你想要进入其中任何一个房子                  ,都需要经过这个大门的检查            。

vue-router全局有三个守卫:

router.beforeEach 全局前置守卫 进入路由之前 router.beforeResolve 全局解析守卫(2.5.0+) 在beforeRouteEnter调用之后调用 router.afterEach 全局后置钩子 进入路由之后 2.9.1.1 全局前置守卫

你可以使用 router.beforeEach 注册一个全局前置守卫:

beforeEach 它有两个参数:

to:即将进入的路由Route对象; from:即将离开的路由Route对象;

它有返回值:

false:取消当前导航; 不返回或者undefined:进行默认导航; 返回一个路由地址: 可以是一个string类型的路径; 可以是一个对象                  ,对象中包含path        、query         、params等信息;

可选的第三个参数:next(不推荐使用)

在Vue2中我们是通过next函数来决定如何进行跳转的; 但是在Vue3中我们是通过返回值来控制的,不再推荐使用next函数               ,这是因为开发中很容易调用多次next;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qOIaVKf5-1667816366295)(assets/image-20221031202544204.png)]

​ 比如我们完成一个功能                     ,只有登录后才能访问home/product和home/ad,如果没有登录,只能访问home和about, 前端怎么知道用户是否登录呢? 比如我们在登录成功之后, 后台会产生一个唯一的字符串,这个字符串我们称为token, 并响应给客户端,客户端会把这个token保存在浏览器的本地存储对象:localStorage中.

​ 我们首先创建一个登录页面,

Login.vue

<template> <div> <form action="/home" ref="loginForm"> <label for="username">用户名:</label> <input id="username" v-model="username"/> <hr/> <label for="pwd">密码:</label> <input id="pwd" v-model="password" type="password"/> <hr/> <button type="button" @click="doLogin">登录</button> </form> </div> </template> <script> export default { name: Login, data() { return { username:, password: }; }, mounted() { }, methods: { doLogin(){ if(this.username===admin && this.password===123){ localStorage.setItem("token",this.username) alert(登录成功!!!); this.$refs.loginForm.submit(); }else{ alert(登录失败!!!); this.$refs.loginForm.reset(); } } }, }; </script> <style lang="scss" scoped> </style>

并在router/index.js配置一下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lvy5x7z4-1667816366296)(assets/image-20221101062849597.png)]

在App.vue的导航我们添加一个登录的按钮

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R4OfAHW2-1667816366301)(assets/image-20221101062936603.png)]

并实现跳转到Login.vue

toLogin(){ this.$router.push({ path:/login }); }

现在我们使用全局前置守卫,来实现登录的访问控制, 在router/index.js文件中创建一个前置路由守卫:

//全局的前置路由守卫 --- 初始化的时候被调用,每次路由切换之前被调用 router.beforeEach((to,from) =>{ if(to.path === /home/product || to.path === /home/ad){ if(!localStorage.getItem("token")){ return { path:/login }; } } });

其他路由守卫,请参考https://router.vuejs.org/zh/guide/advanced/navigation-guards.html

2.10 不同的历史模式

在创建路由器实例时    ,`history` 配置允许我们在不同的历史模式中进行选择   。 2.10.1 Hash 模式

​ hash 模式是用 createWebHashHistory() 创建的:

import { createRouter, createWebHashHistory } from vue-router const router = createRouter({ history: createWebHashHistory(), routes: [ //... ], })

​ 它在内部传递的实际 URL 之前使用了一个哈希字符(#)                     。由于这部分 URL 从未被发送到服务器            ,所以它不需要在服务器层面上进行任何特殊处理               。不过                    ,它在 SEO 中确实有不好的影响。如果你担心这个问题        ,可以使用 HTML5 模式                  。

2.10.2 HTML5 模式

​ 用 createWebHistory() 创建 HTML5 模式         ,推荐使用这个模式:

import { createRouter, createWebHistory } from vue-router const router = createRouter({ history: createWebHistory(), routes: [ //... ], })

当使用这种历史模式时                   ,URL 会看起来很 “正常              ”            ,例如 https://example.com/user/id                   。漂亮!

不过      ,问题来了   。由于我们的应用是一个单页的客户端应用                  ,如果没有适当的服务器配置               ,用户在浏览器中直接访问 https://example.com/user/id   ,就会得到一个 404 错误              。这就丑了                    。

不用担心:要解决这个问题                  ,你需要做的就是在你的服务器上添加一个简单的回退路由      。如果 URL 不匹配任何静态资源                  ,它应提供与你的应用程序中的 index.html 相同的页面          。漂亮依旧!

nginx服务器:

location / { try_files $uri $uri/ /index.html; }

rom) =>{

if(to.path === ‘/home/product’ || to.path === ‘/home/ad’){

if(!localStorage.getItem(“token                    ”)){

return {

path:‘/login’

};

}

}

}); 其他路由守卫,请参考https://router.vuejs.org/zh/guide/advanced/navigation-guards.html ### 2.10 不同的历史模式 在创建路由器实例时,`history` 配置允许我们在不同的历史模式中进行选择                     。 #### 2.10.1 Hash 模式hash 模式是用 `createWebHashHistory()` 创建的: ```javascript import { createRouter, createWebHashHistory } from vue-router const router = createRouter({ history: createWebHashHistory(), routes: [ //... ], })

​ 它在内部传递的实际 URL 之前使用了一个哈希字符(#)         。由于这部分 URL 从未被发送到服务器               ,所以它不需要在服务器层面上进行任何特殊处理      。不过                     ,它在 SEO 中确实有不好的影响                     。如果你担心这个问题    ,可以使用 HTML5 模式            。

2.10.2 HTML5 模式

​ 用 createWebHistory() 创建 HTML5 模式            ,推荐使用这个模式:

import { createRouter, createWebHistory } from vue-router const router = createRouter({ history: createWebHistory(), routes: [ //... ], })

当使用这种历史模式时                    ,URL 会看起来很 “正常      ”        ,例如 https://example.com/user/id   。漂亮!

不过         ,问题来了                     。由于我们的应用是一个单页的客户端应用                   ,如果没有适当的服务器配置            ,用户在浏览器中直接访问 https://example.com/user/id      ,就会得到一个 404 错误               。这就丑了。

不用担心:要解决这个问题                  ,你需要做的就是在你的服务器上添加一个简单的回退路由                  。如果 URL 不匹配任何静态资源               ,它应提供与你的应用程序中的 index.html 相同的页面                   。漂亮依旧!

nginx服务器:

location / { try_files $uri $uri/ /index.html; }

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
台湾能用的云盘(台湾云主机购买流程是什么) 表单验证实验报告(vant 的表单校验)