箭头函数中的this就是找最近的作用域中的this
vue-router
就是通过互联的网络把信息从源地址传到目的地址的活动,vue-router用于设定访问路径,将路径和组件映射起来
vue-rounter就是用于单页面富应用,用来管理不同组件在页面中的显示情况
改变url但页面不刷新,有以下的方法可以实现:
- 通过直接赋值location.hash来改变herf
- h5里面的history模式的pushState
这些新页面的改变就是类似栈结构,返回前进都是可以找到之前的页面
history.replaceState则是不能返回找到之前的页面
history.go(),里面传入数字
路由默认是hash模式
基本使用
vue-router的简单配置
// 导入vue-router
import VueRouter from "vue-router"
import Vue from "vue"
// 1.通过Vue.use(插件),安装插件
Vue.use(VueRouter)
// 2.创建vue-router对象
const routes = [
// 配置路由和组件之间的映射关系
{
path:'/home',
component: home
},{
path:'/about',
component: about
}
]
const router = new VueRouter({
// 把配置好的映射关系传入router中
routes
})
// 3. 将router对象传入到vue实例中
export default router //将router导出之后,在最外面的index.js中导入router
如何在最外面的index.js或者main.js中导入呢?
直接使用import导入,然后在Vue对象实例里面加上router
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h => h(App)
})
<template>
<div id="app">
<router-link to="/home">首页</router-link>
<!-- 最后渲染出来是一个a标签 -->
<router-link to="/about">关于</router-link>
<router-view></router-view>
<!-- 就是一个占位符 -->
</div>
</template>
切换的时候切换的就是router-view挂载的组件
将mode改成history模式,不用hush模式
const router = new VueRouter({
// 把配置好的映射关系传入router中
routes,
mode:'history'
})
配置路由的默认路径
只需要多配置一个映射就好了
在router中的index.js中增加一个路由:
{
path:'',//或者可以在单引号里面加/,都表示页面默认值
redirect:"/home"//是重定向,就是直接将根目录重定向在home的路径下面了
}
关于router-link的属性
- to就是表示链接到哪个组件
- tag是表示最后router-link渲染成什么样的标签,默认是a标签
- replace属性是阻止留下history记录,在指定之后,不能通过后退键返回上一个页面
- active-class属性用于修改选中的router-link的具体样式,可以用来改变类名,如果有多个router-link的话,可以采用一种简写方式,就是在写router的index.js文件中加上linkActiveClass:""属性,都是一样的效果
动态路由
在有些情况下,一个页面的path不能确定,当遇到用户页面的时候,一般会想获取用户的部分数据作为path,这个时候就要用到动态路由
- 写一个component
- 在配置vuerouter的js文件中配置新的组件和路由之间的映射,在path中要加上:和给动态部分的名称。例如:path:’/user/:userId’
- 在父组件中,data部分返回动态名称的内容,例如:
data() {
return {
userId:'lisi'
}
}
- 应用组件,使用router-link来应用新写的组件,要用v-bind来使用data里面的数据,例如::to="
/user/
+userId" - 如果需要在子组件的内部也使用这个数据,可以给子组件加上computed,里面新写一个方法来返回父组件的data数据,这个时间要用到$route.params.xxx xxx就是最开始起的动态部分的名称。例如:
computed: {
userId(){
return this.$route.params.userId
}
}
然后使用mustache语法使用这个方法,或者不写方法直接用mustache语法,例如:{{$route.params.userId}}
路由的懒加载
对写好的vue项目进行打包,产生的dist文件中的js文件夹的具体内容
app是当前应用程序开发的所有代码(业务代码)
mainfest是为打包的代码数据进行底层支撑的
vendor里面是第三方代码,例如vue,vue-router等等
什么是懒加载,懒加载就是需要时再加载
路由的懒加载就是因为打包构建的时候,如果将所有的js代码都放在一个js文件中必然会导致这个页面非常大,这个时候如果一次性从服务器请求那就会花费一定的时间,用户的电脑还有可能会出现空白,路由的懒加载出现的原因就是为了解决这个问题,路由懒加载会将一个个路由对应的组件打包成一个个的js代码块,只有在这个路由被访问到时候才加载对应的组件
三种写法
- 结合vue的异步组件和webpack的代码
const Home = resolve => { require.ensure(['../components/home.vue'], () => {resolve('../components/home.vue')) })}
- AMD写法
const about = resolve => require(['../components/about.vue'], resolve)
- 在es6中,用更加简单的写法来组织vue异步组件和webpack的代码分割
const home = () => import("../components/home.vue")//可以赋值给const,也可以在component这里直接写,例如:component: () => import('../components/user.vue')
嵌套路由
就是在home这个组件中访问到别的小组件的内容
使用方法:
- 创建对应的子组件,并且在路由映射中配置对应的子路由
- 在组件内部使用标签
{
path:'/home',
component: home,
children:[
{
path: '',
redirect:'news'//设置默认路由
},{
path: 'news',
component: homeNews
},{
path: 'message',
component: homeMessage
}
]
}
在应用这两个子组件的时候就需要直接在home(父组件)中使用router-link和router-view
参数传递
传递参数的两种类型:params和query
-
params类型: 数据少的时候建议
设置路由格式:/router/:id
传递方式:在path后面跟上对应的值
传递后形成的路径:/router/123,/router/abc -
query类型: 数据多的时候建议使用
配置路由格式:/router,就普通配置
传递方式:对象中使用query的key作为传递方式
传递后形成的路径:/router?id=123,/router?id=abc
对于query类型来说,和平时的组件差异是在router-link这里,例如
<router-link :to="{path: '/profile', query:{name: 'why', age:18, height: 1.67}}">档案</router-link>
通过v-bind用to传过来的对象就是query对象,然后会拼接成最常见的url形式
关于url:
协议://主机:端口/路径?查询
scheme://host:port/path?query#fragment
当想使用路由跳转可以不使用router-link,比如想使用button可以给他加上click方法,在method里面写上跳转方法,例如:
userClick() {
this.$router.push('/user/' + this.userId)
},
profileClick() {
this.$router.push({
path: '/profile',
query: {
name: 'muge',
age: 18,
height: 1.67
}
})
}
当push里面传对象的时候,其实也就是传了query对象
当组件内部想要用数据的时候,可以像params一样,直接将params的方法换成query
$router就是那个new出来的vue-router
$route则是现在活跃的那个路由\
所有的组件都继自Vue类的原型
生命周期:
- created 当组件被创建出来的时候就会回调这个函数
- mounted 当组件被挂载在dom上面的时候就会回调这个函数
- updated 只要界面发生刷新,就会触发这个回调
- destroyed dom被完全销毁的时候触发的回调
导航守卫
目的是监听路由之间的跳转
通过router.beforeEach来实现,例如实现一下切换路由的demo
router.beforeEach((to, from, next) => {//hook 这个就是前置钩子,在路由跳转前回调
// 从from跳转到to to和from都是组件
console.log(to);
document.title = to.matched[0].meta.title;// 对嵌套组件处理元数据
next()// 必须要执行一次,在不写的情况下是默认会执行的,但是写了这个函数就会覆盖之前的默认,这个时候就要主动执行
})
next: 调用该方法后,才能进入下一个钩子
上图是对router.beforeEach内部参数的一个解释
上图是对嵌套组件处理元数据的原因
在配置路由和组件的映射关系的时候,加上meta属性,可以用来存放元数据
有前置钩子自然也有后置钩子(守卫),就是afterEach(),这个不需要主动执行,在路由跳转后进行回调,参数只有to和from
上述的两个守卫都是全局守卫,还有路由独享守卫和组件内部的守卫
keep-alive
keep-alive是vue内置的一个组件,可以使被包含的组件保留状态,或者避免重新渲染
keep-alive内部有两个属性:(如果想选中自己的组件的话,属性值填组件的name属性)
- include,字符串或正则表达式,只有匹配的组件会被缓存
- exclude,字符串或正则表达式,任何匹配的组件都不会被缓存
router-view也是一个组件,如果直接包在keep-alive里面,所有路径匹配到的视图组件都会被缓存
如何使用就是在keep-alive标签里面放置我们的router-view标签,这样就会让不需要重新加载的组件不被再次重新加载
activated() {//只有在用keep-alive的时候才会有效的方法
// console.log('act');
this.$router.push(this.path);
},
deactivated() {
console.log('deact');
}