vue-router
2020-08-23 本文已影响0人
青乌
路由就是处理页面跳转的,尤其是单页跳转。客户端路由有两种实现方式:基于hash 和基于html5 history api。
路由的三个概念:
- route:一条路由homeBtn=>homePage
- routes:路由组[homeBtn=>homePage,aboutBtn=>aboutPage]
- router:路由机制,管理路由。当用户点击home 按钮的时候,这时router 就起作用了,它到routes 中去查找,去找到对应的 home 内容,所以页面中就显示了 home 内容。
基本使用
1.准备两个页面Home.vue和About.vue。
<template>
<div>
<h1>home</h1>
<p>{{msg}}</p>
</div>
</template>
<script>
export default {
data () {
return {
msg: "我是home 组件"
}
}
}
</script>
<template>
<div>
<h1>about</h1>
<p>{{aboutMsg}}</p>
</div>
</template>
<script>
export default {
data () {
return {
aboutMsg: '我是about组件'
}
}
}
</script>
2.在 App.vue中 定义<router-link > 和 </router-view> 。
<template>
<div id="app">
<img src="./assets/logo.png">
<header>
<!-- router-link 定义点击后导航到哪个路径下 -->
<router-link to="/home">Home</router-link>
<router-link to="/about">About</router-link>
</header>
<!-- 对应的组件内容渲染到router-view中 -->
<router-view></router-view>
</div>
</template>
<script>
export default {
}
</script>
3.在 src目录下再新建一个router.js 定义router, 就是定义 路径到 组件的 映射。
import Vue from "vue";
import VueRouter from "vue-router";
// 引入组件
import home from "./home.vue";
import about from "./about.vue";
// 要告诉 vue 使用 vueRouter
Vue.use(VueRouter);
const routes = [
{
path:"/home",
component: home
},
{
path: "/about",
component: about
},
// 重定向
{
path: '/',
redirect: '/home'
}
]
var router = new VueRouter({
routes
})
export default router;
4.把路由注入到根实例中,启动路由。这里其实还有一种方法,就像vuex store 注入到根实例中一样,我们也可以把vueRouter 直接注入到根实例中。在main.js中引入路由,注入到根实例中
import Vue from 'vue'
import App from './App.vue'
// 引入路由
import router from "./router.js" // import router 的router 一定要小写, 不要写成Router, 否则报 can't match的报错
new Vue({
el: '#app',
router, // 注入到根实例中
render: h => h(App)
})
动态路由
1.增加新的路由。模仿用户登录动态id(http:xxx.com/user/:id)
<!--app.vue-->
<template>
<div id="app">
<img src="./assets/logo.png">
<header>
<!-- 增加两个到user组件的导航,可以看到这里使用了不同的to属性 -->
<router-link to="/user/123">User123</router-link>
</header>
<router-view></router-view>
</div>
</template>
2.router.js。配置了动态的id
//router.js
const routes = [
{
/*新增user路径,配置了动态的id*/
{
path: "/user/:id",
component: user
},
{
path: '/',
redirect: '/home'
}
]
3.用户页面。this.$route.params.id
router有一个params 属性用来获得这个动态部分。用computed 属性。
<!--user.vue-->
<template>
<div>
<h1>User</h1>
<div>我是user组件</div>
</div>
</template>
<script>
export default {
computed: {
dynamicSegment () {
return this.$route.params.id
}
}
}
</script>
4.动态路由在来回切换时,如果指向同一组件,用watch来监听$route 的变化。
<!--app.vue-->
<router-link to="/user/123">User123</router-link>
<router-link to="/user/456">User456</router-link>
<script>
//user.vue
export default {
data () {
return {
dynamicSegment: ''
}
},
watch: {
$route (to,from){
// to表示的是你要去的那个组件,from 表示的是你从哪个组件过来的,它们是两个对象,你可以把它打印出来,它们也有一个param 属性
this.dynamicSegment = to.params.id
}
}
}
</script>
嵌套路由
进入首页后,才能进入phone页,然后查看详情。home=>phone=>detail
<template>
<div>
<h1>home</h1>
<!-- router-link 的to属性要注意,路由是先进入到home,然后才进入相应的子路由如 phone,所以书写时要把 home 带上 -->
<p>
<router-link to="/home/phone">手机</router-link>
<router-link to="/home/tablet">平板</router-link>
<router-link to="/home/computer">电脑</router-link>
</p>
<router-view></router-view>
</div>
</template>
2.router.js
const routes = [
{
path:"/home", // 下面这个属性也不少,因为,我们是先进入home页面,才能进入子路由
component: home, // 子路由
children: [
{
path: "phone",
component: phone
},
{
path: "tablet",
component: tablet
},
{
path: "computer",
component: computer
},
// 当进入到home时,下面的组件显示
{
path: "",
component: phone
}
]
},
{
path: "/about",
component: about
},
{
path: "/user/:id",
component: user
},
{
path: '/',
redirect: '/home'
}
]
命名路由
直接给这个路由加一个name 属性。
{
path: "/user/:id",
name: "user",
component: user
}
<router-link to="/user/123">User123</router-link> // 和下面等价
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
编程式的导航
上面router-link都是声明式导航。
1.rourter.push()
编程式的导航主要应用到按钮点击上。当点击按钮的时候,调用rourter.push() 方法。this.$router.push("home"), 就可以跳转到home界面
2.router.go(-1) : 返回上一步
其他
将路由不存在的路径都跳转到404组件
{
path: '*',
component: () => import("../views/404.vue"),
}
组件保持存活态 keep-alive
<keep-alive>
<router-view>
<!-- 所有路径匹配到的视图组件都会被缓存! -->
</router-view>
</keep-alive>