Vue笔记:vue-router
目录
路由介绍
SPA(single page application):单一页面应用程序,只有一个完整的页面;它在加载页面时,不会加载整个页面,而是只更新某个指定的组件。
单页面应用(SPA)的核心之一是:更新视图而不重新请求页面;vue-router在实现单页面前端路由时,提供了两种方式:Hash模式和History模式。
路由中有三个基本的概念 route, routes, router。
route,一条路由规则,定义了一个url与一个组件之间的关系。
routes, 一组路由,把route放到一个数组中。
router ,前端路由机制,管理路由,当页面发生跳转时,它到routes 中去查找,去找到对应的的url对应的组件内容,所以页面中就显示了该组件内容。
注意:前端的路由,实际上就是DOM元素的显示和隐藏。当页面中显示一个组件的时候,页面中其他路由的组件全部隐藏。
路由的基本配置
目录结构:
1、在views下创建Home.vue组件
<template> <div> <h2> {{ msg }}</h2> </div> </template> <script> export default { data(){ return{ msg:'我是Home组件' } }, } </script> <style scoped> </style>
2、在App.vue中设置路由的组件显示的位置(通过<router-view></router-view>)
<template> <div id="app"> <router-view></router-view> </div> </template> <!--1.引入组件--> <!--2.挂载组件--> <!--3.在模板中使用--> <script> export default { } </script> <style scoped> </style>
3、在router.js中设置路由(注意,我这里使用路由懒加载的方式)
提前介绍一下路由懒加载:如果不使用懒加载模式,当进入项目时默认会渲染路由中所有组件,当使用懒加载时,只有访问路由指定的url才会渲染对应的组件。
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const routes = [ { path:'/home', component: () => import('./views/Home') }, ] const router = new VueRouter({ routes }) export default router
不使用懒加载的方式:
import Vue from 'vue' import VueRouter from 'vue-router' // 引入组件 import home from "./views/Home.vue"; Vue.use(VueRouter) const routes = [ { path:'/home', // component: () => import('./views/Home') component: home }, ] const router = new VueRouter({ routes }) export default router
这里介绍一下重定向,首次进入页面时,页面显示空白,因为它的访问路径是 '/',我们并没有给这个路径做相应的配置,我们可以把“/”指向home组件。
// 重定向
{
path: '/',
redirect: '/home'
}
4、注册路由到根实例
import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' Vue.use(ElementUI) Vue.config.productionTip = false new Vue({ router, store, render: h => h(App) }).$mount('#app')
路由跳转
在多页面中我们通过a标签实现多页面的跳转,在vue中没有页面的概念,只有组件,我们使用<router-link></router-link>实现组件的之间的切换显示
当我点击页面上的home按钮时,页面中就要显示home组件内容,如果点击页面上的user按钮,页面中就要显示user组件内容。home按钮 => home 组件, user按钮 => user组件,当显示一个组件时,另一个组件内容被隐藏。
1、在views下创建User.vue组件
<template> <div> <h2> {{ msg }}</h2> </div> </template> <script> export default { data(){ return{ msg:'我是User组件' } }, } </script> <style scoped> </style>
2、在router.js中设置路由
import Vue from 'vue' import VueRouter from 'vue-router' // 引入组件 import home from "./views/Home.vue"; import user from "./views/User.vue"; Vue.use(VueRouter) const routes = [ { path:'/home', // component: () => import('./views/Home') component: home }, { path:'/user', component: user }, ] const router = new VueRouter({ routes }) export default router
3、在App.vue中设置路由跳转
<template> <div id="app"> <router-link to="/home">home</router-link> <br> <router-link to="/user">user</router-link> <router-view></router-view> </div> </template> <!--1.引入组件--> <!--2.挂载组件--> <!--3.在模板中使用--> <script> export default { } </script> <style scoped> </style>
编程式导航
上面是<router-link>进行路由的方式,下面是通过事件的方式进行路由:
<template> <div id="app"> <!-- <router-link to="/home">home</router-link>--> <!-- <br>--> <!-- <router-link to="/user">user</router-link>--> <button @click="toHome">home</button> <button @click="toUser">user</button> <router-view></router-view> </div> </template> <!--1.引入组件--> <!--2.挂载组件--> <!--3.在模板中使用--> <script> export default { methods:{ toHome(){ this.$router.push({path:'/home'}) }, toUser(){ this.$router.push({path:'/user'}) }, } } </script> <style scoped> </style>
动态路由
上面我们定义的路由,都是严格匹配的,只有router-link 中的to属性和 router.js 中的路由route中 path 一模一样,才能显示相应的组件component. 但有时现实却不是这样的,当我们去访问网站并登录成功后,它会显示 欢迎你,+ 你的名字。不同的用户登录, 只是显示“你的名字” 部分不同,其它部分是一样的。
这就表示,它是一个组件,假设是user组件。不同的用户(就是用户的id不同),它都会导航到同一个user 组件中。
这样我们在配置路由的时候,path属性,不能写死,那要怎么设置? 导航到 user 组件,路径中肯定有user, id 不同,那就给路径一个动态部分来匹配不同的id,拿到这个id后,前端再向后端请求不一样的数据。
在vue-router中,动态部分 以 : 开头,那么路径就变成了 /user/:id, 这条路由就可以这么写: { path:"/user/:id", component: user }.
1、修改router.js如下:
import Vue from 'vue' import VueRouter from 'vue-router' // 引入组件 import home from "./views/Home.vue"; import user from "./views/User.vue"; Vue.use(VueRouter) const routes = [ { path:'/home', // component: () => import('./views/Home') component: home }, { path:'/user/:id', component: user }, ] const router = new VueRouter({ routes }) export default router
2、修改User.vue组件($route.params.id为url中传入的id)
<template> <div> <h2> {{ msg }}</h2> <h2> {{ $route.params.id }} </h2> </div> </template> <script> export default { data(){ return{ msg:'我是User组件' } }, } </script> <style scoped> </style>
嵌套路由
嵌套路由,主要是由我们的页面结构所决定的。当我们进入到home页面的时候,它下面还有分类,如手机系列,平板系列,电脑系列。当我们点击各个分类的时候,它还是需要路由到各个部分,如点击手机,它肯定到对应到手机的部分。
在路由的设计上,首先进入到 home ,然后才能进入到phone, tablet, computer. Phone, tablet, compute 就相当于进入到了home的子元素。所以vue 提供了childrens 属性,它也是一组路由,相当于我们所写的routes。
首先,在home页面上定义三个router-link 标签用于导航,然后再定义一个router-view标签,用于渲染对应的组件。router-link 和router-view 标签要一一对应。
1、Home.vue 组件修改如下:
<template> <div> <h2> {{ msg }}</h2> <router-link to="/home/phone">手机</router-link> <router-link to="/home/tablet">平板</router-link> <router-link to="/home/computer">电脑</router-link> <router-view></router-view> </div> </template> <script> export default { data(){ return{ msg:'我是Home组件' } }, } </script> <style scoped> </style>
2、router.js修改如下:
import Vue from 'vue' import VueRouter from 'vue-router' // 引入组件 import home from "./views/Home.vue"; import user from "./views/User.vue"; import phone from "./components/Phone.vue"; import tablet from "./components/Tablet.vue"; import computer from "./components/Computer.vue"; Vue.use(VueRouter) const routes = [ { path:'/home', component: home, // 子路由 children: [ { path: "phone", component: phone }, { path: "tablet", component: tablet }, { path: "computer", component: computer } ] }, { path:'/user/:id', component: user }, ] const router = new VueRouter({ routes }) export default router
3.在components下增加三个组件:
Phone、Tablet、Computer
模板如下:
<template> <div> <h2>{{ msg }}</h2> </div> </template> <script> export default { data(){ return{ msg:'我是Phone组件' } }, } </script> <style scoped> </style>
vue-router中的$route和$router
1、$route对象
$route对象表示当前的路由信息,包含了当前 URL 解析得到的信息。包含当前的路径,参数,query对象等。
1.$route.path:
字符串,对应当前路由的路径,总是解析为绝对路径,如 "/foo/bar"。
2.$route.params:
一个 key/value 对象,包含了 动态片段 和 全匹配片段,
如果没有路由参数,就是一个空对象。
3.$route.query:
一个 key/value 对象,表示 URL 查询参数。
例如,对于路径 /foo?user=1,则有 $route.query.user == 1,
如果没有查询参数,则是个空对象。
4.$route.hash:
当前路由的 hash 值 (不带 #) ,如果没有 hash 值,则为空字符串。锚点
5.$route.fullPath:
完成解析后的 URL,包含查询参数和 hash 的完整路径。
6.$route.matched:
数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
7.$route.name : 当前路径名字
8.$route.meta: 路由元信息
一个示例:
Vue使用ElementUI的el-tag元素时根据当前路由显示不同的样式:
:effect = "$route.name === 对象.属性? 'dark' : 'plain' "
2、$router对象
路由实例方法:
push
// 字符串 this.$router.push('home') // 对象 this.$router.push({ path: 'home' }) // 命名的路由 this.$router.push({ name: 'user', params: { userId: 123 }}) // 带查询参数,变成 /register?plan=123 this.$router.push({ path: 'register', query: { plan: '123' }})
push方法其实和<router-link :to="...">是等同的。
push方法的跳转会向 history 栈添加一个新的记录,当我们点击浏览器的返回按钮时可以看到之前的页面。
go
// 页面路由跳转 前进或者后退 this.$router.go(-1) // 后退
replace
//push方法会向 history 栈添加一个新的记录,而replace方法是替换当前的页面, 不会向 history 栈添加一个新的记录 // 一般使用replace来做404页面 this.$router.replace('/')
配置路由时path有时候会加 '/' 有时候不加,以'/'开头的会被当作根路径,就不会一直嵌套之前的路径。