目录
路由的简介
路由基本使用
几个注意点
嵌套(多级)路由
路由的query参数
命名路由
路由的params参数
路由的props配置
路由的简介
理解: 一个路由(route)就是一组映射关系(key - value),多个路由需要路由器(router)进行管理。
前端路由:key是路径,value是组件。
- 理解:value 是 component,用于展示页面内容
- 工作过程:当浏览器的路径改变时,对应的组件就会显示
生活中的路由和路由器是为了完成多台设备的上网,而编码中的路由和路由器是完为了完成实现SPA应用的导航区与展示区的切换。
对SPA应用的理解
- 单页 Web 应用(single page web application,SPA)
- 整个应用只有一个完整的页面
- 点击页面中的导航链接不会刷新页面,只会做页面的局部更新
- 数据需要通过ajax请求获取
路由基本使用
提出如下需求:
将html粘贴到App.vue
在main.js当中引入router之后可以使用一个全新的对象router。但不可像下图一样设置成字符串,需要自己去创建一个路由。
创建index.js专门用于创建整个应用的路由器 (routes为数组形式)
./router/index.js
// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import About from '../components/About'
import Home from '../components/Home'
//创建并暴露一个路由器
export default new VueRouter({
routes:[
{
path:'/about',
component:About
},
{
path:'/home',
component:Home
}
]
})
./components/About.vue
<template>
<h2>我是About的内容</h2>
</template>
<script>
export default {
name:'About'
}
</script>
./components/Home.vue
<template>
<h2>我是Home的内容</h2>
</template>
<script>
export default {
name:'Home'
}
</script>
App.vue
<template>
<div>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header"><h2>Vue Router Demo</h2></div>
</div>
</div>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!-- 原始html中我们使用a标签实现页面的跳转 -->
<!-- <a class="list-group-item active" href="./about.html">About</a> -->
<!-- <a class="list-group-item" href="./home.html">Home</a> -->
<!-- Vue中借助router-link标签实现路由的切换 router-link会转成a标签-->
<router-link class="list-group-item" active-class="active" to="/about">About</router-link>
<router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
<!-- active-class为该元素被激活的样式-->
</div>
</div>
<div class="col-xs-6">
<div class="panel">
<div class="panel-body">
<!-- 指定组件的呈现位置 -->
<router-view></router-view>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name:'App',
}
</script>
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可配置高亮样式)
vue
<router-link active-class="active" to="/about">About</router-link>
5. 指定展示位置
vue
<router-view></router-view>
几个注意点
1.靠路由规则匹配出来由路由器渲染出来的组件叫做路由组件,如果自己亲自写的标签叫做一般组件,一般情况下会将他们分为不同的文件夹。
2.不用的路由组件或者说当切换切走的路由组件其实是被销毁了
3.各个组件上都多了两个东西,route(路由的配置信息)和router(路由器) (打印出vc)
每个组件route是不一样的而router是一样的
1. 路由组件通常存放在```pages```文件夹,一般组件通常存放在```components```文件夹。
2. 通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载。
3. 每个组件都有自己的```$route```属性,里面存储着自己的路由信息。
4. 整个应用只有一个router,可以通过组件的```$router```属性获取到。
嵌套(多级)路由
界面分为导航区和展示区,在展示区里还有导航区和展示区
把相应的结构粘贴到Home/About中的tempalte去
新建展示区的组件并把结构粘贴进来
以home为例,把子展示区用问号占位
去index.js里制定路由规则,路由分为一级路由和二级路由等(多级路由),上一节写的都是一级路由,这个时候使用children配置项,这是一个数组,因为这也有可能有n多个子路由。注意子路由里的path不用再加斜杠,因为底层检测到children就会自动在地址加上斜杠。
在home里的导航标签改为router-link(),并在组件的呈现位置写上<router-view>标签
./pages/Home.vue
<template>
<div>
<h2>Home组件内容</h2>
<div>
<ul class="nav nav-tabs">
<li>
<router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
</li>
<li>
<router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link>
</li>
</ul>
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name:'Home',
}
</script>
./pages/Message.vue
<template>
<div>
<ul>
<li>
<a href="/message1">message001</a>
</li>
<li>
<a href="/message2">message002</a>
</li>
<li>
<a href="/message/3">message003</a>
</li>
</ul>
</div>
</template>
<script>
export default {
name:'Message'
}
</script>
./pages/New.vue
<template>
<ul>
<li>news001</li>
<li>news002</li>
<li>news003</li>
</ul>
</template>
<script>
export default {
name:'News'
}
</script>
./router/index.js
// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import About from '../pages/About'
import Home from '../pages/Home'
import News from '../pages/News'
import Message from '../pages/Message'
//创建并暴露一个路由器
export default new VueRouter({
routes:[
{
path:'/about',
component:About
},
{
path:'/home',
component:Home,
children:[
{
path:'news',
component:News,
},
{
path:'message',
component:Message,
}
]
}
]
})
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>
路由的query参数
当点击消息001,就在Detail.vue显示001的细节信息,002、003也是如此。只需要设置一个detail组件,给Detail.vue组件传递参数即可。
编写detail组件
这个detail属于message中的子路由,引入detail之后添加子路由
更改导航标签为router-link和to属性,在需要呈现的地方写入<router-view></router-view>
此时跳转没有携带参数,所以结果是写死的
路由是可以携带两种参数的,一种叫query参数,如下所示,这样就可以将参数交给路由组件了
那么detail组件如何接收呢?还记不记得$route,他是路由的配置信息,在detail中打印出来如下所示:
取数据接收参数如下所示,to的字符串写法
可是666和你好啊是假数据,这时需要将变量传进去,但是直接在to属性里换上m.id会被解析成字符串,所以要在to属性前加冒号,还需要用倒引号包裹,模板字符串里面混着js变量要用${}包裹。
前面加冒号。就会将双引号里的东西当作js来解析,解析发现写的是字符串还是模板字符串,而且里面还混着js变量。
此时参数完美传过来
其实还有一种写法,to的对象写法
对象里边写两个属性,一个是path,一个是query。path写到要跳转的组件,query写成一个对象并写明要携带的参数。效果同上。
./pages/Message.vue
<template>
<div>
<ul>
<li v-for="m in messageList" :key="m.id">
<!-- 跳转路由并携带query参数,to的字符串写法 -->
<!-- <router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{m.title}}</router-link> -->
<!-- 跳转路由并携带query参数,to的对象写法 -->
<router-link :to="{
path:'/home/message/detail',
query:{
id:m.id,
title:m.title
}
}">
{{m.title}}
</router-link>
</li>
</ul>
<hr>
<router-view></router-view>
</div>
</template>
<script>
export default {
name:'Message',
data() {
return {
messageList:[
{id:'001',title:'消息001'},
{id:'002',title:'消息002'},
{id:'003',title:'消息003'}
]
}
},
}
</script>
./router/index.js
// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import About from '../pages/About'
import Home from '../pages/Home'
import News from '../pages/News'
import Message from '../pages/Message'
import Detail from '../pages/Detail'
//创建并暴露一个路由器
export default new VueRouter({
routes:[
{
path:'/about',
component:About
},
{
path:'/home',
component:Home,
children:[
{
path:'news',
component:News,
},
{
path:'message',
component:Message,
children:[
{
path:'detail',
component:Detail,
}
]
}
]
}
]
})
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
命名路由
给路由命名只需要在js里添加name这个配置项即可,这个名字可以在跳转的时候简化编码。
在Message.vue里用name替换path(注意只在对象形式中这么用)
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>
路由的params参数
路径直接携带参数
js里用占位符让vue知道detail是路由的层级,下一层级是id,再下一层级是title
结果发现参数在params里,并且key的名称和占位符是一致的
所以在取值的时候也要改变,如图所示
如果使用to的对象写法,只需将query改为params即可。
注意,如果携带params参数,那么不可以使用path,只能用name。
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的对象写法,则不能使用path配置项,必须使用name配置!
<!-- 跳转并携带params参数,to的字符串写法 --> <router-link :to="/home/message/detail/666/你好">跳转</router-link> <!-- 跳转并携带params参数,to的对象写法 --> <router-link :to="{ name:'xiangqing', params:{ id:666, title:'你好' } }" >跳转</router-link>
3. 接收参数
$route.params.id $route.params.title
路由的props配置
分清楚这个是路由的props而不是组件的props。
在js当中配置一个新的配置项props,他有三种写法:
1.值为对象,该对象中的所有key-value都会以props的形式传给Detail组件。
同时在detail中添加props属性声明接收。
这种方法不推荐因为数据是写死的。
2.值为布尔值,若布尔值为真,就会把该路由组件收到的所有params参数,以props的形式传给Detail组件。
3.值为函数,该函数返回的对象(返回值)中每一组key-value都会通过props传给Detail组件
传入参数$route,用来获取query参数,在函数里封装成对象通过props传给Detail组件。
作用:让路由组件更方便的收到参数。
{ 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 } } }