命名视图
想同时展示多个视图时,并且每个视图展示不同的组件时,可以使用命名视图。也就是 <router-view></router-view>
当想展示多个且不同的路由组件时可以设置 name
属性, name
属性默认值为 default
<router-view name="default"></router-view><!-- 默认视图-->
<router-view name="two"></router-view> <!-- 第二个视图-->
<router-view name="three"></router-view><!-- 第三个视图-->
多个视图渲染不同的页面, 多个视图就需要多个组件,确保正确使用 components 配置 (带上 s):
import Bar from './Bar'
import Baz from './Baz'
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Foo,
two: Bar,
three: Baz
}
}
]
})
案例
当使用多个默认视图
app.vue的源码
<template>
<div id="app">
<div class="nav-box">
<div class="logo">zxt</div>
<!-- <router-link to="/home" tag="div" class="logo" >ZXT</router-link> -->
<div class="nav-list">
<router-link to="/home">首页</router-link>
<router-link to="/learn">课程学习</router-link>
<router-link to="/show">学员展示</router-link>
<router-link to="/about">关于</router-link>
<router-link to="/community">社区</router-link>
</div>
</div>
<div class="content">
<!--多个视图-->
<router-view></router-view>
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name: 'App',
components: {
},
}
</script>
<style>
:root,body{
height: 100%;
}
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
}
.nav-box{
width: 100%;
height: 60px;
display: flex;
justify-content: space-around;
align-items: center;
background: rgba(0, 0, 200, .5);
}
.logo{
color: #fff;
font-size: 30px;
font-weight: bold;
cursor: pointer;
}
.nav-list{
display: flex;
width: 60%;
justify-content: space-between;
align-items: center;
}
.nav-list a{
text-decoration: none;
color: #000;
font-size: 18px;
}
/* 此处修改选中效果,不然当单击二级导航栏时,一级导航栏没有选中效果 */
.nav-list a.router-link-active{
font-weight: bold;
color: #fff;
}
.content{
margin-top: 40px;
font-size: 20px;
}
</style>
route.vue的源码
{
path: '/show',
component: () => import('./components/views/Show.vue')
},
当多个视图各个展示的不一样
app.vue的代码
<template>
<div id="app">
<div class="nav-box">
<div class="logo">zxt</div>
<!-- <router-link to="/home" tag="div" class="logo" >ZXT</router-link> -->
<div class="nav-list">
<router-link to="/home">首页</router-link>
<router-link to="/learn">课程学习</router-link>
<router-link to="/show">学员展示</router-link>
<router-link to="/about">关于</router-link>
<router-link to="/community">社区</router-link>
</div>
</div>
<div class="content">
<!--多个视图-->
<router-view></router-view>
<router-view name="view"></router-view>
</div>
</div>
</template>
<script>
export default {
name: 'App',
components: {
},
}
</script>
<style>
:root,body{
height: 100%;
}
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
}
.nav-box{
width: 100%;
height: 60px;
display: flex;
justify-content: space-around;
align-items: center;
background: rgba(0, 0, 200, .5);
}
.logo{
color: #fff;
font-size: 30px;
font-weight: bold;
cursor: pointer;
}
.nav-list{
display: flex;
width: 60%;
justify-content: space-between;
align-items: center;
}
.nav-list a{
text-decoration: none;
color: #000;
font-size: 18px;
}
/* 此处修改选中效果,不然当单击二级导航栏时,一级导航栏没有选中效果 */
.nav-list a.router-link-active{
font-weight: bold;
color: #fff;
}
.content{
margin-top: 40px;
font-size: 20px;
}
</style>
route.js 的源码
{
path: '/show',
components:{
default: () => import('./components/views/Show.vue'),
view: () => import('./components/views/About.vue')
}
},
show.vue
<template>
<div class="show">学员展示</div>
</template>
about.vue
<template>
<div class="about">关于</div>
</template>
路由组件传参
以动态路由为例,你会发现question.vue 渲染页面的时候需要通过$route进行一系列操作,这就写死啦只能在当动态路由下才能使用。其他地方是无法使用的。当我们想把question.vue当做组件使用时,就会发现缺少参数
示例
动态路由匹配中的question的源码
<template>
<div v-if="data">
<div class="title">
{{ data.title }}
</div>
<div class="option" >
<div class="option-item" @click="handleClick(options.id)" v-for="options in optionQusetinList" :key="options.id" :title="options.title" :class="options.type"> {{ options.title}}</div>
</div>
</div>
</template>
<script>
export default {
data(){
return {
data:null
}
},
computed:{
/**
* 计算属性
* 下一篇文章与上一篇的文章
*/
optionQusetinList(){
let arr = []
if(this.data.next){
const {next,nextId} = this.data
arr.push({
type:'next',
title:next,
id:nextId,
})
}
if(this.data.prev){
const {prev ,prevId} = this.data
arr.push({
type:'prev',
title:prev,
id:prevId,
})
}
return arr
}
},
methods:{
/**
* 获取数据
*/
getData(){
const { id } = this.$route.params
this.$axios.get(`/question/${id}`).then(res =>{
this.data = res
})
},
/**
* 触发单击事件修改路由
*/
handleClick(id){
const { name } = this.$route
this.$router.push({name,params:{id}})
}
},
/**
* 监听路由信息是否被修改
* 当路由信息被修改后重新获取数据
*/
watch:{
'$route':{
handler(){
this.getData()
},
immediate: true
}
}
}
</script>
<style scoped>
.option{
width: 80%;
height: 30px;
position: fixed;
left: 0;
right: 0;
bottom: 10px;
margin: 10px auto;
}
.option-item{
width: 200px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #3385ff;
cursor: pointer;
}
.option-item:hover{
color: red;
}
.option-item.next{
float: right;
}
.option-item .right{
float: left;
}
</style>
在课程学习页面(课程学习页面的源码文件为learn.vue)吧question当做组件引入
<template>
<div class="learn">
课程学习
<router-question></router-question>
</div>
</template>
<script>
import routerQuestion from "./question"
export default {
components:{
routerQuestion
}
}
</script>
效果图
你会发现报错信息是找不到,因为question.vue中你获取页面数据的id值是从动态路由的参数中获取到的
const { id } = this.$route.params
路由名字也是
const { name } = this.$route
你在看当前页面的路由
而动态路由为
那吗我们可以将所需要的数据传递进去
使用prop来传递参数
learn.vue中的代码修改为
<template>
<div class="learn">
课程学习
<router-question :id='90878976' name="question" ></router-question>
</div>
</template>
<script>
import routerQuestion from "./question"
export default {
components:{
routerQuestion
}
}
</script>
修改question .vue 的源码
<template>
<div v-if="data">
<div class="title">
{{ data.title }}
</div>
<div class="option" >
<div class="option-item" @click="handleClick(options.id)" v-for="options in optionQusetinList" :key="options.id" :title="options.title" :class="options.type"> {{ options.title}}</div>
</div>
</div>
</template>
<script>
export default {
// 接受传递过来的参数
props:{
id:{
type:[String,Number],
},
name:{
type:String,
}
},
data(){
return {
data:null
}
},
mounted(){
console.log(this.id)
console.log(this.name)
},
computed:{
/**
* 计算属性
* 下一篇文章与上一篇的文章
*/
optionQusetinList(){
let arr = []
if(this.data.next){
const {next,nextId} = this.data
arr.push({
type:'next',
title:next,
id:nextId,
})
}
if(this.data.prev){
const {prev ,prevId} = this.data
arr.push({
type:'prev',
title:prev,
id:prevId,
})
}
return arr
}
},
methods:{
/**
* 获取数据
*/
getData(){
const { id } = this
this.$axios.get(`/question/${id}`).then(res =>{
this.data = res
})
},
/**
* 触发单击事件修改路由
*/
handleClick(id){
const { name } = this
console.log(name)
this.$router.push({name,params:{id}})
}
},
/**
* 监听路由信息是否被修改
* 当路由信息被修改后重新获取数据
*/
watch:{
'$route':{
handler(){
this.getData()
},
immediate: true
}
}
}
</script>
<style scoped>
.option{
width: 80%;
height: 30px;
position: fixed;
left: 0;
right: 0;
bottom: 10px;
margin: 10px auto;
}
.option-item{
width: 200px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #3385ff;
cursor: pointer;
}
.option-item:hover{
color: red;
}
.option-item.next{
float: right;
}
.option-item .right{
float: left;
}
</style>
router.js
{
/**
* 动态路由匹配
* /question/下的参数都将是question.vue 渲染出来的
*/
path:'/question/:id',
name:'question',
props:true, // 开启路由组件传递参数
component:() => import('./components/views/question.vue')
}
模式
布尔模式
如果 props 被设置为 true,route.params 将会被设置为组件属性。
上面的router.js就是使用的布尔模式
对象模式
如果 props 是一个对象,它会被按原样设置为组件属性。当 props 是静态的时候有用
{
/**
* 动态路由匹配
* /question/下的参数都将是question.vue 渲染出来的
*/
path:'/question/:id',
name:'question',
props:{
id: 67809854,
},
component:() => import('./components/views/question.vue')
}
函数模式
你可以创建一个函数返回 props。函数的第一个参数是 route (即$route)。
{
/**
* 动态路由匹配
* /question/下的参数都将是question.vue 渲染出来的
*/
path:'/question/:id',
name:'question',
// 函数模式
props:route =>({
name:route.name,
id: route.params.id,
}),
component:() => import('./components/views/question.vue')
}