一:路由简介
- 路由就是一组key-value的对应关系
- 多个路由,需经过路由器进行管理
SPA应用:single page web application(单页面web应用)
Vue-router
一:相关理解
- vue-router:vue的一个插件库(需安装--npm install vue-router --save),专门用来实现SPA应用
- 对SPA应用的理解
- single page web application(单页面web应用)
- 整个应用只有一个完整的页面
- 点击页面中的导航链接不会刷新页面,只会做页面的局部更新
- 数据要通过ajax请求获取
- 路由的理解(什么是路由?)
- 一个路由就是一组映射关系(key-value)
- key为路径,value可能是function或component
- 路由分类
- 后端路由
- 理解:value是function,用于处理客户端提交的请求
- 工作过程:服务器接收到一个请求时,根据请求路径找到匹配的函数来处理请求,返回响应数据
- 前端路由
- 理解:value是component,用于展示页面内容
- 工作过程:当浏览器的路径改变时,对应的组件就会显示
- 后端路由
二:基本路由(学习资料:https://router.vuejs.org/zh/installation.html)
安装应用路由
第一步:安装vue-router
npm install vue-router@3 --save 对应 vue2
npm install vue-router@4 --对应vue3
第二步:应用插件并编写router配置项(src/router创建文件并新增index.js——用于定义路由)
1 import Vue from 'vue' 2 import VueRouter from 'vue-router' 3 import Home from '../views/Home.vue' 4 import About from '../views/About.vue' 5 6 //Vue中使用router插件 7 Vue.use(VueRouter) 8 9 //路由配置,配置路由路径与组件的对应关系 10 const routes = [ 11 { 12 path: '/home', 13 name: 'Home', 14 component: () => import('../views/Home.vue') 15 }, 16 { 17 path: '/about', 18 name: 'About', 19 component: () => import('../views/About.vue') 20 }, 21 {//根路由--默认 22 path: '/', 23 redirect: '/home' 24 } 25 ] 26 27 //新建路由实例 28 const router = new VueRouter({ 29 routes 30 }) 31 32 //导出路由实例,在main.js中导入使用 33 export default router
第三步:main.js文件——用于引入路由
1 // 引入Vue 2 import Vue from 'vue' 3 // 引入App 4 import App from './App.vue' 5 //导入路由router 6 import router from './router' 7 8 // 配置提示 9 Vue.config.productionTip = false 10 11 new Vue({ 12 router, //在vue实例中使用router 13 render: h => h(App) 14 }).$mount('#app')
第四步:App.vue——在app中引入路由(router-link:实现组件切换;router-view:指定展示位置)
1 <template> 2 <div> 3 <nav> 4 <router-link style="margin: 10px;" 5 to="/Home">Home</router-link> 6 <router-link to="/About">About</router-link>
<!--指定展示位置--> 7 <router-view></router-view> 8 </nav> 9 </div> 10 </template> 11 12 <script> 13 // 引入组件 14 // import Home from './components/Home.vue'; 15 // import About from './components/About.vue'; 16 export default { 17 name: 'App', 18 // components: { Home, About }, 19 20 21 } 22 </script> 23 24 <style scoped> 25 </style>
示例一:路由组件 + 一般组件
main.js
1 // 引入Vue 2 import Vue from 'vue' 3 // 引入App 4 import App from './App.vue' 5 //导入路由router 6 import router from './router' 7 8 // 配置提示 9 Vue.config.productionTip = false 10 11 new Vue({ 12 router, //在vue实例中注册使用router 13 render: h => h(App) 14 }).$mount('#app')
index.js
1 import Vue from 'vue' 2 import VueRouter from 'vue-router' 3 import Home from '../views/Home.vue' 4 import About from '../views/About.vue' 5 6 //Vue中使用router插件 7 Vue.use(VueRouter) 8 9 //路由配置,配置路由路径与组件的对应关系 10 const routes = [ 11 { 12 path: '/home', 13 name: 'Home', 14 component: () => import('../views/Home.vue') 15 }, 16 { 17 path: '/about', 18 name: 'About', 19 component: () => import('../views/About.vue') 20 }, 21 {//根路由--默认 22 path: '/', 23 redirect: '/home' 24 } 25 ] 26 27 //新建路由实例 28 const router = new VueRouter({ 29 routes 30 }) 31 32 //导出路由实例,在main.js中导入使用 33 export default router
Banner.vue
1 <template> 2 <h2>Vue Router Demo</h2> 3 </template> 4 5 <script> 6 export default { 7 name: 'Banner', 8 } 9 </script> 10 11 <style> 12 </style>
About.vue
1 <template> 2 <div> 3 <h3>about page</h3> 4 </div> 5 </template> 6 7 <script> 8 export default { 9 name: 'About', 10 11 } 12 </script> 13 14 <style> 15 </style>
Home.vue
1 <template> 2 <div> 3 <h3>home page</h3> 4 </div> 5 </template> 6 7 <script> 8 export default { 9 name: 'Home', 10 11 } 12 </script> 13 14 <style> 15 </style>
App.vue
<template> <div> <div> <!-- 一般组件 需要引入+注册 --> <Banner /> </div> <div> <!-- 路由组件 --> <router-link style="margin: 10px;" to="/Home">Home</router-link> <router-link to="/About">About</router-link> <router-view> <!-- 用于填充路由组件 --> </router-view> </div> </div> </template> <script> // 引入组件 import Banner from './components/Banner.vue'; export default { name: 'App', components: { Banner }, } </script> <style scoped> </style>
总结==》
- 路由组件通常存放在views(pages)文件夹中,一般组件通常存放在components文件夹中
- 通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载
- 每个组件都有自己的$router属性,里面存储着自己的路由信息--图上图所示
- 整个应用只有一个router,可以通过组件的$router属性获取到
三:嵌套路由
index.js
1 import Vue from 'vue' 2 import VueRouter from 'vue-router' 3 import Home from '../views/Home.vue' 4 import About from '../views/About.vue' 5 import News from '@/views/home/News.vue' 6 import Message from '@/views/home/Message.vue' 7 8 //Vue中使用router插件 9 Vue.use(VueRouter) 10 11 //路由配置,配置路由路径与组件的对应关系 12 const routes = [ 13 { 14 path: '/home', 15 name: 'Home', 16 component: () => import('../views/Home.vue'), 17 children: [ 18 { 19 path: '/home/news',//path最左侧/代表根路径 20 component: News 21 }, 22 { 23 path: 'Message',//这里没有用/ 表示相对路径 24 component: Message, 25 }, 26 { 27 path: '', 28 redirect: '/home/News' 29 } 30 ] 31 }, 32 { 33 path: '/about', 34 name: 'About', 35 component: () => import('../views/About.vue'), 36 }, 37 {//根路由--默认 38 path: '/', 39 redirect: '/home' 40 } 41 ] 42 43 //新建路由实例 44 const router = new VueRouter({ 45 routes 46 }) 47 48 //导出路由实例,在main.js中导入使用 49 export default router
Home.vue
1 <template> 2 <div> 3 <h3>home page</h3> 4 <div> 5 <ul class="nav nav-tabs"> 6 <li style="margin: 10px;"><router-link to="/home/News">News</router-link></li> 7 <li style="margin: 10px;"><router-link to="/home/Message">Message</router-link></li> 8 </ul> 9 10 <router-view></router-view> 11 </div> 12 </div> 13 </template> 14 15 <script> 16 export default { 17 name: 'Home', 18 19 } 20 </script> 21 22 <style> 23 </style>
总结:
三:路由传参(query)
示例如下:
index.js
1 import Vue from 'vue' 2 import VueRouter from 'vue-router' 3 import Home from '../views/Home.vue' 4 import About from '../views/About.vue' 5 import News from '@/views/home/News.vue' 6 import Message from '@/views/home/Message.vue' 7 import Detail from '@/views/home/Detail.vue' 8 9 //Vue中使用router插件 10 Vue.use(VueRouter) 11 12 //路由配置,配置路由路径与组件的对应关系 13 const routes = [ 14 { 15 path: '/home', 16 name: 'Home', 17 component: () => import('../views/Home.vue'), 18 children: [ 19 { 20 path: '/home/news',//path最左侧/代表根路径 21 component: News 22 }, 23 { 24 path: 'Message',//这里没有用/ 表示相对路径 25 component: Message, 26 children: [ 27 { 28 path: '/home/detail',//path最左侧/代表根路径 29 component: Detail 30 }, 31 ] 32 }, 33 { 34 path: '', 35 redirect: '/home/News' 36 } 37 ] 38 }, 39 { 40 path: '/about', 41 name: 'About', 42 component: () => import('../views/About.vue'), 43 }, 44 {//根路由--默认 45 path: '/', 46 redirect: '/home' 47 } 48 ] 49 50 //新建路由实例 51 const router = new VueRouter({ 52 routes 53 }) 54 55 //导出路由实例,在main.js中导入使用 56 export default router
Message.vue
1 <template> 2 <div> 3 <h3>Message page</h3> 4 <ul> 5 <li v-for="m in messageList" 6 :key="m.id"> 7 <!-- 传参方式一:跳转路由并携带query参数, to的字符串写法 --> 8 <!-- <router-link :to="`/home/detail/?id=${m.id}&title=${m.title}`">{{ m.title }}</router-link> --> 9 10 <!-- 传参方式二:跳转路由并携带query参数, to的对象写法 --> 11 <router-link :to="{ 12 path: '/home/detail', 13 query: { 14 id:m.id, 15 title:m.title 16 } 17 }"> 18 {{ m.title }} 19 </router-link> 20 </li> 21 </ul> 22 <hr> 23 <router-view></router-view> 24 </div> 25 </template> 26 27 <script> 28 export default { 29 name: 'Message', 30 data () { 31 return { 32 messageList: [ 33 { id: '001', title: 'message 001' }, 34 { id: '002', title: 'message 002' }, 35 { id: '003', title: 'message 003' }, 36 ] 37 } 38 } 39 40 } 41 </script> 42 43 <style> 44 </style>
Detail.vue
1 <template> 2 <ul> 3 <li>消息编号:{{ $route.query.id }}</li> 4 <li>消息标题:{{ $route.query.title }}</li> 5 6 </ul> 7 </template> 8 9 <script> 10 export default { 11 name: 'Detail', 12 mounted () { 13 console.log('$route==》', this.$route) 14 }, 15 } 16 </script> 17 18 <style> 19 </style>
四:路由命名(name)
注:简化写法中,对象写法中,如果使用 path 代替 name 则需写完整路径。
五:路由传参(params)
示例如下所示:
index.js
1 import Vue from 'vue' 2 import VueRouter from 'vue-router' 3 import Home from '../views/Home.vue' 4 import About from '../views/About.vue' 5 import News from '@/views/home/News.vue' 6 import Message from '@/views/home/Message.vue' 7 import Detail from '@/views/home/Detail.vue' 8 9 //Vue中使用router插件 10 Vue.use(VueRouter) 11 12 //路由配置,配置路由路径与组件的对应关系 13 const routes = [ 14 { 15 path: '/home', 16 name: 'Home', 17 component: () => import('../views/Home.vue'), 18 children: [ 19 { 20 path: '/home/news',//path最左侧/代表根路径 21 component: News 22 }, 23 { 24 path: 'Message',//这里没有用/ 表示相对路径 25 component: Message, 26 children: [ 27 { 28 name: 'detail', 29 path: '/home/detail/:id/:title',//path最左侧/代表根路径 30 component: Detail 31 }, 32 ] 33 }, 34 { 35 path: '', 36 redirect: '/home/News' 37 } 38 ] 39 }, 40 { 41 path: '/about', 42 name: 'About', 43 component: () => import('../views/About.vue'), 44 }, 45 {//根路由--默认 46 path: '/', 47 redirect: '/home' 48 } 49 ] 50 51 //新建路由实例 52 const router = new VueRouter({ 53 routes 54 }) 55 56 //导出路由实例,在main.js中导入使用 57 export default router
Message.vue
1 <template> 2 <div> 3 <h3>Message page</h3> 4 <ul> 5 <li v-for="m in messageList" 6 :key="m.id"> 7 <!-- query传参方式一:跳转路由并携带query参数, to的字符串写法 --> 8 <!-- <router-link :to="`/home/detail/?id=${m.id}&title=${m.title}`">{{ m.title }}</router-link> --> 9 10 <!-- query传参方式二:跳转路由并携带query参数, to的对象写法 --> 11 <!-- <router-link :to="{ 12 path: '/home/detail', 13 query: { 14 id:m.id, 15 title:m.title 16 } 17 }"> 18 {{ m.title }} 19 </router-link> --> 20 21 <!-- params传参方式一:跳转路由并携带参数, to的字符串写法 --> 22 <!-- <router-link :to="`/home/detail/${m.id}/${m.title}`">{{ m.title }}</router-link> --> 23 24 <!-- params传参方式二:跳转路由并携带query参数, to的对象写法 25 注:params 对象写法必须使用name 替代path 26 --> 27 <router-link :to="{ 28 // path: '/home/detail', 29 name:'detail', 30 params: { 31 id:m.id, 32 title:m.title 33 } 34 }"> 35 {{ m.title }} 36 </router-link> 37 </li> 38 </ul> 39 <hr> 40 <router-view></router-view> 41 </div> 42 </template> 43 44 <script> 45 export default { 46 name: 'Message', 47 data () { 48 return { 49 messageList: [ 50 { id: '001', title: 'message 001' }, 51 { id: '002', title: 'message 002' }, 52 { id: '003', title: 'message 003' }, 53 ] 54 } 55 } 56 57 } 58 </script> 59 60 <style> 61 </style>
Detail
1 <template> 2 <ul> 3 <li>消息编号:{{ $route.params.id }}</li> 4 <li>消息标题:{{ $route.params.title }}</li> 5 6 </ul> 7 </template> 8 9 <script> 10 export default { 11 name: 'Detail', 12 mounted () { 13 console.log('$route==》', this.$params) 14 }, 15 } 16 </script> 17 18 <style> 19 </style>
六:路由的props配置
总结:
配置路由的props有三种写法:(对象写法、bool值写法、函数写法)
- 对象写法:不建议使用,传值固定
- eg:props: {a:1,b:'你好'}
- 在组件中取值: props: ['a', 'b'],
- bool值写法:bool值
-
props: true--若只为真,就会把该路由组件收到的说有params(不能接受到query参数)参数以props的形式传给对应组件
- 值适用于获取param参数,不能用于query参数
-
- 值为函数写法:可操作params参数,同时也可操作query参数
- 不确定参数类型--建议用法
-
props ($route) { // return { id: $route.query.id, title: $route.query.title } return { id: $route.params.id, title: $route.params.title } }
-
- 确定参数类型--以params为例
-
结构赋值
// props ({ query }) { //结构赋值 props ({ params }) { // return { id: $route.query.id, title: $route.query.title } return { id: params.id, title: params.title } }
- 连续结构赋值
-
// 结构赋值连续写法 props ({ params: { id, title } }) { // return { id: $route.query.id, title: $route.query.title } return { id, title } }
-
- 不确定参数类型--建议用法
示例如下所示:
index.js
1 import Vue from 'vue' 2 import VueRouter from 'vue-router' 3 import Home from '../views/Home.vue' 4 import About from '../views/About.vue' 5 import News from '@/views/home/News.vue' 6 import Message from '@/views/home/Message.vue' 7 import Detail from '@/views/home/Detail.vue' 8 9 //Vue中使用router插件 10 Vue.use(VueRouter) 11 12 //路由配置,配置路由路径与组件的对应关系 13 const routes = [ 14 { 15 path: '/home', 16 name: 'Home', 17 component: () => import('../views/Home.vue'), 18 children: [ 19 { 20 path: '/home/news',//path最左侧/代表根路径 21 component: News 22 }, 23 { 24 path: 'Message',//这里没有用/ 表示相对路径 25 component: Message, 26 children: [ 27 { 28 name: 'detail', 29 path: '/home/detail/:id/:title',//path最左侧/代表根路径 30 component: Detail, 31 32 // props写法一:值为对象,该对象中的所有key-value都会以props的形式传给Detail组件 33 // props: {a:1,b:'你好'} //不常用,传固定值 34 35 // props写法二:值为bool,若值为真--就会把该路由组件收到的说有params(不能接受到query参数)参数以props的形式传给Detail组件 36 // props: true 37 38 // props写法三:值为函数 39 props ($route) { 40 // return { id: $route.query.id, title: $route.query.title } 41 return { id: $route.params.id, title: $route.params.title } 42 } 43 44 // props ({ query }) { //结构赋值 45 // props ({ params }) { 46 // // return { id: $route.query.id, title: $route.query.title } 47 // return { id: params.id, title: params.title } 48 // } 49 50 // 结构赋值连续写法 51 // props ({ params: { id, title } }) { 52 // // return { id: $route.query.id, title: $route.query.title } 53 // return { id, title } 54 // } 55 56 }, 57 ] 58 }, 59 { 60 path: '', 61 redirect: '/home/News' 62 } 63 ] 64 }, 65 { 66 path: '/about', 67 name: 'About', 68 component: () => import('../views/About.vue'), 69 }, 70 {//根路由--默认 71 path: '/', 72 redirect: '/home' 73 } 74 ] 75 76 //新建路由实例 77 const router = new VueRouter({ 78 routes 79 }) 80 81 //导出路由实例,在main.js中导入使用 82 export default router
Detail.vue
1 <template> 2 <ul> 3 <li>消息编号:{{id}}</li> 4 <li>消息标题:{{title}}</li> 5 6 </ul> 7 </template> 8 9 <script> 10 export default { 11 name: 'Detail', 12 // props: ['a', 'b'], 13 props: ['id', 'title'], 14 computed: { 15 16 }, 17 mounted () { 18 console.log('$route==》', this.$route) 19 }, 20 } 21 </script> 22 23 <style> 24 </style>
七:router-link的redirect属性
如下所示,注:当使用replace属性后,浏览器中的地址信息将不被记录——即,将导致操作后,无退回操作
1 <!-- 路由组件 --> 2 <router-link replace 3 style="margin: 10px;" 4 to="/Home">Home</router-link> 5 <router-link :replace="true" 6 to="/About">About</router-link>
注:浏览器地址栏左侧←→将不会有变化