什么是路由?
路由就是通过互联的网络把信息从源地址传输到目的地址的活动。
网页的发展阶段
后端路由阶段:
由后端处理URL和页面之间的映射关系,前端展示的页面都是经由后端处理好的。
前后端分离阶段:
随着Ajax技术的出现,有了前后端分离的开发模式,后端只负责提供数据,不负责任何阶段的内容。浏览器中显示的网页中的大部分内容,都是由前端写的js代码在浏览器中经过执行,最终渲染出来的网页,即前端渲染。
单页面富应用阶段:
SPA(Single page application)在前后端分离的基础上加了一层前端路由,由前端来维护一套路由规则。整个网页只有一个html页面,由前端对url和页面之间的映射关系。
什么是vue-router?
vue-router是Vue.js官方的路由插件,与vue.js深度集成,适用于构建单页面应用程序。路由用于设定访问路径,将路径和组件映射起来,在vue-router的单页面应用中,页面路径的改变就是组件的切换。
vue-router的封装
步骤一:安装 vue-router 插件
npm install vue-router --save
步骤二:在模块化工程中使用
- 导入路由对象,并且调用 Vue.use( VueRouter )
- 创建路由实例,并且传入路由映射配置
- 在Vue实例中挂载创建的路由实例?
vue-router的使用
安装vue-router之后,在src目录下新建router文件夹,并创建index.js文件进行配置:
(Vue CLI 创建项目时选择vue-router后可以自动生成该目录文件)
router/index.js
//配置路由信息
import Router from 'vue-router'//导入vue-router
import Vue from 'vue'//导入vue
import HelloWorld from '@/components/HelloWorld'
//Vue.use(插件),安装插件
Vue.use(Router)
//创建并导出
export default new Router({
routes: [//处理url与组件之间的映射关系
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
}
]
})
在main.js文件中导入并引用
main.js
import Vue from 'vue'
import App from './App'
import router from './router'//导入创建的router
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h => h(App)
})
?配置路由的映射关系:
在components文件夹下创建两个组件: Home.vue、About.vue文件
<template>
<div>
<h2>Home</h2>
<p>Home组件</p>
</div>
</template>
<script>
export default {
name:"Home"
}
</script>
<style>
</style>
<template>
<div>
<h2>About</h2>
<p>About组件</p>
</div>
</template>
<script>
export default {
name:"About"
}
</script>
<style>
</style>
配置映射关系:打开router/index.js文件,配置routers:[]
//配置路由信息
import Router from 'vue-router'//导入vue-router
import Vue from 'vue'//导入vue
//导入创建的组件Home、About
import Home from '../components/Home'
import About from '../components/About'
//Vue.use(插件),安装插件
Vue.use(Router)
//创建并导出
export default new Router({
routes: [//处理url与组件之间的映射关系
{
path: '/home',
component: Home
},
{
path: '/about',
component: About
}
]
})
?在App.vue文件中写标签进行路由切换:
<template>
<div id="app">
<router-link to="/home">Home</router-link>
<router-link to="/about">About</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
</style>
固定标签<router-link></router-link> 和 <router-view></router-view>
router-link 和 router-view 是 vue 自动注册的两个组件,前者最终会被渲染成a标签,后者决定了渲染出来的组件放在什么位置进行显示,二者缺一不可。
运行结果:
?总结以上vue-router的使用步骤:
- 创建路由组件
- 配置路由映射:组件和路由的映射关系
- 使用路由:通过<router-link>和<router-view>
路由的默认配置 :router/index.js
//创建并导出
export default new Router({
routes: [//处理url与组件之间的映射关系
{//设置路由的默认路径
path:'',
redirect:'/home',//重定向,一旦页面路径为' '时,默认指向 /home
},
{
path: '/home',
component: Home
},
{
path: '/about',
component: About
}
],
mode:'history',//默认情况下使用hash方式: #/home,修改为 history 模式后,为: /home
// linkActiveClass: 'active' //路由标签被点击时添加class属性为active,默认情况下是 router-link-exact-active
})
项目运行,则默认指向 /home?
?<router-link>的属性
<router-link>除了to属性进行路由跳转之外,还有一些其他属性,比如tag属性
默认情况下,<router-link>会被渲染成<a>标签:
<router-link to="/home" tag="button">Home</router-link>
<router-link to="/about" tag="button">About</router-link>
replace属性:不能通过浏览器左上角的????进行返回操作:
<router-link to="/home" tag="button" replace>Home</router-link>
当路由跳转标签被点击时,vue会自动为该标签添加一个class:
通过这个属性,我们可以对标签的点击样式进行控制。
App.vue中添加样式:
<style>
.router-link-exact-active{
color: red;
}
</style>
?
路由代码跳转
<template>
<div id="app">
<!-- <router-link to="/home" tag="button">Home</router-link>
<router-link to="/about" tag="button">About</router-link> -->
<button @click="homeClick">Home</button>
<button @click="aboutClick">About</button>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
methods:{
homeClick(){
//通过代码修改路由: vue-router 为每一个元素都添加了$router属性
this.$router.push('/home')//实现路由修改,可以返回
// this.$router.replace('/home')//不能返回
},
aboutClick(){
this.$router.push('/about')//实现路由修改
// this.$router.replace('/about')//不能返回
}
}
}
</script>
<style>
.router-link-exact-active{
color: red;
}
</style>
动态路由?
有时候一个页面的path路径很可能是不确定的,比如我们进入用户界面时,希望出现以下路径:
/user/aaa,/user/bbb,/user/ccc,除了前面的/user之外,后面还跟上了用户的ID。这种path和componment的匹配关系就是动态路由,也是路由传递数据的一种方式。
新建组件 User.vue
<template>
<div>
<h2>用户界面</h2>
<p>动态路由</p>
</div>
</template>
<script>
export default {
name: 'User',
}
</script>
<style>
</style>
配置路由:router/index.js
//配置路由信息
import Router from 'vue-router'//导入vue-router
import Vue from 'vue'//导入vue
//导入创建的组件Home、About
import Home from '../components/Home'
import About from '../components/About'
import User from '../components/User'
//Vue.use(插件),安装插件
Vue.use(Router)
//创建并导出
export default new Router({
routes: [//处理url与组件之间的映射关系
{//设置路由的默认路径
path:'',
redirect:'/home',//重定向,一旦页面路径为' '时,默认指向 /home
},
{
path: '/home',
component: Home
},
{
path: '/about',
component: About
},
{
path: '/user/:userId',
component: User
}
],
mode:'history',//默认情况下使用hash方式: #/home,修改为 history 模式后,为: /home
// linkActiveClass: 'active' //路由标签被点击时添加class属性为active,默认情况下是 router-link-exact-active
})
App.vue
<template>
<div id="app">
<router-link to= "/home" tag="button">Home</router-link>
<router-link to= "/about" tag="button">About</router-link>
<router-link :to= "'/user/'+ userId" tag="button">用户</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return {
userId:'xiaoyuer'
}
}
}
</script>
<style>
.router-link-exact-active{
color: red;
}
</style>
运行结果:
?this.$route 获取当前活跃的路由(被点击的),this.$router为整个路由对象,包括很多路由。
this.$route.params可以拿到当前活跃路由的一些参数信息,例如:
User.vue
<template>
<div id="app">
<router-link to= "/home" tag="button">Home</router-link>
<router-link to= "/about" tag="button">About</router-link>
<router-link :to= "'/user/'+ userId" tag="button">用户</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return {
userId:'xiaoyuer'
}
}
}
</script>
<style>
.router-link-exact-active{
color: red;
}
</style>
运行结果:
路由懒加载:
当我们对应用程序进行打包时,javaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候再加载对应的组件,这样就能够更加高效。
ES6中懒加载的写法:
const Home = () => import('../components/Home.vue')
router/index.js
//配置路由信息
import Router from 'vue-router'//导入vue-router
import Vue from 'vue'//导入vue
//导入创建的组件Home、About
// import Home from '../components/Home'
// import About from '../components/About'
// import User from '../components/User'
//懒加载的方式
const Home = () => import('../components/Home')
const About = () => import('../components/About')
const User = () => import('../components/User')
//Vue.use(插件),安装插件
Vue.use(Router)
//创建并导出
export default new Router({
routes: [//处理url与组件之间的映射关系
{//设置路由的默认路径
path:'',
redirect:'/home',//重定向,一旦页面路径为' '时,默认指向 /home
},
{
path: '/home',
component: Home
},
{
path: '/about',
component: About
},
{
path: '/user/:userId',
component: User
}
],
mode:'history',//默认情况下使用hash方式: #/home,修改为 history 模式后,为: /home
// linkActiveClass: 'active' //路由标签被点击时添加class属性为active,默认情况下是 router-link-exact-active
})
这样在打包时,会将每一个组件都打包成一个独立的js文件。当页面需要加载时,再对相应的组件进行调用,提高应用程序的性能。
路由嵌套?
路由嵌套是指再一个路由页面中嵌套另一个路由,比如在 home 页面中,我们可以通过 /home/news、/home/message 来访问一些其他内容。一个路径映射一个组件,访问以上两个路径也会分别渲染两个组件:News.vue 和 Message.vue。对应关系如图所示:
实现嵌套路由的步骤:
- 创建对应的子组件,并且在路由映射中配置对应的子路由。
- 在组件内部使用 <router-link> 和 <router-view>标签。
HomeNews.vue
<template>
<div>
<ul>
<li>新闻1</li>
<li>新闻2</li>
<li>新闻3</li>
<li>新闻4</li>
</ul>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
HomeMessage.vue
<template>
<div>
<ul>
<li>消息1</li>
<li>消息2</li>
<li>消息3</li>
<li>消息4</li>
</ul>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
配置路由:router/index.js
导入(懒加载)
const HomeNews = () => import('../components/HomeNews')
const Homemessage = () => import('../components/HomeMessage')
配置子路由:
{
path: '/home',
component: Home,
children:[
{//子路由的默认路径
path:'',
redirect:'news'
},
{
path: 'news',
component:HomeNews
},
{
path: 'message',
component:Homemessage
}
]
}
在 Home 组件中使用:
<template>
<div>
<h2>Home</h2>
<p>Home组件</p>
<h2>嵌套路由</h2>
<router-link to="/home/news">新闻News</router-link>
<router-link to="/home/message">消息News</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name:"Home"
}
</script>
<style>
</style>
?运行结果:
?Vue-Router 参数传递
vue-router 传递参数的方式主要有两种
params 类型:即动态路由
- 配置路由格式:/router/:id
- 传递方式:在 path 后面跟上对应的值
- 传递后形成的路径:/router/123,/router/abc
query 类型:
- ?配置路由格式:/router,普通配置
- 传递方式:对象中使用 query 的 key 作为传递方式
- 传递后形成的路径:/router?id=123,/router?id=abc
接下来主要介绍第二种参数传递的方式:
创建组件 Profile.vue 并配置路由,在App.vue中使用:
<router-link :to= "{path:'/profile',query:{name:'xiaoyuer', age: 18, height: 160}}">
profile</router-link>
运行结果:
Url路径组成:
?获取参数:$route.query
Profile.vue
<template>
<div>
<h2>Profile组件</h2>
<h2>{{$route.query}}</h2>
<h2>{{$route.query.name}}</h2>
</div>
</template>
<script>
export default {
name:'Profile'
}
</script>
<style>
</style>
一般情况下,传递的数据量较大时,推荐使用 query 的方式进行参数传递。?
导航守卫
beforeEach() 和 afterEach() 为全局导航守卫,用来监听路由跳转。
Keep-alive 与 Vue-Router
在路由跳转过程中,每一次路由跳转,其本质是对组件进行重新创建。这种情况下,当我们对某一个页面进行了大量操作之后,然后切换到下一个页面进行其他操作,当我们再一次切换到前面的页面时,相当于重新创建该组件,页面内容也会被完全刷新,如果要保留上一次的操作,可以使用Keep-alive进行处理,能够阻止组件被频繁地创建和销毁。keep-alive 是Vue内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。router-view 也是一个组件,如果直接被包在 keep-alive 里面,所有路径匹配到视图组件都会被缓存。添加keep-alive之后,activated/deactivated 函数能够使用。
activated():当前组件活跃时执行,访问该组件。
deactivated():当前组件不活跃时执行,离开该组件。
?App.vue中添加:
<keep-alive>
<router-view></router-view>
</keep-alive>
Home.vue?
?
<keep-alive> 的属性?
include - 字符串或正则表达式,只有匹配的组件会被缓存
exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存
|