vue 路由的挂载 vue-router router-view router-link replace linkActiveClass mode

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>

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值