vue-router
传统项目通过多页面结构,切换内容的时候我们往往会进行单个html的文件跳转, 这个过程会受到网络, 性能影响, 浏览器会出现不定时间的空白界面, 用户体验不好
而单页面应用就是用户通过某些操作更改地址栏url之后, 动态的进行不同模板内容的无刷新切换, 用户体验好
Vue会使用官方提供的vue-router插件来使用单页面, 原理就是通过jian’ce地址变化后将对应的路由组件进行切换 (装载与卸载)
路由在cli脚手架的应用
- 因为vue-router并不是原生生态里面的, 需要引入vue-router, 然后通过Vue.use来注册插件
router/index.js文件
import Vue from 'vue'
imprort Router from 'vue-router'
vue.use(Router)
- 创建router路由器
new Router({
router: [
{path: '/home', component: Home}
]
})
- 创建路由表并配置在路由器中
var router = [
{path, componet} // path为路径, component为路径对应的路由组件
]
var router = new Router ({
router
})
export defuault router
- 在根实例里注入router, 目的是为了让所有的组件都能通过this.
r
o
u
t
e
r
,
t
h
i
s
.
router, this.
router,this.route 来使用路由的相关功能api
main.js文件
import router from './router/
new Vue({
el: '#app',
router,
template: '<APP/>',
conponents: { APP }
})
- 利用router-view来指定路由切换的位置
app.vue文件
<template>
<div id='app'>
// 路由容器 -- 基于slot封装的, 根据不同的url地址切换对应的路由组件
<router-view></router-view>
</div>
<template>
- 使用router-link来创建切换的工具, 会渲染成a标签, 添加to属性来设置要更改的path信息, 且会根据当前路由的变化为a标签添加对应的router-link-active/ router-link-exact-active类名
<template>
<div class='nowplaying'>
<!-- 编程式跳转 -->
<ul>
<li v-for='data in dataList' :key='data' @click='toDetail(data)'> {{data}} </li>
</ul>
<ul>
<!-- 具名路由的方式 给detail配置了名字 还可以通过query对象的方式进行传参 声明式跳转 -->
<router-link
v-for='data in dataList'
:key='data'
:to="{name: 'detail', params: {id: data}, query: {title: '第一章'}}"
tag='li'
> {{data}} </router-link>
</ul>
</div>
</template>
<script>
export default {
data () {
return {
dataList: ['1111', '2222', '3333']
}
},
methods: {
toDetail (id) {
// 组件上的 $router 提供了很多跳转方法, 把这些跳转方式称之为编程式跳转
this.$router.push(`/detail/${id}`)
}
}
}
</script>
路由懒加载
懒加载也叫延迟加载, 即在需要的时候进行加载, 随用随载. 在单页应用中, 如果没有应用懒加载, 运用webpack打包的文件会异常的大, 造成进入首页时, 需要加载的内容过多, 延迟过长, 不利于用户体验
router文件下 index.js
{
name: 'center',
path: '/center',
component: () => import('@/views/Center') // 采用了路由懒加载方式
}
多级路由
在创建路由表的时候,可以为每一个路由对象创建children属性,值为数组,在这个里面又可以配置一些路由对象来使用多级路由, 注意: 一级路由path前加 ‘/’
const routes = [
{
path: '/films',
component: films,
// 二级路由
children: [
{
path: '/films/nowplaying',
component: nowplaying
},
...
]
}
]
二级路由组件的切换位置依然由router-view来指定 (指定在父级路由组件的模板中)
<template>
<div class="films">
<p>轮播图</p>
<p>导航栏</p>
<router-view></router-view>
</div>
</template>
默认路由和重定向
当我们进入应用,默认像显示某一个路由组件,或者当我们进入某一级路由组件的时候想默认显示其某一个子路由组件,我们可以配置默认路由:
{path: '路径', component: Main}
当我们需要进入之后进行重定向到其他路由的时候,或者当url与路由表不匹配的时候:
{path: '/', redirect: '/films'} // 重定向 访问根路径 / ===> films
// 放在最下面
{path: '*', component: error} // 没有配置的路径, 会跳转到编写到的404页面
动态路由匹配
有的时候我们需要在路由跳转的时候跟上参数,路由传参的参数主要有两种:路由参数、queryString参数
路由参数需要在路由表里面配置, 即router文件下 index.js
{path: '/detail/:id', component: detail}
上面的代码就是给detail路由配置接收id的参数,多个参数继续在后面设置
在组件中可以通过this.$route.params来使用
export default {
created () {
console.log(this.$route.params.id)
}
}
queryString参数不需要在路由表设置接收,直接设置?后面的内容,在路由组件中通过this.$route.query接收
export default {
created () {
// 上面 路由在cli脚手架的应用 第5个, 有配置, detail组件可以接收到地址栏? 后面的参数
console.log(this.$route.query.title)
}
}
路由模式
为了构建SPA(单页面应用),需要引入前端路由系统,这也就是Vue-router存在的意义。前端路由的核心,就在于 ——— 改变视图的同时不会向后端发出请求。
路由的两种模式: hash, history, 默认会使用hash模式, 但是如果url里不想出现丑陋hash值,在new VueRouter的时候配置mode值为history来改变路由模式,本质使用H5的histroy.pushState方法来更改url,不会引起刷新.
history模式,会出现404 的情况,需要后台配置
nginx.conf文件
location / {
try_files $uri $uri/ /index.html;
}
路由原理:
hash路由 ====> window.onhashchange监听路径的切换
history路由 ===> window.onpopstate监听路径的切换
路由守卫
在某些情况下,当路由跳转前或跳转后、进入、离开某一个路由前、后,需要做某些操作,就可以使用路由钩子来监听路由的变化
全局路由钩子:
// 全局路由的前置守卫
router.beforeEach ((to, from, next) => {
// 会在任意路由跳转前执行, next记得要放行
})
router.afterEach ((to, from) => {
// 会在任意路由跳转后执行
})
单个路由钩子:
const routes = [
...
{
path: '/center'
component: center,
beforeEnter (to, from, next) {
// 进入这个组件之前会被触发, 必须要执行next, 不然center这个组件不会正常显示出来
}
}
]
路由组件钩子:
<script>
export default {
// 进入center之前
beforeRouteEnter () {
...
// 实践应用可以登录拦截操作, 判断是否由token, 如果没有可以使用 next('/路径') 跳转到登录页面
}
// 离开center之后
beforeRouteLeave (to, from, next) {
...
// 实践应用可以询问用户是否需要离开此页面
}
// 在当前路由改变, 但是该组件被复用时调用
beforeRouteUpdate (to, from, next) {
...
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用
// 这里需要注意: 如果是hash模式是没有问题的, 页面不会刷新, 可以进来这个函数
}
}
</script>
Editted by: kiat
——还在摸爬滚打中的前端小萌新