## 一、传统路由的概念 传统路由的核心思想是: URL 的每一次变化,都对应着一次对服务器的请求,并由服务器决定返回什么内容给浏览器。 在这种模式下,路由的逻辑和规则完全由服务器端的代码(如 Java、PHP、Python、Node.js 等)来控制和处理。 **简单举例** 想象你去图书馆借书。 - 你每次要一本不同的书(点击不同的链接),比如 `/books/scifi` 或 `/books/history`,你都需要把请求告诉图书管理员(服务器)。 - 管理员会跑到不同的书架(服务器端的不同逻辑处理程序),找到整本完整的书(一个完整的HTML页面),然后把它交给你。 - 即使两本书的封面、目录页很像,你每次拿到手的也是一本全新的、独立的书。 这个过程就是传统路由。 浏览器可以通过存储页面缓存和记录浏览过程来实现页面的前进与后退。 但Vue构建的页面一般都是单页面应用(SPA),无论页面内容怎么变化,其实还是在这个页面(URL)没有改变,所以浏览器就无法通过传统路由的方式去实现前进与后退,因此就需要使用到Vue路由。 ## 二、Vue路由的安装 #### 1、通过CDN安装 ```html ``` 在生产环境下需要指定特定的版本号和内部版本,避免版本更新带来的不兼容性 ```html ``` #### 2、下载到本地 打开[CDN页面](https://unpkg.com/vue-router@4) -> 右键 -> 另存为 ## 三、实现Vue路由 #### 1、创建Vue实例 ```html Title 首页 新闻 ``` #### 2、定义路由组件 在` ``` #### 3、定义路由规则 在上一步后面追加,声明常量`routers`来将组件绑定到URL路径上 ```html ``` #### 4、创建路由实例 在上一步后面追加,声明常量`router`,通过`VueRouter.createRouter()`来返回一个路由实例,传入的参数是路由的配置对象,使用两个属性`history`、`routes`,分别作用为配置路由模式与路由规则,通过`VueRouter.createWebHashHistory()`来配置哈希路由模式,路由规则要传入上一步定义的路由规则常量,若常量名与属性名一致则可以简写。 ```html ``` #### 5、挂载路由对象 修改Vue实例挂载,在挂载实例前使用use(路由对象)来挂载路由对象,若有多个路由对象(子目录)需要挂载,可以使用链式挂载方式`use(router1).use(router2).use(...).mount('#app');` ```html ``` #### 6、调用路由 调用路由需要使用使用``标签来实现路由跳转,实质上为``标签,且需要定义路由出口用来显示路由跳转的内容。 ```html Title Home News 首页 新闻 ``` #### 7、根路由 实现上面的例子后会发现在启动项目时没有默认显示首页,必须点击后才能显示首页(home),所以要在路由规则中添加对根目录的路由规则。 ```html ``` #### 8、路由重定向 默认首页也可以通过编写路由重定向规则来实现。 ```html ``` ## 四、嵌套路由 #### 1、创建子路由模板 ```html 登录 注册 ``` #### 2、定义路由组件 ```html ``` #### 3、定义路由规则 因为是嵌套的子路由,所以在需要嵌套的路由中添加`children`属性,其值与`routes`写法并无两样,需要注意的是路径要写到`/`根目录的全路径。 ```html ``` #### 5、挂载路由对象 修改Vue实例挂载,在挂载实例前使用use(路由对象)来挂载路由对象,若有多个路由对象(子目录)需要挂载,可以使用链式挂载方式`use(router1).use(router2).use(...).mount('#app');` ```html ``` #### 6、调用路由 修改父路由的模板内容,在模板里添加``标签与``标签 ```html 首页 登录 注册 ``` ## 五、路由传参 在进行路由跳转时跳转到的页面可能需要某些参数来完成页面的渲染,这时就可以用到路由传参。 #### 1、`params`传参(restful风格) 首先需要修改路由规则中每个URL对应的组件,为其属性`name`赋值并将URL改为动态URL`/:参数名/`,之后将``标签的`to`属性绑定,在里面声明一个对象,其`name`属性代表对应组件的`name`属性,`params`属性用来存放参数对象,在路由的模板中可以使用`$route.params.参数名`来调用参数 ```html Title Home News 首页 新闻 参数: 参数: ``` **注意**:在Vue3的[4.1.4](https://github.com/vuejs/router/compare/v4.1.3...v4.1.4) (2022-08-22更新)版本后,非restful风格的params传参被移除。详见:[router/packages/router/CHANGELOG.md at main · vuejs/router](https://github.com/vuejs/router/blob/main/packages/router/CHANGELOG.md#414-2022-08-22) #### 2、`query`传参 首先将``标签的`to`属性绑定,在里面声明一个对象,其`path`属性代表对应组件的`path`属性,`query`属性用来存放参数对象,在路由的模板中可以使用`$route.query.参数名`来调用参数 ```html Title Home News 首页 新闻 参数: 参数: ``` #### 3、两种方式的区别 | **对比项** | **query方式** | **params方式** | | ------------------ | ------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | | **URL显示形式** | 参数以`?key=value` 形式附加在URL后,如:`/path?name=John&age=20` | 参数作为路径的一部分,如:`/user/123`(需在路由配置中定义占位符,如 `/user/:id`) | | **路由配置** | 无需在路由配置中声明参数,可直接使用 | 必须在路由配置中通过占位符(如`:id`)声明参数,否则参数不会生效 | | **参数传递方式** | 通过`router.push({ path: '/path', query: { name: 'John' } })` 传递 | 通过`router.push({ name: 'user', params: { id: 123 } })` 传递(需用命名路由) | | **参数获取方式** | 在组件中通过`this.$route.query.name` 获取 | 在组件中通过`this.$route.params.id` 获取 | | **参数类型支持** | 支持传递任意类型参数(如字符串、数字、数组等),但URL中会强制转换为字符串 | 支持任意类型参数,但URL路径中会以字符串形式显示,需手动转换类型 | | **参数是否必传** | 参数可选,URL中可省略 | 若路由配置中声明了占位符(如`/:id`),则参数必传,否则跳转失败 | | **浏览器刷新** | 刷新页面后参数保留在URL中,数据不会丢失 | 刷新页面后参数仍保留在URL路径中,但需确保路由配置匹配,否则可能丢失参数 | | **适用场景** | 适合可选参数(如搜索筛选、分页参数) | 适合必传参数(如资源ID、详情页标识) | | **SEO友好性** | 由于参数明文显示,对搜索引擎更友好 | 参数作为路径的一部分,结构清晰,但动态路径可能需额外SEO处理 | | **示例代码** | ```js router.push({ path: '/search', query: { keyword: 'vue' } }) ``` | ```js router.push({ name: 'UserDetail', params: { userId: 123 } }) ``` | ## 六、编程式路由 编程式路由可以通过逻辑来判断路由到哪里去,所以不能使用``标签进行路由转跳了,需要使用自定义方法来进行转跳,触发自定义方法的方式任选,在此用按钮为例。 #### 1、创建路由导航 修改挂载标签的内容 ```html 首页 新闻 登录 前进 后退 ``` #### 2、配置路由 ```html ``` **注意**:使用`params`方式传参时,路径必须为动态路径,且参数必须传入。 #### 3、挂载路由 在上一步后面追加,要写自定义方法,使用`this.$router.push()`方法进行路由转跳,参数是一个路由地址对象,写法与``中的`:on`已绑定属性相同,若路由不传参则直接写路径字符串即可。 ```html ``` **注意**:`this.$router.go()`方法传入整型参数,绝对值为前进/回退的页数,符号为正是前进,符号为负是后退。 ## 七、路由监听 路由监听是用Vue实例的`watch`属性实现的,实现方法与属性监听器的方法一样,都是用属性名来命名,所以这里用`$route`来命名方法,参数依旧有两个`newValue`、`oldValue`。 ```html Title Home News 首页 新闻 ``` ## 八、导航守卫 #### 1、概念 导航守卫也叫做路由守卫,是用来在路由转跳之前做一些验证,比如说登录验证。 #### 2、使用方法 可以通过`router.beforeEach((to,from,next)=>{})`方法来注册一个全局前置守卫,每个守卫方法由三个参数: * to:即将要进入的目标路由对象(转跳目标页面),可以用`to.path`来获取即将要进入的路由地址; * from:当前导航正要离开的路由地址(当前页面),可以用`from.path`来获取正要离开的路由地址; * next:是一个函数,表示验证通过继续执行,直接用`next()`调用即可 #### 3、示例 ```html Title 首页 新闻 登录 前进 后退 首页 新闻 参数: 参数: 登录 ``` Loading... ## 一、传统路由的概念 传统路由的核心思想是: URL 的每一次变化,都对应着一次对服务器的请求,并由服务器决定返回什么内容给浏览器。 在这种模式下,路由的逻辑和规则完全由服务器端的代码(如 Java、PHP、Python、Node.js 等)来控制和处理。 **简单举例** 想象你去图书馆借书。 - 你每次要一本不同的书(点击不同的链接),比如 `/books/scifi` 或 `/books/history`,你都需要把请求告诉图书管理员(服务器)。 - 管理员会跑到不同的书架(服务器端的不同逻辑处理程序),找到整本完整的书(一个完整的HTML页面),然后把它交给你。 - 即使两本书的封面、目录页很像,你每次拿到手的也是一本全新的、独立的书。 这个过程就是传统路由。 浏览器可以通过存储页面缓存和记录浏览过程来实现页面的前进与后退。 但Vue构建的页面一般都是单页面应用(SPA),无论页面内容怎么变化,其实还是在这个页面(URL)没有改变,所以浏览器就无法通过传统路由的方式去实现前进与后退,因此就需要使用到Vue路由。 ## 二、Vue路由的安装 #### 1、通过CDN安装 ```html <script src="https://unpkg.com/vue-router@4"></script> ``` 在生产环境下需要指定特定的版本号和内部版本,避免版本更新带来的不兼容性 ```html <script src="https://unpkg.com/vue-router@4.6.3"></script> ``` #### 2、下载到本地 打开[CDN页面](https://unpkg.com/vue-router@4) -> 右键 -> 另存为 ## 三、实现Vue路由 #### 1、创建Vue实例 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./assets/js/vue.global.js"></script> <script src="./assets/js/vue-router.global.js"></script> </head> <body> <div id="app"> </div> <template id="home"> <div> <h2>首页</h2> </div> </template> <template id="news"> <div> <h2>新闻</h2> </div> </template> <script> Vue.createApp().mount('#app'); </script> </body> </html> ``` #### 2、定义路由组件 在`<script>`标签内第一行添加,声明两个常量,里面`template`分别指向两个`<template>`标签,代表两个组件 ```html <script> const Home = { template: '#home' }; const News = { template: '#news' }; </script> ``` #### 3、定义路由规则 在上一步后面追加,声明常量`routers`来将组件绑定到URL路径上 ```html <script> const routes = [ { path: '/home', component: Home }, { path: '/news', component: News } ]; </script> ``` #### 4、创建路由实例 在上一步后面追加,声明常量`router`,通过`VueRouter.createRouter()`来返回一个路由实例,传入的参数是路由的配置对象,使用两个属性`history`、`routes`,分别作用为配置路由模式与路由规则,通过`VueRouter.createWebHashHistory()`来配置哈希路由模式,路由规则要传入上一步定义的路由规则常量,若常量名与属性名一致则可以简写。 ```html <script> const router = VueRouter.createRouter({ // 配置路由模式(哈希方式) history: VueRouter.createWebHashHistory(), // 路由规则(如果路由规则名为routes,那么可以简写) // routes: routes routes }); </script> ``` #### 5、挂载路由对象 修改Vue实例挂载,在挂载实例前使用use(路由对象)来挂载路由对象,若有多个路由对象(子目录)需要挂载,可以使用链式挂载方式`use(router1).use(router2).use(...).mount('#app');` ```html <script> Vue.createApp().use(router).mount('#app'); </script> ``` #### 6、调用路由 调用路由需要使用使用`<router-link>`标签来实现路由跳转,实质上为`<a>`标签,且需要定义路由出口用来显示路由跳转的内容。 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./assets/js/vue.global.js"></script> <script src="./assets/js/vue-router.global.js"></script> </head> <body> <div id="app"> <p> <!--这里使用router-link标签来实现路由跳转--> <router-link to="/home">Home</router-link><br> <router-link to="/news">News</router-link> </p> <!-- 路由出口(显示路由内容) --> <router-view></router-view> </div> <template id="home"> <div> <h2>首页</h2> </div> </template> <template id="news"> <div> <h2>新闻</h2> </div> </template> <script> // 1、定义路由组件 const Home = { template: '#home' }; const News = { template: '#news' }; // 2、定义路由规则(每个路径映射一个组件) const routes = [ { path: '/home', component: Home }, { path: '/news', component: News } ]; // 3、创建路由实例 const router = VueRouter.createRouter({ // 配置路由模式(哈希方式) history: VueRouter.createWebHashHistory(), // 路由规则(如果路由规则名为routes,那么可以简写) // routes: routes routes }); // 4、将路由对象挂载到Vue实例 Vue.createApp().use(router).mount('#app'); </script> </body> </html> ``` #### 7、根路由 实现上面的例子后会发现在启动项目时没有默认显示首页,必须点击后才能显示首页(home),所以要在路由规则中添加对根目录的路由规则。 ```html <script> // 定义根路由 const routes = [ { path: '/', component: Home }, { path: '/home', component: Home }, { path: '/news', component: News } ]; </script> ``` #### 8、路由重定向 默认首页也可以通过编写路由重定向规则来实现。 ```html <script> // 定义根路由 const routes = [ { path: '/', redirect: '/home' }, { path: '/home', component: Home }, { path: '/news', component: News } ]; </script> ``` ## 四、嵌套路由 #### 1、创建子路由模板 ```html <template id="login"> <div> <h2>登录</h2> </div> </template> <template id="reg"> <div> <h2>注册</h2> </div> </template> ``` #### 2、定义路由组件 ```html <script> const Login = { template: '#login' }; const Reg = { template: '#reg' }; </script> ``` #### 3、定义路由规则 因为是嵌套的子路由,所以在需要嵌套的路由中添加`children`属性,其值与`routes`写法并无两样,需要注意的是路径要写到`/`根目录的全路径。 ```html <script> const routes = [ { path: '/', redirect: '/home' }, { path: '/home', component: Home, children: [ { path: '/home', redirect: '/home/login' }, { path: '/home/login', component: Login }, { path: '/home/reg', component: Reg } ], }, { path: '/news', component: News } ]; </script> ``` #### 5、挂载路由对象 修改Vue实例挂载,在挂载实例前使用use(路由对象)来挂载路由对象,若有多个路由对象(子目录)需要挂载,可以使用链式挂载方式`use(router1).use(router2).use(...).mount('#app');` ```html <script> Vue.createApp().use(router).mount('#app'); </script> ``` #### 6、调用路由 修改父路由的模板内容,在模板里添加`<router-link>`标签与`<router-view>`标签 ```html <template id="home"> <div> <h2>首页</h2> <router-link to="/home/login">登录</router-link> <br> <router-link to="/home/reg">注册</router-link> <router-view></router-view> </div> </template> ``` ## 五、路由传参 在进行路由跳转时跳转到的页面可能需要某些参数来完成页面的渲染,这时就可以用到路由传参。 #### 1、`params`传参(restful风格) 首先需要修改路由规则中每个URL对应的组件,为其属性`name`赋值并将URL改为动态URL`/:参数名/`,之后将`<router-link>`标签的`to`属性绑定,在里面声明一个对象,其`name`属性代表对应组件的`name`属性,`params`属性用来存放参数对象,在路由的模板中可以使用`$route.params.参数名`来调用参数 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./assets/js/vue.global.js"></script> <script src="./assets/js/vue-router.global.js"></script> </head> <body> <div id="app"> <p> <!--这里使用router-link标签来实现路由跳转--> <router-link to="/home">Home</router-link> <br> <router-link :to="{name:'News',params:{id:id,name:name}}">News</router-link> </p> <!-- 路由出口(显示路由内容) --> <router-view></router-view> </div> <template id="home"> <div> <h2>首页</h2> </div> </template> <template id="news"> <div> <h2>新闻</h2> 参数:<span v-text="$route.params.id"></span><br> 参数:<span v-text="$route.params.name"></span> </div> </template> <script> // 1、定义路由组件 const Home = { template: '#home' }; const News = { template: '#news' }; // 2、定义路由规则(每个路径映射一个组件) const routes = [ { path: '/', redirect: '/home' }, { path: '/home', name: 'Home', component: Home }, { path: '/news/:id/:name', name: 'News', component: News } ]; // 3、创建路由实例 const router = VueRouter.createRouter({ // 配置路由模式(哈希方式) history: VueRouter.createWebHashHistory(), // 路由规则(如果路由规则名为routes,那么可以简写) // routes: routes routes }); // 4、将路由对象挂载到Vue实例 Vue.createApp({ data() { return { id: 12, name: '张三' } } }).use(router).mount('#app'); </script> </body> </html> ``` **注意**:在Vue3的[4.1.4](https://github.com/vuejs/router/compare/v4.1.3...v4.1.4) (2022-08-22更新)版本后,非restful风格的params传参被移除。详见:[router/packages/router/CHANGELOG.md at main · vuejs/router](https://github.com/vuejs/router/blob/main/packages/router/CHANGELOG.md#414-2022-08-22) #### 2、`query`传参 首先将`<router-link>`标签的`to`属性绑定,在里面声明一个对象,其`path`属性代表对应组件的`path`属性,`query`属性用来存放参数对象,在路由的模板中可以使用`$route.query.参数名`来调用参数 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./assets/js/vue.global.js"></script> <script src="./assets/js/vue-router.global.js"></script> </head> <body> <div id="app"> <p> <!--这里使用router-link标签来实现路由跳转--> <router-link to="/home">Home</router-link> <br> <router-link :to="{path:'/news',query:{id:id,name:name}}">News</router-link> </p> <!-- 路由出口(显示路由内容) --> <router-view></router-view> </div> <template id="home"> <div> <h2>首页</h2> </div> </template> <template id="news"> <div> <h2>新闻</h2> 参数:<span v-text="$route.query.id"></span><br> 参数:<span v-text="$route.query.name"></span> </div> </template> <script> // 1、定义路由组件 const Home = { template: '#home' }; const News = { template: '#news' }; // 2、定义路由规则(每个路径映射一个组件) const routes = [ { path: '/', redirect: '/home' }, { path: '/home', component: Home }, { path: '/news', component: News } ]; // 3、创建路由实例 const router = VueRouter.createRouter({ // 配置路由模式(哈希方式) history: VueRouter.createWebHashHistory(), // 路由规则(如果路由规则名为routes,那么可以简写) // routes: routes routes }); // 4、将路由对象挂载到Vue实例 Vue.createApp({ data() { return { id: 12, name: '张三' } } }).use(router).mount('#app'); </script> </body> </html> ``` #### 3、两种方式的区别 | **对比项** | **query方式** | **params方式** | | ------------------ | ------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | | **URL显示形式** | 参数以`?key=value` 形式附加在URL后,如:`/path?name=John&age=20` | 参数作为路径的一部分,如:`/user/123`(需在路由配置中定义占位符,如 `/user/:id`) | | **路由配置** | 无需在路由配置中声明参数,可直接使用 | 必须在路由配置中通过占位符(如`:id`)声明参数,否则参数不会生效 | | **参数传递方式** | 通过`router.push({ path: '/path', query: { name: 'John' } })` 传递 | 通过`router.push({ name: 'user', params: { id: 123 } })` 传递(需用命名路由) | | **参数获取方式** | 在组件中通过`this.$route.query.name` 获取 | 在组件中通过`this.$route.params.id` 获取 | | **参数类型支持** | 支持传递任意类型参数(如字符串、数字、数组等),但URL中会强制转换为字符串 | 支持任意类型参数,但URL路径中会以字符串形式显示,需手动转换类型 | | **参数是否必传** | 参数可选,URL中可省略 | 若路由配置中声明了占位符(如`/:id`),则参数必传,否则跳转失败 | | **浏览器刷新** | 刷新页面后参数保留在URL中,数据不会丢失 | 刷新页面后参数仍保留在URL路径中,但需确保路由配置匹配,否则可能丢失参数 | | **适用场景** | 适合可选参数(如搜索筛选、分页参数) | 适合必传参数(如资源ID、详情页标识) | | **SEO友好性** | 由于参数明文显示,对搜索引擎更友好 | 参数作为路径的一部分,结构清晰,但动态路径可能需额外SEO处理 | | **示例代码** | ```js router.push({ path: '/search', query: { keyword: 'vue' } }) ``` | ```js router.push({ name: 'UserDetail', params: { userId: 123 } }) ``` | ## 六、编程式路由 编程式路由可以通过逻辑来判断路由到哪里去,所以不能使用`<router-link>`标签进行路由转跳了,需要使用自定义方法来进行转跳,触发自定义方法的方式任选,在此用按钮为例。 #### 1、创建路由导航 修改挂载标签的内容 ```html <div id="app"> <p> <button @click="toHome">首页</button> <button @click="toNews">新闻</button> <button @click="toLogin">登录</button> <br> <button @click="toPlace(1)">前进</button> <button @click="toPlace(-1)">后退</button> </p> <!-- 路由出口(显示路由内容) --> <router-view></router-view> </div> ``` #### 2、配置路由 ```html <script> // 1、定义路由组件 const Home = { template: '#home' }; const News = { template: '#news' }; const Login = { template: '#login' }; // 2、定义路由规则(每个路径映射一个组件) const routes = [ { path: '/', redirect: '/home' }, { path: '/home', component: Home }, { path: '/news', component: News }, { path: '/login/:id/:name', name: 'Login', component: Login } ]; // 3、创建路由实例 const router = VueRouter.createRouter({ // 配置路由模式(哈希方式) history: VueRouter.createWebHashHistory(), // 路由规则(如果路由规则名为routes,那么可以简写) // routes: routes routes }); </script> ``` **注意**:使用`params`方式传参时,路径必须为动态路径,且参数必须传入。 #### 3、挂载路由 在上一步后面追加,要写自定义方法,使用`this.$router.push()`方法进行路由转跳,参数是一个路由地址对象,写法与`<router-link>`中的`:on`已绑定属性相同,若路由不传参则直接写路径字符串即可。 ```html <script> // 4、将路由对象挂载到Vue实例 Vue.createApp({ data() { return { userId: 100, userName: '张三' } }, methods: { toHome() { this.$router.push('/home'); }, toNews() { this.$router.push({ path: '/news', query: { id: this.userId, name: this.userName } }); }, toLogin() { this.$router.push({ name: 'Login', params: { id: this.userId, name: this.userName } }); }, toPlace(value) { // 方式一 // if (value===1){ // this.$router.forward(); // }else if (value===-1){ // this.$router.back(); // } // 方式二 this.$router.go(value); } } }).use(router).mount('#app'); </script> ``` **注意**:`this.$router.go()`方法传入整型参数,绝对值为前进/回退的页数,符号为正是前进,符号为负是后退。 ## 七、路由监听 路由监听是用Vue实例的`watch`属性实现的,实现方法与属性监听器的方法一样,都是用属性名来命名,所以这里用`$route`来命名方法,参数依旧有两个`newValue`、`oldValue`。 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./assets/js/vue.global.js"></script> <script src="./assets/js/vue-router.global.js"></script> </head> <body> <div id="app"> <p> <!--这里使用router-link标签来实现路由跳转--> <router-link to="/home">Home</router-link> <br> <router-link to="/news">News</router-link> </p> <!-- 路由出口(显示路由内容) --> <router-view></router-view> </div> <template id="home"> <div> <h2>首页</h2> </div> </template> <template id="news"> <div> <h2>新闻</h2> </div> </template> <script> // 1、定义路由组件 const Home = { template: '#home' }; const News = { template: '#news' }; // 2、定义路由规则(每个路径映射一个组件) const routes = [ { path: '/', redirect: '/home' }, { path: '/home', component: Home }, { path: '/news', component: News } ]; // 3、创建路由实例 const router = VueRouter.createRouter({ // 配置路由模式(哈希方式) history: VueRouter.createWebHashHistory(), // 路由规则(如果路由规则名为routes,那么可以简写) // routes: routes routes }); // 4、将路由对象挂载到Vue实例 Vue.createApp({ watch: { // 路由监听 $route(newValue, oldValue) { console.log(newValue, oldValue); } } }).use(router).mount('#app'); </script> </body> </html> ``` ## 八、导航守卫 #### 1、概念 导航守卫也叫做路由守卫,是用来在路由转跳之前做一些验证,比如说登录验证。 #### 2、使用方法 可以通过`router.beforeEach((to,from,next)=>{})`方法来注册一个全局前置守卫,每个守卫方法由三个参数: * to:即将要进入的目标路由对象(转跳目标页面),可以用`to.path`来获取即将要进入的路由地址; * from:当前导航正要离开的路由地址(当前页面),可以用`from.path`来获取正要离开的路由地址; * next:是一个函数,表示验证通过继续执行,直接用`next()`调用即可 #### 3、示例 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./assets/js/vue.global.js"></script> <script src="./assets/js/vue-router.global.js"></script> </head> <body> <div id="app"> <p> <button @click="toHome">首页</button> <button @click="toNews">新闻</button> <button @click="toLogin">登录</button> <br> <button @click="toPlace(1)">前进</button> <button @click="toPlace(-1)">后退</button> </p> <!-- 路由出口(显示路由内容) --> <router-view></router-view> </div> <template id="home"> <div> <h2>首页</h2> </div> </template> <template id="news"> <div> <h2>新闻</h2> 参数:<span v-text="$route.query.id"></span><br> 参数:<span v-text="$route.query.name"></span> </div> </template> <template id="login"> <div> <h2>登录</h2> </div> </template> <script> // 1、定义路由组件 const Home = { template: '#home' }; const News = { template: '#news' }; const Login = { template: '#login' }; // 2、定义路由规则(每个路径映射一个组件) const routes = [ { path: '/', redirect: '/login' }, { path: '/home', component: Home }, { path: '/news', component: News }, { path: '/login', component: Login } ]; // 3、创建路由实例 const router = VueRouter.createRouter({ // 配置路由模式(哈希方式) history: VueRouter.createWebHashHistory(), // 路由规则(如果路由规则名为routes,那么可以简写) // routes: routes routes }); // 4、添加路由守卫 router.beforeEach((to, from, next) => { // 创建守卫规则 const rule = ['/home', '/news']; // 模拟登录状态 let isLogin = false; if (rule.indexOf(to.path) >= 0) { if (!isLogin){ console.log('未登录'); router.push('/login'); } } // 验证通过继续向下执行 next(); }); // 5、将路由对象挂载到Vue实例 Vue.createApp({ data() { return { userId: 100, userName: '张三' } }, methods: { toHome() { this.$router.push('/home'); }, toNews() { this.$router.push({ path: '/news', query: { id: this.userId, name: this.userName } }); }, toLogin() { this.$router.push('/login'); }, toPlace(value) { // 方式一 // if (value===1){ // this.$router.forward(); // }else if (value===-1){ // this.$router.back(); // } // 方式二 this.$router.go(value); } } }).use(router).mount('#app'); </script> </body> </html> ``` 最后修改:2025 年 10 月 25 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 👆请简单粗暴地爱我。