动态路由:
根据路由的不同请求不同的数据。
$router 获取vue-router实例
$route 获取url的详细信息
:id表示在user后任意参数都可以访问到对应组件,但是必须有" / "。
如: localhost:8080/user/1
// router.js文件
import Vue from 'vue'
import Router from 'vue-router'
import Home from './components/home'
import User from './components/user'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
{
path: '/',
component: Home
},
{
path: '/user/:id',
component: User,
}
]
})
打印this.$route
<template>
<div id="suser">
<h3 id="oh3">我是USER页</h3>
<button class="btn btn-warning" @click = 'goToHome'>跳转到home</button>
</div>
</template>
<script>
export default {
data() {
return {
id: this.$route
}
},
created() {
console.log(this.$route)
},
methods: {
goToHome() {
this.$router.push('/')
}
}
}
</script>
<style scoped>
h3 {
color: #3eede7;
}
</style>
id存在$route.parms.id中
然后我们把它渲染在template中
header文件: 直接在url中修改id会变,但是在切换组件中不会变。
<template>
<div>
<ul class="nav nav-pills">
<router-link class="bg-success" tag="li" active-class="active" to="/" exact><a>HOME</a></router-link>
<router-link class="bg-success" tag="li" active-class="active" to="/user/1"><a>user1</a></router-link>
<router-link class="bg-success" tag="li" active-class="active" to="/user/2"><a>user2</a></router-link>
</ul>
</div>
</template>
这是因为id在重新创建组件的时候才会初始化,user1和user2都是来自user组件,所以在他们之间切换不会初始化。
解决: 使用watch监听发生变化的路由
<template>
<div id="suser">
<h3 id="oh3">我是USER页</h3>
<button class="btn btn-warning" @click = 'goToHome'>跳转到home</button>
<p>{{ id }}</p>
</div>
</template>
<script>
export default {
data() {
return {
id: this.$route.params.id
}
},
watch: {
$route(to, from) {
console.log(to) // 到哪里去
console.log(from) // 从哪里来
this.id = to.params.id
}
},
methods: {
goToHome() {
this.$router.push('/')
}
}
}
</script>
<style scoped>
h3 {
color: #3eede7;
}
</style>
to: 到user/2; from: 从user/1来。
嵌套路由
子路由都是以/user为基准,写好子路由,同时需要在user.vue中写router-view标签来展示。
import Vue from 'vue'
import Router from 'vue-router'
import Home from './components/home'
import User from './components/user'
import userStart from './components/user/userStart'
import userDetail from './components/user/userDetail'
import userEdit from './components/user/userEdit'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
{
path: '/',
component: Home
},
{
path: '/user',
component: User,
// 子路由
children: [{
path: "",
component: userStart,
},{
path: ":id",
component: userDetail,
},{
path: ":id/edit",
component: userEdit,
}]
}
]
})
现在把userStart中的li换成router-link,让我们可以直接点击切换
<!-- userStart文件 -->
<template>
<div>
<p>选择一个用户</p>
<hr>
<ul class="list-group">
<router-link to="/user/1" class="list-group-item" style="cursor: pointer">user 1</router-link>
<router-link to="/user/2" class="list-group-item" style="cursor: pointer">user 2</router-link>
<router-link to="/user/3" class="list-group-item" style="cursor: pointer">user 3</router-link>
</ul>
</div>
</template>
在用户详情中再嵌套一个编辑按钮
<!-- userDetail.vue文件 -->
<template>
<div>
<p>这是用户详细信息...</p>
<p>{{ $route.params.id }}</p>
<router-link tag="button" :to="'/user/' + $route.params.id + '/edit'" class="btn btn-success">编辑</router-link>
<!-- 因为to的值要使用字符串拼接,所以需要使用v-bind绑定 -->
</div>
</template>
<style scoped>
p {
color: #ff2121;
}
</style>
命名路由
由于router-link标签中的to属性不好写,我们使用命名路由
在to属性中使用对象,有两个参数name和params,name对应router.js中子路由的name,params字段对应当前的id值。
// router.js文件
import Vue from 'vue'
import Router from 'vue-router'
import Home from './components/home'
import User from './components/user'
import userStart from './components/user/userStart'
import userDetail from './components/user/userDetail'
import userEdit from './components/user/userEdit'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
{
path: '/',
component: Home
},
{
path: '/user',
component: User,
children: [{
path: "",
component: userStart,
},{
path: ":id",
component: userDetail,
},{
path: ":id/edit",
component: userEdit,
name: "userEdit" // 对应子组件中的name属性
}]
}
]
})
userDetailvue文件
<template>
<div>
<p>这是用户详细信息...</p>
<p>{{ $route.params.id }}</p>
<router-link
tag="button"
:to="{name:'userEdit', params:{id: $route.params.id}}"
<!-- to使用到了v-bind -->
class="btn btn-success">
编辑
</router-link>
</div>
</template>
<style scoped>
p {
color: #ff2121;
}
</style>
在以前的$router-push中也可以用命名路由
传参:
可以在to的url后加?
可以使用query对象
接收传参:
$route,query.a
听说有些公司不喜欢这种带?=#的传参?
根据需要选择
需求: 使用组件命名,header组件只在Home下显示,在User下隐藏。
把header组件进行命名,匹配到命名名字在显示。
如果是/user,会匹配到默认的router-view进行显示
重定向
如果/任意的东西(不在路由范围的东西),会什么都加载不出来。
在路由字段里重新写一个对象,path使用通配符*,表示如果上面的路径都没有走同,则走这条路;还有一个redirect字段,表示重定向到什么地方,可以是首页,可以是error页,可以是任意页。
// router.js文件
import Vue from 'vue'
import Router from 'vue-router'
import Home from './components/home'
import User from './components/user'
import userStart from './components/user/userStart'
import userDetail from './components/user/userDetail'
import userEdit from './components/user/userEdit'
import Header from './components/header'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
{
path: '/',
components: {
default: Home, // 匹配到'/' 没有命名使用这个
'header-top': Header, // 匹配到'/' 使用该命名的使用这个
},
name: 'home',
},
{
path: '/user',
component: User,
children: [{
path: "",
component: userStart,
},{
path: ":id",
component: userDetail,
},{
path: ":id/edit",
component: userEdit,
name: "userEdit"
}]
},{
path: "*",
redirect: "/user" // 重定向
}
]
})