目录
vue-router的安装
注:如果是使用 vue-cli + webpack进行创建vue项目的时候,其中惠游一个选项告知是否安装vue-router,如果选的是YES,则可以跳过npm依赖安装的步骤
再项目根目录键入指令
npm install vue-router --save
普通路由的挂载 (vue+cli_webpack + vue-router安装状态下)
1、在components文件夹下新建Hi.vue文件
2、创建vue代码
3、在src/router/index.js文件中挂载Hi.vue
4、<router-view></router-view> 放在哪个位置,路由就在哪个位置加载
Hi.vue
<!-- Hi页面 -->
<template>
<div>导航栏
<div>第一部分</div>
<router-link to='/hi/hi1'>导航1</router-link>
<router-link to='/hi/hi2'>导航2</router-link>
<router-view></router-view>
<div>第二部分</div>
</div>
</template>
<script>
export default {
name: 'Hi',
data () {
return {
}
},
// 生命周期 - 创建完成(访问当前this实例)
created () {
},
// 生命周期 - 挂载完成(访问DOM元素)
mounted () {
}
}
</script>
<style scoped>
/* @import url(); 引入css类 */
</style>
index.js文件 —— 两个注意点
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Hi from '@/components/Hi' // 注意点1:文件的导入
Vue.use(Router)
export default new Router({
routes: [
{ path: '/', name: 'HelloWorld', component: HelloWorld },
{ // 注意点2:路由配置
path: '/hi',
name: 'h1',
component: Hi,
}
]
})
子路由的配置
1、上一步基础上 在components文件夹新建Hi1.vue文件和Hi2.vue文件夹
2、在src/router/index.js文件下配置Hi.vue文件的子路由
3、在Hi.vue文件夹下配置路由标签
Hi1.vue
<!-- Hi1 -->
<template>
<div>我是导航1</div>
</template>
<script>
export default {
name: 'Hi1',
data () {
return {
}
},
// 生命周期 - 创建完成(访问当前this实例)
created () {
},
// 生命周期 - 挂载完成(访问DOM元素)
mounted () {
}
}
</script>
<style scoped>
/* @import url(); 引入css类 */
</style>
Hi2.vue
<!-- Hi2 -->
<template>
<div>我是导航2</div>
</template>
<script>
export default {
name: 'Hi2',
data () {
return {
}
},
// 生命周期 - 创建完成(访问当前this实例)
created () {
},
// 生命周期 - 挂载完成(访问DOM元素)
mounted () {
}
}
</script>
<style scoped>
/* @import url(); 引入css类 */
</style>
index.js —— 五个注意点
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Hi from '@/components/Hi' // 注意点1
import Hi1 from '@/components/Hi1' // 注意点2
import Hi2 from '@/components/Hi2' // 注意点3
Vue.use(Router)
export default new Router({
routes: [
{ path: '/', name: 'HelloWorld', component: HelloWorld },
{ // 注意点4
path: '/hi',
// name: 'h1', 注意点6
component: Hi,
children: [ // 注意点5
{ path: '/', name: 'hi',},
{ path: 'hi1', component: Hi1 },
{ path: 'hi2', component: Hi2 }
]
}
]
})
Hi.vue —— 两个注意点
<!-- Hi页面 -->
<template>
<div>导航栏
<router-link to='/hi/hi1'>导航1</router-link> // 注意点1
<router-link to='/hi/hi2'>导航2</router-link>
<router-view/> // 注意点2
</div>
</template>
<script>
export default {
name: 'Hi',
data () {
return {
}
},
// 生命周期 - 创建完成(访问当前this实例)
created () {
},
// 生命周期 - 挂载完成(访问DOM元素)
mounted () {
}
}
</script>
<style scoped>
/* @import url(); 引入css类 */
</style>
路由的分离与封装 (继续依托上述基础)
1、在src目录下新建文件common/config/router.js
import HelloWorld from '@/components/HelloWorld'
import Hi from '@/components/Hi'
import Hi1 from '@/components/Hi1'
import Hi2 from '@/components/Hi2'
export let routers = [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
}, {
path: '/hi',
// name: 'hi',
component: Hi,
children: [
{
path: '/',
name: 'hi'
// component: Hi
},
{
path: 'hi1',
component: Hi1
},
{
path: 'hi2',
component: Hi2
}
]
}
]
2、修改原本的router下的router.js文件
import Vue from 'vue'
import Router from 'vue-router'
// import HelloWorld from '@/components/HelloWorld' // 注意1
// import Hi from '@/components/Hi'
// import Hi1 from '@/components/Hi1'
// import Hi2 from '@/components/Hi2'
import {routers} from '@/common/config/router.js' // 注意2
Vue.use(Router)
export default new Router({
routes: routers // 注意3
// routes: [ // 注意4
// {
// path: '/',
// name: 'HelloWorld',
// component: HelloWorld
// }, {
// path: '/hi',
// name: 'hi',
// component: Hi,
// children: [
// {
// path: '/'
// // component: Hi
// },
// {
// path: 'hi1',
// component: Hi1
// },
// {
// path: 'hi2',
// component: Hi2
// }
// ]
// }
// ]
})
路由的重定向 (在上述基础上) redirect设置
在src/common/router/index.js中新增一个配置项 redirect
import HelloWorld from '@/components/HelloWorld'
import Hi from '@/components/Hi'
import Hi1 from '@/components/Hi1'
import Hi2 from '@/components/Hi2'
export let routers = [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
}, {
path: '/hi',
// name: 'hi',
component: Hi,
children: [
{
path: '/',
name: 'hi'
// component: Hi
},
{
path: 'hi1',
component: Hi1
},
{
path: 'hi2',
component: Hi2
}
]
}, { // 注意1:name的值是之前路由中定义的一个name名字
path: '*',
redirect: {name: 'HelloWorld'}
}
]
vue的mode配置项
mode设置有两个选项,配置new Router() 实例中
配置1、默认为 hash 可以不进行配置,页面将是锚的状态,即在 访问域名#路由名称
配置2、history: 正常的状态,即 访问域名/路由名称 比较倾向于我们之前的写法
// src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import {routers} from '@/common/config/router.js'
Vue.use(Router)
export default new Router({
mode: 'history', // 配置2
routes: routers
})
replace 的设置 防止路由堆栈
replace可以防止切换路由的时候进行堆栈。
相当于window.history.replaceState
只需要在需要配置的router-link中设置replace属性即可
<!-- Hi页面 -->
<template>
<div>导航栏
<div>上部部分</div>
<router-link to='/hi/hi1' replace>导航1</router-link>
<router-link to='/hi/hi2' replace>导航2</router-link>
<router-view/>
<div>人物部分</div>
</div>
</template>
<script>
export default {
name: 'Hi',
data () {
return {
}
},
// 生命周期 - 创建完成(访问当前this实例)
created () {
},
// 生命周期 - 挂载完成(访问DOM元素)
mounted () {
}
}
</script>
<style scoped>
/* @import url(); 引入css类 */
</style>
active-class / linkActiveClass 路由选中后样式的选项配置
配置方式分为两种
方法1:直接在router-link中添加属性 <router-link active-class="calss名称" >路由1</router-link>
方法2:在new Router() 实例中配置linkActiveClass 配置项
import Vue from 'vue'
import Router from 'vue-router'
import {routers} from '@/common/config/router.js'
Vue.use(Router)
export default new Router({
mode: 'history',
linkActiveClass: 'active', // 方法2
routes: routers
})
<!-- Hi页面 -->
<template>
<div>导航栏
<div>上部部分</div>
<!-- 方法1 -->
<!-- <router-link to='/hi/hi1' replace active-class="active">导航1</router-link>
<router-link to='/hi/hi2' replace active-class="active">导航2</router-link> -->
<!-- 方法2 -->
<router-link to='/hi/hi1' replace>导航1</router-link>
<router-link to='/hi/hi2' replace>导航2</router-link>
<router-view/>
<div>人物部分</div>
</div>
</template>
<script>
export default {
name: 'Hi',
data () {
return {
}
},
// 生命周期 - 创建完成(访问当前this实例)
created () {
},
// 生命周期 - 挂载完成(访问DOM元素)
mounted () {
}
}
</script>
<style scoped>
/* @import url(); 引入css类 */
.active{
color:red;
text-decoration: none;
}
</style>
this.$router的使用 路由跳转
this.$router.push()
在开发中,除了使用router-link进行路由跳转之外,还可以使用 this.$router进行跳转
this.$touter.push({path: 路由的地址})
切记,路由地址前要加 /
<!-- Hi页面 -->
<template>
<div>导航栏
<div>上部部分</div>
<!-- <router-link to='/hi/hi1' replace active-class="active">导航1</router-link>
<router-link to='/hi/hi2' replace active-class="active">导航2</router-link> -->
<!-- <router-link to='/hi/hi1' replace>导航1</router-link>
<router-link to='/hi/hi2' replace>导航2</router-link> -->
<!-- this.$router.push进行跳转 -->
<button @click="toRouterHi1">导航1</button>
<button @click="toRouterHi2">导航2</button>
<router-view/>
<div>人物部分</div>
</div>
</template>
<script>
export default {
name: 'Hi',
data () {
return {
}
},
methods: {
toRouterHi1 () {
this.$router.push({path: '/hi/hi1'}) // 注意要加 /
},
toRouterHi2 () {
this.$router.push({path: '/hi/hi2'})
}
},
// 生命周期 - 创建完成(访问当前this实例)
created () {
},
// 生命周期 - 挂载完成(访问DOM元素)
mounted () {
}
}
</script>
<style scoped>
/* @import url(); 引入css类 */
.active{
color:red;
text-decoration: none;
}
</style>
this.$router.replace
如果不想使路由进行堆栈操作的话,则使用
this.$router.replace({path: 跳转路由})
<!-- Hi页面 -->
<template>
<div>导航栏
<div>上部部分</div>
<!-- <router-link to='/hi/hi1' replace active-class="active">导航1</router-link>
<router-link to='/hi/hi2' replace active-class="active">导航2</router-link> -->
<!-- <router-link to='/hi/hi1' replace>导航1</router-link>
<router-link to='/hi/hi2' replace>导航2</router-link> -->
<button @click="toRouterHi1">导航1</button>
<button @click="toRouterHi2">导航2</button>
<router-view/>
<div>人物部分</div>
</div>
</template>
<script>
export default {
name: 'Hi',
data () {
return {
}
},
methods: {
toRouterHi1 () {
// this.$router.push({path: '/hi/hi1'})
this.$router.replace({path: '/hi/hi1'}) // 防止堆栈
},
toRouterHi2 () {
// this.$router.push({path: '/hi/hi2'})
this.$router.replace({path: '/hi/hi2'}) // 防止堆栈
}
},
// 生命周期 - 创建完成(访问当前this实例)
created () {
},
// 生命周期 - 挂载完成(访问DOM元素)
mounted () {
}
}
</script>
<style scoped>
/* @import url(); 引入css类 */
.active{
color:red;
text-decoration: none;
}
</style>
注:$router中,当连续点击同一路由出现报错信息的解决方案
在vue-router3.0中,当使用push或者replace的时候,连续点击同一路由时,会出现报错信息
Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation to current location:
只需要在使用Vue.use(Router)的地方垢面加上下面 第一段、第二段 代码即可
或者
在路由跳转的时候使用
this.$router.push({path:'/hi/hi2'}).catch(err => err)
原理就是将错误信息抛出便可
import Vue from 'vue'
import Router from 'vue-router'
import {routers} from '@/common/config/router.js' // 注意2
Vue.use(Router)
// push路由重复点击警告问题 // 第一段
const pushOrg = Router.prototype.push
Router.prototype.push = function push (to) {
return pushOrg.call(this, to).catch(err => err)
}
// replace路由重复点击警告问题 // 第二段
const replaceOrg = Router.prototype.replace
Router.prototype.replace = function replace (to) {
return replaceOrg.call(this, to).catch(err => err)
}
export default new Router({
mode: 'history',
linkActiveClass: 'active',
routes: routers // 注意3
})
动态传参 和 $route获取参数
动态传参
路由的动态传参共有两种
第一种:直接在定义路由的时候添加/:参数名
第二种:在跳转路由的时候使用 ?参数名=参数值&参数名=参数值 格式: ?id=1&name=zhang
步骤:
步骤1:在定义路由的时候 在路由后方添加 /:参数名
步骤2.1:在路由跳转的时候 在路由后方添加 /对应的参数值
或者
2.2:在路由后面使用 ?参数名=参数值&参数名=参数值
import HelloWorld from '@/components/HelloWorld'
import Hi from '@/components/Hi'
import Hi1 from '@/components/Hi1'
import Hi2 from '@/components/Hi2'
import Hi3 from '@/components/Hi3'
import VueBase from '@/components/VueBase'
import VueOne from '@/components/VueOne'
import VueTwo from '@/components/VueTwo'
import LessUse from '@/components/LessUse'
export let routers = [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/lessUse',
name: 'LessUse',
component: LessUse
},
{
path: '/vueBase',
name: 'VueBase',
component: VueBase
},
{
path: '/vueOne',
name: 'VueOne',
component: VueOne
},
{
path: '/vueTwo',
name: 'VueTwo',
component: VueTwo
},
{
path: '/hi',
// name: 'hi',
component: Hi,
children: [
{
path: '/',
name: 'hi'
// component: Hi
},
{
path: 'hi1/:id', // 步骤1
component: Hi1
},
{
path: 'hi2/:id/:userId', // 步骤1
component: Hi2
},
{
path: 'hi3/:id', // 步骤1
component: Hi3
}
]
}
// { // 注意1:name的值是之前路由中定义的一个name名字
// path: '*',
// redirect: {name: 'HelloWorld'}
// }
]
<!-- Hi页面 -->
<template>
<div>导航栏
<div>上部部分</div>
<!-- <router-link to='/hi/hi1' replace active-class="active">导航1</router-link>
<router-link to='/hi/hi2' replace active-class="active">导航2</router-link> -->
<!-- <router-link to='/hi/hi1' replace>导航1</router-link>
<router-link to='/hi/hi2' replace>导航2</router-link> -->
<button @click="toRouterHi1">导航1</button>
<button @click="toRouterHi2">导航2</button>
<button @click="toRouterHi3">导航3</button>
<router-view/>
<div>人物部分</div>
</div>
</template>
<script>
export default {
name: 'Hi',
data () {
return {
}
},
methods: {
numberRand (max = 1, min = 100) {
return (Math.random() * (max - min + 1) | 0) + min
},
toRouterHi1 () {
const id = parseInt(this.numberRand(1, 1000))
this.$router.push({path: `/hi/hi1/${id}`}) // 步骤2.1
// this.$router.replace({path: '/hi/hi1'})
},
toRouterHi2 () {
const id = parseInt(this.numberRand(1, 1000))
const userId = parseInt(this.numberRand(1, 10000))
this.$router.push({path: `/hi/hi2/${id}/${userId}`}) // 步骤2.1
// this.$router.replace({path: '/hi/hi2'})
},
toRouterHi3 () {
const id = parseInt(this.numberRand(1, 1000))
const name = '张三丰'
const age = 12
this.$router.push({path: `/hi/hi3/${id}?name=${name}&age=${age}`}) // 步骤2.1 + 2.2
}
},
// 生命周期 - 创建完成(访问当前this实例)
created () {
},
// 生命周期 - 挂载完成(访问DOM元素)
mounted () {
}
}
</script>
<style scoped>
/* @import url(); 引入css类 */
.active{
color:red;
text-decoration: none;
}
</style>
使用$route获取传参 $route.params 和 $route.query
使用1:当使用 /:参数名 进行传参的时候,获取需要使用 $route.params.参数名
使用2:当使用 ?参数名=参数值&参数名=参数值 进行传参的时候,获取需要使用 $route.query.参数名
<!-- -->
<template>
<div>我是导航3</div>
</template>
<script>
export default {
name: 'Hi3',
data () {
return {
}
},
// 生命周期 - 创建完成(访问当前this实例)
created () {
const id = this.$route.params.id // 使用1
const name = this.$route.query.name // 使用2
const age = this.$route.query.age // 使用2
console.log(id)
console.log(name)
console.log(age)
},
// 生命周期 - 挂载完成(访问DOM元素)
mounted () {
}
}
</script>
<style scoped>
/* @import url(); 引入css类 */
</style>
watch中监听$route中的传参变化
问题:当重复点击某一个设置了随机动态参数的路由的时候,第二次点击页面将无法在 created 或者 watched 中获取新得参数传值
方法:这个时候需要使用watch来监听 $route的变化
注1:当页面不刷新,仅仅参数变动的时候,在data中赋值this.$route给参数无效,因此需要在watch中直接监控$route
注2:在使用watch做监控的时候,尽量使用immediate+handler参数进行操作
<!-- -->
<template>
<div>我是导航3</div>
</template>
<script>
export default {
name: 'Hi3',
data () {
return {
id: this.$route.params.id, // 注1:重复点击的时候不好用
name: this.$route.query.name,
age: this.$route.query.age,
route: this.$route
}
},
watch: {
// $route () {
// console.log(this.$route.params.id)
// console.log(this.$route.query.name)
// console.log(this.$route.query.age)
// }
id: {
immediate: true,
handler: 'idChange'
},
name: {
immediate: true,
handler () {
this.nameChange()
}
},
age: {
immediate: true,
handler () {
this.ageChange()
}
},
route: {
immediate: true,
handler: 'routeChange'
},
$route: { // 注1 在这里监控$route才生效
immediate: true, // 注2
handler: 'routeChange1' // 注2
}
},
methods: {
idChange () {
console.log(this.id)
console.log(`id发生了改变`)
},
nameChange () {
console.log(`name发生了改变`)
},
ageChange () {
console.log(`age发生了改变`)
},
routeChange () {
console.log(`路由发生变化`)
},
routeChange1 () {
this.route = this.$route // 注1:重复点击的时候,当元素发生变化的时候需要进行重新赋值
this.id = this.$route.params.id // 注1:重复点击的时候,当元素发生变化的时候需要进行重新赋值
this.name = this.$route.query.name
this.age = this.$route.query.age
console.log(`真路由发生变化`)
}
},
// 生命周期 - 创建完成(访问当前this实例)
created () {
const id = this.$route.params.id
const name = this.$route.query.name
const age = this.$route.query.age
console.log(id)
console.log(name)
console.log(age)
},
// 生命周期 - 挂载完成(访问DOM元素)
mounted () {
}
}
</script>
<style scoped>
/* @import url(); 引入css类 */
</style>