vue路由的配置是在 vue-cli的环境下进行的。
vue-router是一个插件包,可以用npm来进行安装的。
npm install vue-router --save
// 引入vue框架
import Vue from 'vue'
// 引入vue-router路由依赖
import Router from 'vue-router'
// 引入页面组件,命名为HelloWorld
import HelloWorld from '@/components/HelloWorld'
// Vue全局使用Router
Vue.use(Router)
// 定义路由配置
export default new Router({
routes: [ //配置路由,这里是个数组
{ //每一个链接都是一个对象
path: '/hello', //链接路径
name: 'HelloWorld', //路由名称,
component: HelloWorld //对应的组件模板
}
]
})
我们可以使用model:’history’,来定义路由的格式,history是需要后台接口来提供服务的
因为hash发生变化的url都会被浏览器记录下来,从而你会发现浏览器的前进后退都可以用了,同时点击后退时,页面字体颜色也会发生变化。这样一来,尽管浏览器没有请求服务器,但是页面状态和url一一关联起来,后来人们给它起了一个霸气的名字叫前端路由,成为了单页应用标配
包括back,forward,go三个方法,对应浏览器的前进,后退,跳转操作,有同学说了,(谷歌)浏览器只有前进和后退,没有跳转,
通过pushstate把页面的状态保存在state对象中,当页面的url再变回这个url时,可以通过event.state取到这个state对象,从而可以对页面状态进行还原,这里的页面状态就是页面字体颜色,其实滚动条的位置,阅读进度,组件的开关的这些页面状态都可以存储到state的里面。
history模式怕啥
通过history api,我们丢掉了丑陋的#,但是它也有个毛病:
不怕前进,不怕后退,就怕刷新,f5,(如果后端没有准备的话),因为刷新是实实在在地去请求服务器的,不玩虚的。
在hash模式下,前端路由修改的是#中的信息,而浏览器请求时是不带它玩的,所以没有问题.但是在history下,你可以自由的修改path,当刷新时,如果服务器中没有相应的响应或者资源,会分分钟刷出一个404来。
export default new Router({
mode: 'history',
routes: [
{
path: '/hello',
component: Login
}]
})
2.在对应界面是引入 router
import Vue from 'vue'
// 引入根组件
import App from './App'
// 引入路由配置
import router from './router'
// 关闭生产模式下给出的提示
Vue.config.productionTip = false
// 定义实例
new Vue({
el: '#app',
router, // 注入框架中
components: { App },
template: ' '
})
引入之后就可以使用了
<p>导航 :
<router-link to="/">首页router-link>
<router-link to="/hello">hellorouter-link>
p>
通过 router-link to =’/hello’,可以匹配到我们需要加载相对应的组件,这样的跳转方式适合导航栏。但是登录跳转呢?总不能二话不说就跳了吧?那就看第3条。
3.其他跳转方式:
this.$router.push('/home');
this.$router.replace('/home');
// 后退一步记录,等同于 history.back()
this.$router.go(-1)
// 在浏览器记录中前进一步,等同于 history.forward()
this.$router.go(1)
this.$router
是表示全局应用路由的写法。通过 this.$router.push('/home')
;也可以实现router-link这样的跳转。后面有个登录跳转的小例子(第4条)。
4.嵌套路由的引用,最典型的就是登录以后里面有一个导航栏了。
登录部分的主要代码:
<script>
export default{
data () {
return {
userName: '',
password: ''
}
},
methods:{
login:function(){
console.log(this.userName+"!!"+this.password)
if(this.userName==='xxx'&&this.password==='123'){
//重点是这部分
this.$router.push({name:'page2',
params: { userName: this.userName,password:this.password }})
}
//重点是这部分
}
}
}
script>
这里是伪验证哈,这里是通过axios读取数据库中用户表来进行验证的。page2是和登录界面同一级的,这个是/router/index.js
export default new Router({
mode: 'history',
routes: [
{
path: '/',
component: Login
},
// 重定向
// {
// name: 'page2',
// path: '/page2',
// redirect: '/page31'
// },
{
name: 'page2',
path: '/page2',
component: page2,
}]
})
这样就实现了登录这一个功能,现在还没完,在App.vue中
是这样写的。我们在一加载的时候就做的是{
path: '/',
component: Login
},
所以可以直接将登录组件显示在下面这段代码的router-vuew中
<template>
<div class="app">
<router-view/>
div>
template>
<script>
export default {
}
script>
<style>
.app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
style>
同时当我们登录成功以后,/page对应的组件也会显示到上面的这个router-view中。从而取代登录组件,实现登陆成功的视觉效果。
后面,在page2组件中我想再添加导航栏怎么做。这里就有一个重点。
children属性:
{
name: 'page2',
path: '/page2',
component: page2,
children: [{
path: '/page21',
component: page21
},
{
name: 'page22',
path: '/page22',
component: page22
},
{
name: 'page23',
path: '/page23',
component: page23
},
{
name: 'page24',
path: '/page24',
component: page24}
]
}
也正因为这个属性,所属在page2 下的路由,会寻找到page2中对应的
,这样就实现了嵌套路由的使用。下面把page2组件的代码贴出来:
<template>
<div id="pageId">
<span style="width: 100%;
display: block;
background-color: #545c64;
color: #ccc;">{{msg}},{{userName}}span>
<el-menu
:default-active="activeIndex"
class="el-menu-demo"
mode="horizontal"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
//这块是重点
<el-menu-item index="1"><router-link to="/page21">page21router-link>el-menu-item>
<el-menu-item index="2"><router-link to="/page22">page22router-link>el-menu-item>
<el-menu-item index="3"><router-link to="/page23">page23router-link>el-menu-item>
<el-menu-item index="4"><router-link to="/page24">page24router-link>el-menu-item>
<el-menu-item index=""><el-button type="text" @click="dialogVisible = true"><i class="el-icon-service">i>el-button>el-menu-item>
//这块是重点
el-menu>
<div class="line">div>
<el-dialog
title="提示"
:visible.sync="dialogVisible"
width="30%"
:before-close="handleClose">
<audio-a :src='src'>audio-a>
el-dialog>
//这块是重点
<keep-alive>
<router-view v-on:playthisa='playthisb'>router-view>
keep-alive>
//这块是重点
div>
template>
<script>
import Vue from 'vue'
import axios from 'axios'
import audioA from './audio'
export default( {
name: 'pageId',
data () {
return {
msg: 'welcome to I Music',
userName:this.$route.params.userName||"",
activeIndex: '1',
activeIndex2: '1',
src:'',
dialogVisible: false
}
},
mounted:function(){
this.isLogin()
},
components:{
'audio-a': audioA
},
methods:{
isLogin:function (param) {
if(!this.userName){
this.$router.push('/')
}else{
this.$router.push({ path: 'page21' })
}
},
playthisb(data){
this.src =data
},
handleClose(done) {
done();
}
}
})
script>
<style scoped>
a{ text-decoration:none}
style>
这样就是嵌套路由的完整应用了
5.
组件缓存,当组件内部需要重新渲染的时候,会将组件缓存在keep-alive中,防止每次切换导航,都会去重新加载请求。
精确控制到每一个组件是否需要缓存:
export default new Router({
routes: [
{
path: '/',
name: 'Hello',
component: Hello,
meta: {
keepAlive: false // 不需要缓存
}
},
{
path: '/page1',
name: 'Page1',
component: Page1,
meta: {
keepAlive: true // 需要被缓存
}
}
]
})
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
6.路由懒加载
大项目中,为了提高初始化页面的效率,路由一般使用懒加载模式,一共三种实现方式。
(1)第一种写法:
component: (resolve) => require(['@/components/One'], resolve)
(2)第二种写法:
component: () => import('@/components/Two')
(3)第三种写法:
components: r => require.ensure([], () => r(require('@/components/Three')), 'group-home')
PS:
一般常用第二种简写
第三种中,’group-home’是把组件按组分块打包, 可以将多个组件放入这个组中,在打包的时候Webpack会将相同 chunk 下的所有异步模块打包到一个异步块里面。
demo代码:https://github.com/jinguohua/demo
demo演示:https://jinguohua.github.io user:晋国华 psw :123