Vue-Router
路由中有一个非常重要的概念叫路由表:本质上就是一个映射表,决定了数据包的指向。
服务器渲染/后端渲染
如 jsp, php, java ... 服务器直接生产渲染好对应的 html 页面,返回到客户端进行展示。 这种情况下渲染好的页面不需要单独加载任何的 css, js, 可以直接交给浏览器显示,这样也有利于 SEO. 缺点是逻辑代码和 html 混合在一起,维护糟糕,都是由后端人员完成。
后端处理 url 和页面之间的映射关系
前后端分离阶段
前端人员由 js 执行 ajax 接口,后端人员只负责提供数据。
前端渲染
浏览器中显示的网页中的大部分内容,都是由前端编写的 js 代码在浏览器中执行,最终渲染出来的网页。
前端路由阶段
SPA: 单页面富应用阶段,主要特点是在前后端分离的基础上增加了一层前端路由。 只有 一个 html. 改变 url 页面不进行整理的刷新。 如何实现呢?有如下三种方式
- location.hash = "/about"
- html5 的 history 模式: pushState
入栈:
history.pushState({},'','/about');
history.pushState({},'','/home');
history.pushState({},'','/me');
出栈:
history.back();
- htm5 的 history 模式: go
history.go(-1); == history.back(); history.go(1); == history.forward();
history.go(2);
- 刷新跳转 location.href="/about"
vue-router 基本使用
- 它是 vue 的一个插件 安装: npm install vue-router --save
- 安装之后的配置步骤分为三步:
- 第一步:导入路由对象,并且调用 vue.use(VueRouter)
import Vue from 'vue'
import Router from 'vue-router';
Vue.use(Router) //通过 Vue.use(插件) 来安装路由插件
- 第二步:创建路由实例(new Router),并且传入路由映射配置
const routes = [
{
path: '/',
redirect: '/home' //一进来网页就默认跳转到首页,重定向
},
{
path: '/home',
component: Pay
},
{
path: '/about',
component: About
}
];
export default new Router({
routes,
mode:'history', //默认情况下路径改变使用的是 url 的 hash 模式,所以带#,这里把它变成 html5 的 history 模式
linkActiveClass:'tracyActiveClass' //高亮的 router-link 修改默认的 router-link-active 为我自定义的
})
- 第三步:在 Vue 实例中挂载创建的路由实例
main.js 入口文件中 import router from './router'
new Vue({
el: '#app',
router, //将 router 对象传入 Vue 实例
render: h => h(App)
})
- 使用路由的步骤也分为三步
- 第一步:创建路由组件
- 第二步:配置路由映射,组件和路径映射关系
创建映射关系前要引入 组件: import HelloWorld from '@/components/HelloWorld'
- 第三步:使用路由 通过 <router-link> 和 <router-view />
<router-link>: 该标签是一个 vue-router 中已经内置的组件,它会被渲染成一个 a 标签
<router-view />: 该标签会根据当前的路径渲染出不同的组件,网页的masterhead, navigation and footer 会和它处于同一个等级;在路由切换时,切换的是它挂载的组件,其他内容不会发生改变
-
router-link 的使用
- 基本用法 to="用于指定跳转的路径" <router-link to="/home">首页</router-link>
- tag="指定 router-link 之后渲染成什么组件" <router-link tag="button">首页</router-link>
- replace 不会留下 history 记录, 后退键返回不能返回到上一个页面中 <router-link replace>首页</router-link>
- active-class: 当 router-link 对应的理由匹配成功时,会自动给当前元素设置一个 router-link-active 的 class, 我们可以把它重命名
- 通过代码的方式修改路由
- @click="toHome"
toHome(){
this.$router.push('/home'); // html5 的 history 模式: pushState
this.$router.replace('/home'); //返回不了上一页
- const routeData = this.$router.resolve({ path: '/home', query: { id: 1 } }); window.open(routeData.href, '_blank'); //新窗口
- },
动态路由
- /user/aaa 或 /user/bbb
- { path: '/user/:abc', component: 组件 }
{{ $route.params.abc }}
-
$router 和 $route 的区别
- $router 就是 router 文件夹 index.js 中 new 出来的 Router 对象
想要导航到不同的 url 则使用 this.$router.push 方法
- $route为当前 router 跳转到的对象, 可以获取 name、path、query、params、meta、matched 等
其中 matched 里放的是这 url 打开之后(除了 APP 之外的所有的)components
this.$route.path 当前路径
路由的懒加载
- 当打包构件应用时,js 会变得非常大,影响页面加载
- 把不同的路由对应的组件分割成不同的代码块,当路由被访问的时候才加载对应组件,会更加高效
- 正常打包所有文件都只会打包成如下三个文件
- vendor.####.js: 所有第三方插件,如 vue/vue-router/axios/bs
- manifest.####.js: 为了打包而做的底层支撑
- app.####.js: 当前应用程序"自己写"的所有代码(业务代码)
- 路由懒加载做了什么?
将路由对应的组件打包成一个丹迪的 js 文件,只有在这个路由被访问的时候才加载对应的组件
- 它们只在引用组件的时候有区别
正常加载: import About from '@/components/About';
懒加载: const About = () => import ('@/components/About');
vue-router 嵌套路由
- /home/abc 这种多层的 url 结构就涉及到嵌套路由
- 实现嵌套路由的两个步骤
- 创建对应的子组件,并且在路由映射中配置对应的子组件
- 在父组件内部使用 <router-view></router-view> 标签
- 在父路由里配置 children
{
path: '/home',
component: home的组件, //这里要写 router-view 标签了
children: [{
path: '',
redirect: 'abc' //重定向
}, {
path:'abc', //子路由不用写斜线了 不用写 "/abc"
component: abc的组件
},
{
... 其他子路由
}]
}
vue-router 参数传递
-
Params的类型
参考动态路由
http://www.##.com/about/aaa
http://www.##.com/about/bbb
的传递方式
-
query 的类型
http://www.##.com/about?name=tracy&age=18 的传递方式
router-link 写法
<router-link :to="{path:'about',query:{name:'tracy', age: 18}}">
@click 事件写法
click(){
this.$router.push({
path:'/about',
query:{
name: 'tracy',
age:18
}
})
}
- url 组成
协议://主机:端口/路径?查询#片段
scheme://host:port/path?query#fragment
vue-router 导航守卫
keep-alive
- keep-alive 可以使被包含的组件保留状态,或者避免重新渲染
- 两个重要的属性
- include: 字符串正则表达式,只有匹配的组件会被缓存
(因为是正则,所以不能随便加空格)
- exclude: 与上面相反
- 只有在这个时候 组件内部的 name 属性才会派上用场
如一个组件name :"tabBar", 另一个name:"hello"
-
<keep-alive include="tabBar,hello">
<router-view />
</keep-alive>
对应的是 exclude, 写在 exclude 中的会销毁,其他的都不销毁
- router-view 被包裹在 keep-alive 中的时候,所有匹配到的视图组件都会被缓存, 也就是说切换页面的时候所有组件不会重新渲染
- 用 keep-alive 被包含的组件内的变量都会缓存,也就是说当你设置了 a = 2,离开这个页面再回来的时候, a 还是等于 2