路由
-
理解: 一个路由(route)就是一组映射关系(key - value),多个路由需要路由器(router)进行管理。
-
1.基本使用
1. 安装vue-router,命令:npm i vue-router 2. 应用插件:Vue.use(VueRouter) 3. 编写router配置项: //引入VueRouter import VueRouter from 'vue-router' //引入Luyou 组件 import About from '../components/About' import Home from '../components/Home' //创建router实例对象,去管理一组一组的路由规则 const router = new VueRouter({ routes:[ { path:'/about', component:About }, { path:'/home', component:Home } ] }) //暴露router export default router 4. 实现切换(active-class可配置高亮样式) <router-link active-class="active" to="/about">About</router-link> 5. 指定展示位置 <router-view></router-view>
2.几个注意点
1. 路由组件通常存放在pages文件夹,一般组件通常存放在components文件夹。
2. 通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载。
3. 每个组件都有自己的$route属性,里面存储着自己的路由信息。
4. 整个应用只有一个router,可以通过组件的$router属性获取到。
路由的基本使用
1 import Vue from 'vue' 2 import App from './App.vue' 3 4 Vue.config.productionTip = false 5 6 import VueRouter from "vue-router"; 7 Vue.use(VueRouter) 8 import router from './router' 9 10 new Vue({ 11 el:"#app", 12 render: h => h(App), 13 beforeCreate() { 14 //安装全局事件总线 15 Vue.prototype.$bus = this 16 }, 17 router:router 18 })
1 import VueRouter from "vue-router" 2 import About from "@/pages/About"; 3 import Home from "@/pages/Home"; 4 5 //创建并暴露一个路由器 6 export default new VueRouter({ 7 routes:[ 8 { 9 path:'/about', 10 component:About 11 }, 12 { 13 path:'/home', 14 component:Home 15 } 16 ] 17 })
1 <template> 2 <div> 3 <div class="row"> 4 <Banner></Banner> 5 </div> 6 <div class="row"> 7 <div class="col-xs-2 col-xs-offset-2"> 8 <div class="list-group"> 9 <!-- <a class="list-group-item active" href="./about.html">About</a>--> 10 <!-- <a class="list-group-item" href="./home.html">Home</a>--> 11 12 <router-link class="list-group-item" active-class="active" to="/about">About</router-link> 13 <router-link class="list-group-item" active-class="active" to="./home">Home</router-link> 14 </div> 15 </div> 16 <div class="col-xs-6"> 17 <div class="panel"> 18 <div class="panel-body"> 19 <!-- 位置 --> 20 <router-view></router-view> 21 </div> 22 </div> 23 </div> 24 </div> 25 </div> 26 </template> 27 <script> 28 import Banner from "@/components/Banner"; 29 30 export default { 31 name:'App', 32 components:{Banner}, 33 } 34 </script>
1 <template> 2 <h2>我是About的内容</h2> 3 </template> 4 5 <script> 6 export default { 7 name: "About" 8 } 9 </script> 10 11 <style scoped> 12 13 </style>
1 <template> 2 <h2>我是Home的内容</h2> 3 </template> 4 5 <script> 6 export default { 7 name: "Home" 8 } 9 </script> 10 11 <style scoped> 12 13 </style>
1 <template> 2 <div class="col-xs-offset-2 col-xs-8"> 3 <div class="page-header"><h2>Vue Router Demo</h2></div> 4 </div> 5 </template> 6 7 <script> 8 export default { 9 name: "Banner" 10 } 11 </script> 12 13 <style scoped> 14 15 </style>
1. 配置路由规则,使用children配置项: routes:[ { path:'/about', component:About, }, { path:'/home', component:Home, children:[ //通过children配置子级路由 { path:'news', //此处一定不要写:/news component:News }, { path:'message',//此处一定不要写:/message component:Message } ] } ] 2. 跳转(要写完整路径): <router-link to="/home/news">News</router-link>
多级路由
1 import Vue from 'vue' 2 import App from './App.vue' 3 4 Vue.config.productionTip = false 5 6 import VueRouter from "vue-router"; 7 Vue.use(VueRouter) 8 import router from './router' 9 10 new Vue({ 11 el:"#app", 12 render: h => h(App), 13 beforeCreate() { 14 //安装全局事件总线 15 Vue.prototype.$bus = this 16 }, 17 router:router 18 })
1 import VueRouter from "vue-router" 2 import About from "@/pages/About"; 3 import Home from "@/pages/Home"; 4 import News from "@/pages/News"; 5 import Message from "@/pages/Message"; 6 7 //创建并暴露一个路由器 8 export default new VueRouter({ 9 routes:[ 10 { 11 path:'/about', 12 component:About 13 }, 14 { 15 path:'/home', 16 component:Home, 17 children:[ 18 { 19 path:'news', 20 component:News 21 }, 22 { 23 path: 'message', 24 component: Message 25 } 26 ] 27 } 28 ] 29 })
1 <template> 2 <div> 3 <div class="row"> 4 <Banner></Banner> 5 </div> 6 <div class="row"> 7 <div class="col-xs-2 col-xs-offset-2"> 8 <div class="list-group"> 9 <!-- <a class="list-group-item active" href="./about.html">About</a>--> 10 <!-- <a class="list-group-item" href="./home.html">Home</a>--> 11 12 <router-link class="list-group-item" active-class="active" to="/about">About</router-link> 13 <router-link class="list-group-item" active-class="active" to="./home">Home</router-link> 14 </div> 15 </div> 16 <div class="col-xs-6"> 17 <div class="panel"> 18 <div class="panel-body"> 19 <!-- 位置 --> 20 <router-view></router-view> 21 </div> 22 </div> 23 </div> 24 </div> 25 </div> 26 </template> 27 <script> 28 import Banner from "@/components/Banner"; 29 30 export default { 31 name:'App', 32 components:{Banner}, 33 } 34 </script>
1 <template> 2 <h2>我是About的内容</h2> 3 </template> 4 5 <script> 6 export default { 7 name: "About" 8 } 9 </script> 10 11 <style scoped> 12 13 </style>
1 <template> 2 <div> 3 <h2>Home组件内容</h2> 4 <div> 5 <ul class="nav nav-tabs"> 6 <li> 7 <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link> 8 </li> 9 <li> 10 <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link> 11 </li> 12 </ul> 13 <router-view></router-view> 14 </div> 15 </div> 16 </template> 17 18 <script> 19 export default { 20 name: "Home" 21 } 22 </script> 23 24 <style scoped> 25 26 </style>
1 <template> 2 <ul> 3 <li>news001</li> 4 <li>news002</li> 5 <li>news003</li> 6 </ul> 7 </template> 8 9 <script> 10 export default { 11 name: "News" 12 } 13 </script> 14 15 <style scoped> 16 17 </style>
1 <template> 2 <div> 3 <ul> 4 <li> 5 <a href="/message1">message001</a> 6 </li> 7 <li> 8 <a href="/message2">message002</a> 9 </li> 10 <li> 11 <a href="/message/3">message003</a> 12 </li> 13 </ul> 14 </div> 15 </template> 16 17 <script> 18 export default { 19 name: "Message" 20 } 21 </script> 22 23 <style scoped> 24 25 </style>
1 <template> 2 <div class="col-xs-offset-2 col-xs-8"> 3 <div class="page-header"><h2>Vue Router Demo</h2></div> 4 </div> 5 </template> 6 7 <script> 8 export default { 9 name: "Banner" 10 } 11 </script> 12 13 <style scoped> 14 15 </style>
4.路由的query参数
1. 传递参数 <!-- 跳转并携带query参数,to的字符串写法 --> <router-link :to="/home/message/detail?id=666&title=你好">跳转</router-link> <!-- 跳转并携带query参数,to的对象写法 --> <router-link :to="{ path:'/home/message/detail', query:{ id:666, title:'你好' } }" >跳转</router-link> 2. 接收参数: $route.query.id $route.query.title
路由的query参数
1 import Vue from 'vue' 2 import App from './App.vue' 3 4 Vue.config.productionTip = false 5 6 import VueRouter from "vue-router"; 7 Vue.use(VueRouter) 8 import router from './router' 9 10 new Vue({ 11 el:"#app", 12 render: h => h(App), 13 beforeCreate() { 14 //安装全局事件总线 15 Vue.prototype.$bus = this 16 }, 17 router:router 18 })
1 import VueRouter from "vue-router" 2 import About from "@/pages/About"; 3 import Home from "@/pages/Home"; 4 import News from "@/pages/News"; 5 import Message from "@/pages/Message"; 6 import Detail from "@/pages/Detail"; 7 8 //创建并暴露一个路由器 9 export default new VueRouter({ 10 routes:[ 11 { 12 path:'/about', 13 component:About 14 }, 15 { 16 path:'/home', 17 component:Home, 18 children:[ 19 { 20 path:'news', 21 component:News 22 }, 23 { 24 path: 'message', 25 component: Message, 26 children:[ 27 { 28 path:'detail', 29 component:Detail 30 } 31 ] 32 } 33 ] 34 } 35 ] 36 })
1 <template> 2 <div> 3 <div class="row"> 4 <Banner></Banner> 5 </div> 6 <div class="row"> 7 <div class="col-xs-2 col-xs-offset-2"> 8 <div class="list-group"> 9 <!-- <a class="list-group-item active" href="./about.html">About</a>--> 10 <!-- <a class="list-group-item" href="./home.html">Home</a>--> 11 12 <router-link class="list-group-item" active-class="active" to="/about">About</router-link> 13 <router-link class="list-group-item" active-class="active" to="./home">Home</router-link> 14 </div> 15 </div> 16 <div class="col-xs-6"> 17 <div class="panel"> 18 <div class="panel-body"> 19 <!-- 位置 --> 20 <router-view></router-view> 21 </div> 22 </div> 23 </div> 24 </div> 25 </div> 26 </template> 27 <script> 28 import Banner from "@/components/Banner"; 29 30 export default { 31 name:'App', 32 components:{Banner}, 33 } 34 </script>
1 <template> 2 <h2>我是About的内容</h2> 3 </template> 4 5 <script> 6 export default { 7 name: "About" 8 } 9 </script> 10 11 <style scoped> 12 13 </style>
1 <template> 2 <div> 3 <h2>Home组件内容</h2> 4 <div> 5 <ul class="nav nav-tabs"> 6 <li> 7 <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link> 8 </li> 9 <li> 10 <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link> 11 </li> 12 </ul> 13 <router-view></router-view> 14 </div> 15 </div> 16 </template> 17 18 <script> 19 export default { 20 name: "Home" 21 } 22 </script> 23 24 <style scoped> 25 26 </style>
1 <template> 2 <ul> 3 <li>news001</li> 4 <li>news002</li> 5 <li>news003</li> 6 </ul> 7 </template> 8 9 <script> 10 export default { 11 name: "News" 12 } 13 </script> 14 15 <style scoped> 16 17 </style>
1 <template> 2 <div> 3 <ul> 4 <li v-for="m in messageList" :key="m.id"> 5 <!--字符串写法--> 6 <!-- <router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{m.title}}</router-link> --> 7 <!--对象写法--> 8 <router-link :to="{ 9 path:'/home/message/detail', 10 query:{ 11 id:m.id, 12 title:m.title 13 } 14 }"> 15 {{m.title}} 16 </router-link> 17 </li> 18 </ul> 19 <hr> 20 <router-view></router-view> 21 </div> 22 </template> 23 24 <script> 25 export default { 26 name: "Message", 27 data(){ 28 return { 29 messageList:[ 30 {id:'001',title:'消息001'}, 31 {id:'002',title:'消息002'}, 32 {id:'003',title:'消息003'} 33 ] 34 } 35 } 36 } 37 </script> 38 39 <style scoped> 40 41 </style>
1 <template> 2 <ul> 3 <li>消息编号:{{$route.query.id}}</li> 4 <li>消息标题:{{$route.query.title}}</li> 5 </ul> 6 </template> 7 8 <script> 9 export default { 10 name: "Detail" 11 } 12 </script> 13 14 <style scoped> 15 16 </style>
1 <template> 2 <div class="col-xs-offset-2 col-xs-8"> 3 <div class="page-header"><h2>Vue Router Demo</h2></div> 4 </div> 5 </template> 6 7 <script> 8 export default { 9 name: "Banner" 10 } 11 </script> 12 13 <style scoped> 14 15 </style>
5.命名路由
1. 作用:可以简化路由的跳转。 2. 如何使用 (1) 给路由命名: { path:'/demo', component:Demo, children:[ { path:'test', component:Test, children:[ { name:'hello' //给路由命名 path:'welcome', component:Hello, } ] } ] } (2) 简化跳转: <!--简化前,需要写完整的路径 --> <router-link to="/demo/test/welcome">跳转</router-link> <!--简化后,直接通过名字跳转 --> <router-link :to="{name:'hello'}">跳转</router-link> <!--简化写法配合传递参数 --> <router-link :to="{ name:'hello', query:{ id:666, title:'你好' } }" >跳转</router-link>
命名路由
1 import Vue from 'vue' 2 import App from './App.vue' 3 4 Vue.config.productionTip = false 5 6 import VueRouter from "vue-router"; 7 Vue.use(VueRouter) 8 import router from './router' 9 10 new Vue({ 11 el:"#app", 12 render: h => h(App), 13 beforeCreate() { 14 //安装全局事件总线 15 Vue.prototype.$bus = this 16 }, 17 router:router 18 })
1 import VueRouter from "vue-router" 2 import About from "@/pages/About"; 3 import Home from "@/pages/Home"; 4 import News from "@/pages/News"; 5 import Message from "@/pages/Message"; 6 import Detail from "@/pages/Detail"; 7 8 //创建并暴露一个路由器 9 export default new VueRouter({ 10 routes:[ 11 { 12 name:'about', 13 path:'/about', 14 component:About 15 }, 16 { 17 path:'/home', 18 component:Home, 19 children:[ 20 { 21 path:'news', 22 component:News 23 }, 24 { 25 path: 'message', 26 component: Message, 27 children:[ 28 { 29 name:'detail', 30 path:'detail', 31 component:Detail 32 } 33 ] 34 } 35 ] 36 } 37 ] 38 })
1 <template> 2 <div> 3 <div class="row"> 4 <Banner></Banner> 5 </div> 6 <div class="row"> 7 <div class="col-xs-2 col-xs-offset-2"> 8 <div class="list-group"> 9 <!-- <a class="list-group-item active" href="./about.html">About</a>--> 10 <!-- <a class="list-group-item" href="./home.html">Home</a>--> 11 12 <router-link class="list-group-item" active-class="active" to="/about">About</router-link> 13 <router-link class="list-group-item" active-class="active" to="./home">Home</router-link> 14 </div> 15 </div> 16 <div class="col-xs-6"> 17 <div class="panel"> 18 <div class="panel-body"> 19 <!-- 位置 --> 20 <router-view></router-view> 21 </div> 22 </div> 23 </div> 24 </div> 25 </div> 26 </template> 27 <script> 28 import Banner from "@/components/Banner"; 29 30 export default { 31 name:'App', 32 components:{Banner}, 33 } 34 </script>
1 <template> 2 <h2>我是About的内容</h2> 3 </template> 4 5 <script> 6 export default { 7 name: "About" 8 } 9 </script> 10 11 <style scoped> 12 13 </style>
1 <template> 2 <div> 3 <h2>Home组件内容</h2> 4 <div> 5 <ul class="nav nav-tabs"> 6 <li> 7 <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link> 8 </li> 9 <li> 10 <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link> 11 </li> 12 </ul> 13 <router-view></router-view> 14 </div> 15 </div> 16 </template> 17 18 <script> 19 export default { 20 name: "Home" 21 } 22 </script> 23 24 <style scoped> 25 26 </style>
1 <template> 2 <ul> 3 <li>news001</li> 4 <li>news002</li> 5 <li>news003</li> 6 </ul> 7 </template> 8 9 <script> 10 export default { 11 name: "News" 12 } 13 </script> 14 15 <style scoped> 16 17 </style>
1 <template> 2 <div> 3 <ul> 4 <li v-for="m in messageList" :key="m.id"> 5 <!--字符串写法--> 6 <!-- <router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{m.title}}</router-link> --> 7 <!--对象写法--> 8 <router-link :to="{ 9 // path:'/home/message/detail', 10 name:'detail', 11 query:{ 12 id:m.id, 13 title:m.title 14 } 15 }"> 16 {{m.title}} 17 </router-link> 18 </li> 19 </ul> 20 <hr> 21 <router-view></router-view> 22 </div> 23 </template> 24 25 <script> 26 export default { 27 name: "Message", 28 data(){ 29 return { 30 messageList:[ 31 {id:'001',title:'消息001'}, 32 {id:'002',title:'消息002'}, 33 {id:'003',title:'消息003'} 34 ] 35 } 36 } 37 } 38 </script> 39 40 <style scoped> 41 42 </style>
1 <template> 2 <ul> 3 <li>消息编号:{{$route.query.id}}</li> 4 <li>消息标题:{{$route.query.title}}</li> 5 </ul> 6 </template> 7 8 <script> 9 export default { 10 name: "Detail" 11 } 12 </script> 13 14 <style scoped> 15 16 </style>
1 <template> 2 <div class="col-xs-offset-2 col-xs-8"> 3 <div class="page-header"><h2>Vue Router Demo</h2></div> 4 </div> 5 </template> 6 7 <script> 8 export default { 9 name: "Banner" 10 } 11 </script> 12 13 <style scoped> 14 15 </style>
6.路由的params参数
1. 配置路由,声明接收params参数 { path:'/home', component:Home, children:[ { path:'news', component:News }, { component:Message, children:[ { name:'xiangqing', path:'detail/:id/:title', //使用占位符声明接收params参数 component:Detail } ] } ] } 2. 传递参数 <!-- 跳转并携带params参数,to的字符串写法 --> <router-link :to="/home/message/detail/666/你好">跳转</router-link> <!-- 跳转并携带params参数,to的对象写法 --> <router-link :to="{ name:'xiangqing', params:{ id:666, title:'你好' } }" >跳转</router-link> 特别注意:路由携带params参数时,若使用to的对象写法,则不能使用path配置项,必须使用name配置! 3. 接收参数: $route.params.id $route.params.title
路由的params参数
1 import Vue from 'vue' 2 import App from './App.vue' 3 4 Vue.config.productionTip = false 5 6 import VueRouter from "vue-router"; 7 Vue.use(VueRouter) 8 import router from './router' 9 10 new Vue({ 11 el:"#app", 12 render: h => h(App), 13 beforeCreate() { 14 //安装全局事件总线 15 Vue.prototype.$bus = this 16 }, 17 router:router 18 })
1 import VueRouter from "vue-router" 2 import About from "@/pages/About"; 3 import Home from "@/pages/Home"; 4 import News from "@/pages/News"; 5 import Message from "@/pages/Message"; 6 import Detail from "@/pages/Detail"; 7 8 //创建并暴露一个路由器 9 export default new VueRouter({ 10 routes:[ 11 { 12 name:'about', 13 path:'/about', 14 component:About 15 }, 16 { 17 path:'/home', 18 component:Home, 19 children:[ 20 { 21 path:'news', 22 component:News 23 }, 24 { 25 path: 'message', 26 component: Message, 27 children:[ 28 { 29 name:'detail', 30 path:'detail/:id/:title', 31 component:Detail 32 } 33 ] 34 } 35 ] 36 } 37 ] 38 })
1 <template> 2 <div> 3 <div class="row"> 4 <Banner></Banner> 5 </div> 6 <div class="row"> 7 <div class="col-xs-2 col-xs-offset-2"> 8 <div class="list-group"> 9 <!-- <a class="list-group-item active" href="./about.html">About</a>--> 10 <!-- <a class="list-group-item" href="./home.html">Home</a>--> 11 12 <router-link class="list-group-item" active-class="active" to="/about">About</router-link> 13 <router-link class="list-group-item" active-class="active" to="./home">Home</router-link> 14 </div> 15 </div> 16 <div class="col-xs-6"> 17 <div class="panel"> 18 <div class="panel-body"> 19 <!-- 位置 --> 20 <router-view></router-view> 21 </div> 22 </div> 23 </div> 24 </div> 25 </div> 26 </template> 27 <script> 28 import Banner from "@/components/Banner"; 29 30 export default { 31 name:'App', 32 components:{Banner}, 33 } 34 </script>
1 <template> 2 <h2>我是About的内容</h2> 3 </template> 4 5 <script> 6 export default { 7 name: "About" 8 } 9 </script> 10 11 <style scoped> 12 13 </style>
1 <template> 2 <div> 3 <h2>Home组件内容</h2> 4 <div> 5 <ul class="nav nav-tabs"> 6 <li> 7 <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link> 8 </li> 9 <li> 10 <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link> 11 </li> 12 </ul> 13 <router-view></router-view> 14 </div> 15 </div> 16 </template> 17 18 <script> 19 export default { 20 name: "Home" 21 } 22 </script> 23 24 <style scoped> 25 26 </style>
1 <template> 2 <ul> 3 <li>news001</li> 4 <li>news002</li> 5 <li>news003</li> 6 </ul> 7 </template> 8 9 <script> 10 export default { 11 name: "News" 12 } 13 </script> 14 15 <style scoped> 16 17 </style>
1 <template> 2 <div> 3 <ul> 4 <li v-for="m in messageList" :key="m.id"> 5 <!--字符串写法--> 6 <!-- <router-link :to="`/home/message/detail/${m.id}/${m.title}`">{{m.title}}</router-link> --> 7 <!--对象写法--> 8 <router-link :to="{ 9 name:'detail', // 不允许使用path!!!!!! 10 params:{ 11 id:m.id, 12 title:m.title 13 } 14 }"> 15 {{m.title}} 16 </router-link> 17 </li> 18 </ul> 19 <hr> 20 <router-view></router-view> 21 </div> 22 </template> 23 24 <script> 25 export default { 26 name: "Message", 27 data(){ 28 return { 29 messageList:[ 30 {id:'001',title:'消息001'}, 31 {id:'002',title:'消息002'}, 32 {id:'003',title:'消息003'} 33 ] 34 } 35 } 36 } 37 </script> 38 39 <style scoped> 40 41 </style>
1 <template> 2 <ul> 3 <!-- <li>消息编号:{{$route.query.id}}</li>--> 4 <!-- <li>消息标题:{{$route.query.title}}</li>--> 5 <li>消息编号:{{$route.params.id}}</li> 6 <li>消息标题:{{$route.params.title}}</li> 7 </ul> 8 </template> 9 10 <script> 11 export default { 12 name: "Detail" 13 } 14 </script> 15 16 <style scoped> 17 18 </style>
1 <template> 2 <div class="col-xs-offset-2 col-xs-8"> 3 <div class="page-header"><h2>Vue Router Demo</h2></div> 4 </div> 5 </template> 6 7 <script> 8 export default { 9 name: "Banner" 10 } 11 </script> 12 13 <style scoped> 14 15 </style>
作用:让路由组件更方便的收到参数
{
name:'xiangqing',
path:'detail/:id',
component:Detail,
//第一种写法:props值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件
// props:{a:900}
//第二种写法:props值为布尔值,布尔值为true,则把路由收到的所有params参数通过props传给Detail组件
// props:true
//第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件
props(route){
return {
id:route.query.id,
title:route.query.title
}
}
}
路由的props配置
1 import Vue from 'vue' 2 import App from './App.vue' 3 4 Vue.config.productionTip = false 5 6 import VueRouter from "vue-router"; 7 Vue.use(VueRouter) 8 import router from './router' 9 10 new Vue({ 11 el:"#app", 12 render: h => h(App), 13 beforeCreate() { 14 //安装全局事件总线 15 Vue.prototype.$bus = this 16 }, 17 router:router 18 })
1 import VueRouter from "vue-router" 2 import About from "@/pages/About"; 3 import Home from "@/pages/Home"; 4 import News from "@/pages/News"; 5 import Message from "@/pages/Message"; 6 import Detail from "@/pages/Detail"; 7 8 //创建并暴露一个路由器 9 export default new VueRouter({ 10 routes:[ 11 { 12 name:'about', 13 path:'/about', 14 component:About 15 }, 16 { 17 path:'/home', 18 component:Home, 19 children:[ 20 { 21 path:'news', 22 component:News 23 }, 24 { 25 path: 'message', 26 component: Message, 27 children:[ 28 { 29 name:'detail', 30 // path:'detail/:id/:title', 31 path:'detail', 32 component:Detail, 33 // 第一种 34 // props:{a:1,b:'hello'} 35 36 // 第二种(params参数) 37 // props:true 38 39 // 第三种 40 props($route){ 41 return {id:$route.query.id,title:$route.query.title} 42 } 43 // props({query:{id,title}}){ // 结构赋值 44 // return {id,title} 45 // } 46 } 47 ] 48 } 49 ] 50 } 51 ] 52 })
1 <template> 2 <div> 3 <div class="row"> 4 <Banner></Banner> 5 </div> 6 <div class="row"> 7 <div class="col-xs-2 col-xs-offset-2"> 8 <div class="list-group"> 9 <!-- <a class="list-group-item active" href="./about.html">About</a>--> 10 <!-- <a class="list-group-item" href="./home.html">Home</a>--> 11 12 <router-link class="list-group-item" active-class="active" to="/about">About</router-link> 13 <router-link class="list-group-item" active-class="active" to="./home">Home</router-link> 14 </div> 15 </div> 16 <div class="col-xs-6"> 17 <div class="panel"> 18 <div class="panel-body"> 19 <!-- 位置 --> 20 <router-view></router-view> 21 </div> 22 </div> 23 </div> 24 </div> 25 </div> 26 </template> 27 <script> 28 import Banner from "@/components/Banner"; 29 30 export default { 31 name:'App', 32 components:{Banner}, 33 } 34 </script>
1 <template> 2 <h2>我是About的内容</h2> 3 </template> 4 5 <script> 6 export default { 7 name: "About" 8 } 9 </script> 10 11 <style scoped> 12 13 </style>
1 <template> 2 <div> 3 <h2>Home组件内容</h2> 4 <div> 5 <ul class="nav nav-tabs"> 6 <li> 7 <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link> 8 </li> 9 <li> 10 <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link> 11 </li> 12 </ul> 13 <router-view></router-view> 14 </div> 15 </div> 16 </template> 17 18 <script> 19 export default { 20 name: "Home" 21 } 22 </script> 23 24 <style scoped> 25 26 </style>
1 <template> 2 <ul> 3 <li>news001</li> 4 <li>news002</li> 5 <li>news003</li> 6 </ul> 7 </template> 8 9 <script> 10 export default { 11 name: "News" 12 } 13 </script> 14 15 <style scoped> 16 17 </style>
1 <template> 2 <div> 3 <ul> 4 <li v-for="m in messageList" :key="m.id"> 5 <!--字符串写法--> 6 <!-- <router-link :to="`/home/message/detail/${m.id}/${m.title}`">{{m.title}}</router-link> --> 7 <!--对象写法--> 8 <router-link :to="{ 9 name:'detail', // params不允许使用path!!!!!! 10 query:{ 11 id:m.id, 12 title:m.title 13 } 14 }"> 15 {{m.title}} 16 </router-link> 17 </li> 18 </ul> 19 <hr> 20 <router-view></router-view> 21 </div> 22 </template> 23 24 <script> 25 export default { 26 name: "Message", 27 data(){ 28 return { 29 messageList:[ 30 {id:'001',title:'消息001'}, 31 {id:'002',title:'消息002'}, 32 {id:'003',title:'消息003'} 33 ] 34 } 35 } 36 } 37 </script> 38 39 <style scoped> 40 41 </style>
1 <template> 2 <ul> 3 <!-- <li>消息编号:{{$route.query.id}}</li>--> 4 <!-- <li>消息标题:{{$route.query.title}}</li>--> 5 <li>消息编号:{{id}}</li> 6 <li>消息标题:{{title}}</li> 7 </ul> 8 </template> 9 10 <script> 11 export default { 12 name: "Detail", 13 // props:['a','b'], 14 props:['id','title'], 15 } 16 </script> 17 18 <style scoped> 19 20 </style>
1 <template> 2 <div class="col-xs-offset-2 col-xs-8"> 3 <div class="page-header"><h2>Vue Router Demo</h2></div> 4 </div> 5 </template> 6 7 <script> 8 export default { 9 name: "Banner" 10 } 11 </script> 12 13 <style scoped> 14 15 </style>
8.<router-link>
的replace属性
1. 作用:控制路由跳转时操作浏览器历史记录的模式 2. 浏览器的历史记录有两种写入方式:分别为push和replace,push是追加历史记录,replace是替换当前记录。路由跳转时候默认为push 3. 如何开启replace模式:<router-link replace .......>News</router-link>
router-link的replace属性
1 import Vue from 'vue' 2 import App from './App.vue' 3 4 Vue.config.productionTip = false 5 6 import VueRouter from "vue-router"; 7 Vue.use(VueRouter) 8 import router from './router' 9 10 new Vue({ 11 el:"#app", 12 render: h => h(App), 13 beforeCreate() { 14 //安装全局事件总线 15 Vue.prototype.$bus = this 16 }, 17 router:router 18 })
1 import VueRouter from "vue-router" 2 import About from "@/pages/About"; 3 import Home from "@/pages/Home"; 4 import News from "@/pages/News"; 5 import Message from "@/pages/Message"; 6 import Detail from "@/pages/Detail"; 7 8 //创建并暴露一个路由器 9 export default new VueRouter({ 10 routes:[ 11 { 12 name:'about', 13 path:'/about', 14 component:About 15 }, 16 { 17 path:'/home', 18 component:Home, 19 children:[ 20 { 21 path:'news', 22 component:News 23 }, 24 { 25 path: 'message', 26 component: Message, 27 children:[ 28 { 29 name:'detail', 30 path:'detail', 31 component:Detail, 32 props($route){ 33 return {id:$route.query.id,title:$route.query.title} 34 } 35 } 36 ] 37 } 38 ] 39 } 40 ] 41 })
1 <template> 2 <div> 3 <div class="row"> 4 <Banner></Banner> 5 </div> 6 <div class="row"> 7 <div class="col-xs-2 col-xs-offset-2"> 8 <div class="list-group"> 9 <!-- <a class="list-group-item active" href="./about.html">About</a>--> 10 <!-- <a class="list-group-item" href="./home.html">Home</a>--> 11 12 <!-- <router-link replace class="list-group-item" active-class="active" to="/about">About</router-link>--> 13 <!-- <router-link replace class="list-group-item" active-class="active" to="./home">Home</router-link>--> 14 15 <router-link class="list-group-item" active-class="active" to="/about">About</router-link> 16 <router-link class="list-group-item" active-class="active" to="./home">Home</router-link> 17 </div> 18 </div> 19 <div class="col-xs-6"> 20 <div class="panel"> 21 <div class="panel-body"> 22 <!-- 位置 --> 23 <router-view></router-view> 24 </div> 25 </div> 26 </div> 27 </div> 28 </div> 29 </template> 30 <script> 31 import Banner from "@/components/Banner"; 32 33 export default { 34 name:'App', 35 components:{Banner}, 36 } 37 </script>
1 <template> 2 <h2>我是About的内容</h2> 3 </template> 4 5 <script> 6 export default { 7 name: "About" 8 } 9 </script> 10 11 <style scoped> 12 13 </style>
1 <template> 2 <div> 3 <h2>Home组件内容</h2> 4 <div> 5 <ul class="nav nav-tabs"> 6 <li> 7 <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link> 8 </li> 9 <li> 10 <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link> 11 </li> 12 </ul> 13 <router-view></router-view> 14 </div> 15 </div> 16 </template> 17 18 <script> 19 export default { 20 name: "Home" 21 } 22 </script> 23 24 <style scoped> 25 26 </style>
1 <template> 2 <ul> 3 <li>news001</li> 4 <li>news002</li> 5 <li>news003</li> 6 </ul> 7 </template> 8 9 <script> 10 export default { 11 name: "News" 12 } 13 </script> 14 15 <style scoped> 16 17 </style>
1 <template> 2 <div> 3 <ul> 4 <li v-for="m in messageList" :key="m.id"> 5 <!--字符串写法--> 6 <!-- <router-link :to="`/home/message/detail/${m.id}/${m.title}`">{{m.title}}</router-link> --> 7 <!--对象写法--> 8 <router-link :to="{ 9 name:'detail', // params不允许使用path!!!!!! 10 query:{ 11 id:m.id, 12 title:m.title 13 } 14 }"> 15 {{m.title}} 16 </router-link> 17 </li> 18 </ul> 19 <hr> 20 <router-view></router-view> 21 </div> 22 </template> 23 24 <script> 25 export default { 26 name: "Message", 27 data(){ 28 return { 29 messageList:[ 30 {id:'001',title:'消息001'}, 31 {id:'002',title:'消息002'}, 32 {id:'003',title:'消息003'} 33 ] 34 } 35 } 36 } 37 </script> 38 39 <style scoped> 40 41 </style>
1 <template> 2 <ul> 3 <li>消息编号:{{id}}</li> 4 <li>消息标题:{{title}}</li> 5 </ul> 6 </template> 7 8 <script> 9 export default { 10 name: "Detail", 11 props:['id','title'], 12 } 13 </script> 14 15 <style scoped> 16 17 </style>
1 <template> 2 <div class="col-xs-offset-2 col-xs-8"> 3 <div class="page-header"><h2>Vue Router Demo</h2></div> 4 </div> 5 </template> 6 7 <script> 8 export default { 9 name: "Banner" 10 } 11 </script> 12 13 <style scoped> 14 15 </style>
1. 作用:不借助<router-link> 实现路由跳转,让路由跳转更加灵活 2. 具体编码: //$router的两个API this.$router.push({ name:'xiangqing', params:{ id:xxx, title:xxx } }) this.$router.replace({ name:'xiangqing', params:{ id:xxx, title:xxx } }) this.$router.forward() //前进 this.$router.back() //后退 this.$router.go() //可前进也可后退
编程式路由导航
1 import Vue from 'vue' 2 import App from './App.vue' 3 4 Vue.config.productionTip = false 5 6 import VueRouter from "vue-router"; 7 Vue.use(VueRouter) 8 import router from './router' 9 10 new Vue({ 11 el:"#app", 12 render: h => h(App), 13 beforeCreate() { 14 //安装全局事件总线 15 Vue.prototype.$bus = this 16 }, 17 router:router 18 })
1 import VueRouter from "vue-router" 2 import About from "@/pages/About"; 3 import Home from "@/pages/Home"; 4 import News from "@/pages/News"; 5 import Message from "@/pages/Message"; 6 import Detail from "@/pages/Detail"; 7 8 //创建并暴露一个路由器 9 export default new VueRouter({ 10 routes:[ 11 { 12 name:'about', 13 path:'/about', 14 component:About 15 }, 16 { 17 path:'/home', 18 component:Home, 19 children:[ 20 { 21 path:'news', 22 component:News 23 }, 24 { 25 path: 'message', 26 component: Message, 27 children:[ 28 { 29 name:'detail', 30 path:'detail', 31 component:Detail, 32 props($route){ 33 return {id:$route.query.id,title:$route.query.title} 34 } 35 } 36 ] 37 } 38 ] 39 } 40 ] 41 })
1 <template> 2 <div> 3 <div class="row"> 4 <Banner></Banner> 5 </div> 6 <div class="row"> 7 <div class="col-xs-2 col-xs-offset-2"> 8 <div class="list-group"> 9 <router-link class="list-group-item" active-class="active" to="/about">About</router-link> 10 <router-link class="list-group-item" active-class="active" to="/home">Home</router-link> 11 </div> 12 </div> 13 <div class="col-xs-6"> 14 <div class="panel"> 15 <div class="panel-body"> 16 <!-- 位置 --> 17 <router-view></router-view> 18 </div> 19 </div> 20 </div> 21 </div> 22 </div> 23 </template> 24 <script> 25 import Banner from "@/components/Banner"; 26 27 export default { 28 name:'App', 29 components:{Banner}, 30 } 31 </script>
1 <template> 2 <h2>我是About的内容</h2> 3 </template> 4 5 <script> 6 export default { 7 name: "About" 8 } 9 </script> 10 11 <style scoped> 12 13 </style>
1 <template> 2 <div> 3 <h2>Home组件内容</h2> 4 <div> 5 <ul class="nav nav-tabs"> 6 <li> 7 <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link> 8 </li> 9 <li> 10 <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link> 11 </li> 12 </ul> 13 <router-view></router-view> 14 </div> 15 </div> 16 </template> 17 18 <script> 19 export default { 20 name: "Home" 21 } 22 </script> 23 24 <style scoped> 25 26 </style>
1 <template> 2 <ul> 3 <li>news001</li> 4 <li>news002</li> 5 <li>news003</li> 6 </ul> 7 </template> 8 9 <script> 10 export default { 11 name: "News" 12 } 13 </script> 14 15 <style scoped> 16 17 </style>
1 <template> 2 <div> 3 <ul> 4 <li v-for="m in messageList" :key="m.id"> 5 <!--字符串写法--> 6 <!-- <router-link :to="`/home/message/detail/${m.id}/${m.title}`">{{m.title}}</router-link> --> 7 <!--对象写法--> 8 <router-link :to="{ 9 name:'detail', 10 query:{ 11 id:m.id, 12 title:m.title 13 } 14 }"> 15 {{m.title}} 16 </router-link> 17 18 <button @click="pushShow(m)">push查看</button> 19 <button @click="replaceShow(m)">replace查看</button> 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:'消息001'}, 34 {id:'002',title:'消息002'}, 35 {id:'003',title:'消息003'} 36 ] 37 } 38 }, 39 methods:{ 40 pushShow(m){ 41 this.$router.push({ 42 name:'detail', 43 query:{ 44 id:m.id, 45 title:m.title 46 } 47 }) 48 }, 49 replaceShow(m){ 50 this.$router.replace({ 51 name:'detail', 52 query:{ 53 id:m.id, 54 title:m.title 55 } 56 }) 57 } 58 } 59 } 60 </script> 61 62 <style scoped> 63 64 </style>
1 <template> 2 <ul> 3 <li>消息编号:{{id}}</li> 4 <li>消息标题:{{title}}</li> 5 </ul> 6 </template> 7 8 <script> 9 export default { 10 name: "Detail", 11 props:['id','title'], 12 } 13 </script> 14 15 <style scoped> 16 17 </style>
1 <template> 2 <div class="col-xs-offset-2 col-xs-8"> 3 <div class="page-header"><h2>Vue Router Demo</h2></div> 4 <button @click="back">后退</button> 5 <button @click="forward">前进</button> 6 <button @click="test">测试一下go</button> 7 </div> 8 </template> 9 10 <script> 11 export default { 12 name: "Banner", 13 methods:{ 14 back(){ 15 this.$router.back() 16 }, 17 forward(){ 18 this.$router.forward() 19 }, 20 test(){ 21 this.$router.go(-2) // 后退两步 22 } 23 } 24 } 25 </script> 26 27 <style scoped> 28 29 </style>
1. 作用:让不展示的路由组件保持挂载,不被销毁。 2. 具体编码: <keep-alive include="News"> <router-view></router-view> </keep-alive>
缓存路由组件
1 <template> 2 <div> 3 <h2>Home组件内容</h2> 4 <div> 5 <ul class="nav nav-tabs"> 6 <li> 7 <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link> 8 </li> 9 <li> 10 <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link> 11 </li> 12 </ul> 13 <keep-alive include="News"> 14 <router-view></router-view> 15 </keep-alive> 16 <!-- <keep-alive :include="['News','Message']">--> 17 <!-- <router-view></router-view>--> 18 <!-- </keep-alive>--> 19 </div> 20 </div> 21 </template> 22 23 <script> 24 export default { 25 name: "Home" 26 } 27 </script> 28 29 <style scoped> 30 31 </style>
11.两个新的生命周期钩子
1. 作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态。
2. 具体名字:
1. activated路由组件被激活时触发。
2. deactivated路由组件失活时触发。
两个新的生命周期钩子
1 <template> 2 <ul> 3 <li :style="{opacity}">欢迎学习Vue</li> 4 <li>news001 <input type="text"> </li> 5 <li>news002 <input type="text"> </li> 6 <li>news003 <input type="text"> </li> 7 </ul> 8 </template> 9 10 <script> 11 export default { 12 name: "News", 13 data(){ 14 return { 15 opacity:1 16 } 17 }, 18 // mounted() { 19 // this.timer = setInterval(()=>{ 20 // this.opacity -= 0.01 21 // if (this.opacity <= 0) this.opacity = 1 22 // },16) 23 // }, 24 // beforeDestroy() { 25 // clearInterval(this.timer) 26 // } 27 28 activated() { 29 this.timer = setInterval(()=>{ 30 this.opacity -= 0.01 31 if (this.opacity <= 0) this.opacity = 1 32 },16) 33 }, 34 deactivated() { 35 clearInterval(this.timer) 36 } 37 } 38 </script> 39 40 <style scoped> 41 42 </style>
12.路由守卫
1. 作用:对路由进行权限控制
2. 分类:全局守卫、独享守卫、组件内守卫
3. 全局守卫:
//全局前置守卫:初始化时执行、每次路由切换前执行
router.beforeEach((to,from,next)=>{
console.log('beforeEach',to,from)
if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制
if(localStorage.getItem('school') === 'atguigu'){ //权限控制的具体规则
next() //放行
}else{
alert('暂无权限查看')
// next({name:'guanyu'})
}
}else{
next() //放行
}
})
//全局后置守卫:初始化时执行、每次路由切换后执行
router.afterEach((to,from)=>{
console.log('afterEach',to,from)
if(to.meta.title){
document.title = to.meta.title //修改网页的title
}else{
document.title = 'vue_test'
}
})
4. 独享守卫:
beforeEnter(to,from,next){
console.log('beforeEnter',to,from)
if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制
if(localStorage.getItem('school') === 'atguigu'){
next()
}else{
alert('暂无权限查看')
// next({name:'guanyu'})
}
}else{
next()
}
}
5. 组件内守卫:
//进入守卫:通过路由规则,进入该组件时被调用
beforeRouteEnter (to, from, next) {
},
//离开守卫:通过路由规则,离开该组件时被调用
beforeRouteLeave (to, from, next) {
}
全局路由守卫
1 import VueRouter from "vue-router" 2 import About from "@/pages/About"; 3 import Home from "@/pages/Home"; 4 import News from "@/pages/News"; 5 import Message from "@/pages/Message"; 6 import Detail from "@/pages/Detail"; 7 8 //创建并暴露一个路由器 9 const router = new VueRouter({ 10 routes:[ 11 { 12 name:'about', 13 path:'/about', 14 component:About, 15 meta:{title:"关于"} 16 }, 17 { 18 name:'home', 19 path:'/home', 20 component:Home, 21 meta:{title:"主页"}, 22 children:[ 23 { 24 name:'news', 25 path:'news', 26 component:News, 27 meta:{isAuth:true,title:"新闻"} 28 }, 29 { 30 name: 'message', 31 path: 'message', 32 component: Message, 33 meta:{isAuth:true,title:"消息"}, 34 children:[ 35 { 36 name:'detail', 37 path:'detail', 38 component:Detail, 39 meta:{isAuth:true,title:"详情"}, 40 props($route){ 41 return {id:$route.query.id,title:$route.query.title} 42 } 43 } 44 ] 45 } 46 ] 47 } 48 ] 49 }) 50 //全局前置路由守卫 51 router.beforeEach((to,from,next)=>{ 52 if (to.meta.isAuth){ 53 // if (to.path === '/home/news' || to.path === '/home/message'){ 54 // if (to.name === 'news' || to.name === 'message'){ 55 if (localStorage.getItem('school')==='jingdong'){ 56 next() 57 }else { 58 alert("学校名错误!") 59 } 60 }else { 61 next() 62 } 63 }) 64 65 //全局后置路由守卫(没有next) 66 router.afterEach((to, from)=>{ 67 document.title = to.meta.title || "初始" 68 }) 69 70 export default router
独享路由守卫
1 import VueRouter from "vue-router" 2 import About from "@/pages/About"; 3 import Home from "@/pages/Home"; 4 import News from "@/pages/News"; 5 import Message from "@/pages/Message"; 6 import Detail from "@/pages/Detail"; 7 8 //创建并暴露一个路由器 9 const router = new VueRouter({ 10 routes:[ 11 { 12 name:'about', 13 path:'/about', 14 component:About, 15 meta:{title:"关于"} 16 }, 17 { 18 name:'home', 19 path:'/home', 20 component:Home, 21 meta:{title:"主页"}, 22 children:[ 23 { 24 name:'news', 25 path:'news', 26 component:News, 27 meta:{isAuth:true,title:"新闻"}, 28 beforeEnter:(to,from,next)=>{ 29 if (to.meta.isAuth){ 30 if (localStorage.getItem('school')==='jingdong'){ 31 next() 32 }else { 33 alert("学校名错误!") 34 } 35 }else { 36 next() 37 } 38 } 39 }, 40 { 41 name: 'message', 42 path: 'message', 43 component: Message, 44 meta:{isAuth:true,title:"消息"}, 45 children:[ 46 { 47 name:'detail', 48 path:'detail', 49 component:Detail, 50 meta:{isAuth:true,title:"详情"}, 51 props($route){ 52 return {id:$route.query.id,title:$route.query.title} 53 } 54 } 55 ] 56 } 57 ] 58 } 59 ] 60 }) 61 /* 62 //全局前置路由守卫 63 router.beforeEach((to,from,next)=>{ 64 if (to.meta.isAuth){ 65 // if (to.path === '/home/news' || to.path === '/home/message'){ 66 // if (to.name === 'news' || to.name === 'message'){ 67 if (localStorage.getItem('school')==='jingdong'){ 68 next() 69 }else { 70 alert("学校名错误!") 71 } 72 }else { 73 next() 74 } 75 }) 76 */ 77 78 //全局后置路由守卫(没有next) 79 router.afterEach((to)=>{ 80 document.title = to.meta.title || "初始" 81 }) 82 83 84 export default router
组件内路由守卫
1 <template> 2 <h2>我是About的内容</h2> 3 </template> 4 5 <script> 6 export default { 7 name: "About", 8 beforeRouteEnter(to,from,next){ 9 if (to.meta.isAuth){ 10 if (localStorage.getItem('school')==='jingdong'){ 11 next() 12 }else { 13 alert("学校名错误!") 14 } 15 }else { 16 next() 17 } 18 }, 19 beforeRouteLeave(to,from,next){ 20 next() 21 } 22 } 23 </script> 24 25 <style scoped> 26 27 </style>
13.路由器的两种工作模式
1. 对于一个url来说,什么是hash值?—— #及其后面的内容就是hash值。
2. hash值不会包含在 HTTP 请求中,即:hash值不会带给服务器。
3. hash模式:
1. 地址中永远带着#号,不美观 。
2. 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
3. 兼容性较好。
4. history模式:
1. 地址干净,美观 。
2. 兼容性和hash模式相比略差。
3. 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。