vue-router路由使用实例详解

简介: vue-router路由使用实例详解

【1】路由入门

官网文档:https://router.vuejs.org/zh/installation.html

github: https://github.com/vuejs/vue-router

① 基础入门

① 下载安装

npm install vue-router --save

② 引入模块

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)

③ 创建router 模块

index.js如下所示

/*
路由器对象模块
 */
import Vue from 'vue'
import VueRouter from 'vue-router'
import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
// 声明使用vue-router插件
/*
内部定义并注册了2个组件标签(router-link/router-view),
给组件对象添加了2个属性:
  1. $router: 路由器
  2. $route: 当前路由
 */
Vue.use(VueRouter)
export default new VueRouter ({
  // 注册应用中所有的路由
  routes: [
    {
      path: '/about',
      component: About
    },
    {
      path: '/home',
      component: Home,
    },
     {//根路由
      path: '/',
      redirect: '/about'
    }
  ]
})

上面代码也可改写为如下方式:

/*路由器对象模块 */
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
    {
      path: '/about',
      name: "About",
      component: () =>import(/* webpackChunkName: "About" */ "../pages/About.vue")
    },
    {
      path: '/home',
      name:'Home',
      component: () =>import(/* webpackChunkName: "Home" */ "../pages/Home.vue"),
    },
     {//根路由
      path: '/',
      redirect: '/about'
    }
  ];
const router = new VueRouter({
    mode: "history",
    routes
});
export default router;

还可以指定绝对路径,如下所示:

//声明组件
import filmSchedule from '@/views/modules/filmSchedule/list'
//定义路由
{
    path: '/filmSchedule',
    name: '电影排片',
    component: filmSchedule
},

④ 入口js-main.js中配置路由组件

/*
入口JS
 */
import Vue from 'vue'
import App from './App.vue'
import router from './router'
/*配置对象的属性名称都是确定的名称 ,不能随便修改 */
new Vue({
  el: '#app',
  components: {App}, // 映射组件标签
  template: '<App/>', // 指定需要渲染到页面的模板
  router  // 注册路由器
})

⑤ 页面

<div class="list-group">
 <!--生成路由链接-->
 <router-link to="/about" class="list-group-item">About</router-link>
 <router-link to="/home" class="list-group-item">Home</router-link>
</div>
 <div class="panel-body">
  <!--显示当前组件-->
    <keep-alive>
      <router-view msg="abc"></router-view>
    </keep-alive>
  </div>

② 重定向和别名

重定向也是通过 routes 配置来完成,下面例子是从 /a 重定向到 /b

const router = new VueRouter({
  routes: [
    { path: '/a', redirect: '/b' }
  ]
})

重定向的目标也可以是一个命名的路由:

const router = new VueRouter({
  routes: [
    { path: '/a', redirect: { name: 'foo' }}
  ]
})

甚至是一个方法,动态返回重定向目标:

const router = new VueRouter({
  routes: [
    { path: '/a', redirect: to => {
      // 方法接收 目标路由 作为参数
      // return 重定向的 字符串路径/路径对象
    }}
  ]
})

注意导航守卫并没有应用在跳转路由上,而仅仅应用在其目标上。在下面这个例子中,为 /a 路由添加一个 beforeEnter 守卫并不会有任何效果。


别名


“重定向”的意思是,当用户访问 /a时,URL 将会被替换成 /b,然后匹配路由为 /b,那么“别名”又是什么呢?


/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。


上面对应的路由配置为:

const router = new VueRouter({
  routes: [
    { path: '/a', component: A, alias: '/b' }
  ]
})

“别名”的功能让你可以自由地将 UI 结构映射到任意的 URL,而不是受限于配置的嵌套路由结构。

③ 命名路由


有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。你可以在创建 Router 实例的时候,在 routes 配置中给某个路由设置名称。

const router = new VueRouter({
  routes: [
    {
      path: '/user/:userId',
      name: 'user',
      component: User
    }
  ]
})

要链接到一个命名路由,可以给 router-linkto 属性传一个对象:

<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

这跟代码调用 router.push() 是一回事:

router.push({ name: 'user', params: { userId: 123 } })

这两种方式都会把路由导航到 /user/123 路径。


【2】嵌套路由

路由模块的index.js

/*
路由器对象模块
 */
import Vue from 'vue'
import VueRouter from 'vue-router'
import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
import News from '../pages/News.vue'
import Message from '../pages/Message.vue'
import MessageDetail from '../pages/MessageDetail.vue'
// 声明使用vue-router插件
Vue.use(VueRouter)
export default new VueRouter ({
  // 注册应用中所有的路由
  routes: [
    {
      path: '/about',
      component: About
    },
    {
      path: '/home',
      component: Home,
      children: [
        {
          path: '/home/news',//path最左侧/代表根路径
          component: News
        },
        {
          path: 'message',//这里没有用/ 表示相对路径
          component: Message,
          children: [
            {
              path:'detail/:id',
              component: MessageDetail
            }
          ]
        },
        {
          path: '',
          redirect: '/home/news'
        }
      ]
    },
    {
      path: '/',
      redirect: '/about'
    }
  ]
})


页面

<template>
  <div>
    <h2>Home</h2>
    <div>
      <ul class="nav nav-tabs">
        <li><router-link to="/home/news">News</router-link></li>
        <li><router-link to="/home/message">Message</router-link></li>
      </ul>
      <router-view></router-view>
    </div>
  </div>
</template>

【3】缓存路由组件对象

默认情况下, 被切换的路由组件对象会死亡释放, 再次回来时是重新创建的。如果可以缓存路由组件对象, 可以提高用户体验。


可以使用标签keep-aliverouter-view包含,这样被访问过的路由就会保持生存。

<keep-alive>
  <router-view></router-view>
</keep-alive>


【4】向路由组件传递数据

① 路由路径携带参数(param/query)


一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用。

配置路由

{
  path: 'message',
  component: Message,
  children: [
    {
      path:'detail/:id',
      component: MessageDetail
    }
  ]
}


页面

<ul>
  <li v-for="m in messages" :key="m.id">
  //这里是ES6语法,ES5语法为''
  <router-link :to="`/home/message/detail/${m.id}`">{{m.title}}</router-link>
  </li>
</ul>

如上所示即可通过URL传递id到路由。路由组件中读取请求参数this.$route.params.id。为什么不是this.$route.query.id呢?是因为这里没有使用?id=XX这种传参方式。

<script>
  export default {
    data() {
      return {
        detail: {}
      }
    },
    // 改变当前路由组件参数数据时, 不会重新创建组件对象, mounted不会重新执行
    mounted () {
      const id = this.$route.params.id
      this.detail = messageDetails.find(detail => detail.id===id*1)
    },
    watch: {
      $route: function () { // 改变当前路由组件参数数据时自动调用
        const id = this.$route.params.id
        this.detail = messageDetails.find(detail => detail.id===id*1)
      }
    }
  }
</script>


更多实例:

//两种正确写法
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user
//当前页面
this.$router.push(`concertDetail?concertId=${id}`)
this.$router.push({ path: 'concertDetail', query: { "concertId": id } })
//concertDetail页面获取参数
this.$route.query.concertId


<router-view>属性携带数据

页面如下所示:

<keep-alive>
  <router-view msg="abc"></router-view>
</keep-alive>

在路由模板页面可取到msg:

<template>
  <div>
    <h2>About</h2>
    <p>{{msg}}</p>
    <input type="text">
  </div>
</template>
<script>
  export default {
    props: {
      msg: String
    }
  }
</script>


【5】编程式路由导航

① router.push

除了使用 <router-link> 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。

router.push(location, onComplete?, onAbort?)

注意:在 Vue 实例内部,你可以通过 $router 访问路由实例。因此你可以调用 this.$router.push。


想要导航到不同的 URL,则使用 router.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。


当你点击 <router-link> 时,这个方法会在内部调用,所以说,点击 <router-link :to="..."> 等同于调用 router.push(...)

声明式 编程式
<router-link :to="..."> router.push(...)

该方法的参数可以是一个字符串路径,或者一个描述地址的对象。例如:

// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

注意:如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path:

const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user

同样的规则也适用于 router-link 组件的 to 属性。


在 2.2.0+,可选的在 router.push 或 router.replace 中提供 onComplete 和 onAbort 回调作为第二个和第三个参数。这些回调将会在导航成功完成 (在所有的异步钩子被解析之后) 或终止 (导航到相同的路由、或在当前导航完成之前导航到另一个不同的路由) 的时候进行相应的调用。在 3.1.0+,可以省略第二个和第三个参数,此时如果支持 Promise,router.push 或 router.replace 将返回一个 Promise。


注意: 如果目的地和当前路由相同,只有参数发生了改变 (比如从一个用户资料到另一个 /users/1 -> /users/2),你需要使用 beforeRouteUpdate 来响应这个变化 (比如抓取用户信息)。


② router.replace

router.replace(location, onComplete?, onAbort?)

router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。

声明式 编程式
<router-link :to="..." replace> router.replace(...)


使用实例如下:

<li v-for="m in messages" :key="m.id">
  <router-link :to="`/home/message/detail/${m.id}`">{{m.title}}</router-link>
  <button @click="pushShow(m.id)">push查看</button>
  <button @click="replaceShow(m.id)">replace查看</button>
</li>
methods: {
   pushShow (id) {
     this.$router.push(`/home/message/detail/${id}`)
   },
   replaceShow(id) {
     this.$router.replace(`/home/message/detail/${id}`)
   }
 }


总结如下:

1) this.$router.push(path): 相当于点击路由链接(可以返回到当前路由界面)
2) this.$router.replace(path): 用新路由替换当前路由(不可以返回到当前路由界面)
3) this.$router.back(): 请求(返回)上一个记录路由
4) this.$router.go(-1): 请求(返回)上一个记录路由
5) this.$router.go(1): 请求下一个记录路由


③ 替换路由参数并刷新路由

this.$router.replace({
  name: 'concertDetail',
  query: {
    concertId: id
  }
})
/**  兼容性好*/
window.location.reload()


目录
相关文章
|
10天前
|
JavaScript 网络架构
vue3 Elementplus 动态路由菜单不跳转问题
vue3 Elementplus 动态路由菜单不跳转问题
26 1
|
1天前
|
JavaScript 网络架构
vue3 【提效】自动路由(含自定义路由) unplugin-vue-router 实用教程
vue3 【提效】自动路由(含自定义路由) unplugin-vue-router 实用教程
8 0
vue3 【提效】自动路由(含自定义路由) unplugin-vue-router 实用教程
|
6天前
|
JavaScript
学习和分享关于 Vue.js 的路由(vue-router)
学习和分享关于 Vue.js 的路由(vue-router)
13 2
|
6天前
|
JavaScript
vue 自动注册路由
vue 自动注册路由
14 1
|
9天前
|
JavaScript 前端开发 程序员
探索Vue.js宝库:解锁基础知识与实用技能之门(1. 数据绑定与响应式 2. 条件与循环 3. 组件化开发;1. 路由管理与导航 2. 状态管理与Vuex 3. Vue.js的生命周期)
探索Vue.js宝库:解锁基础知识与实用技能之门(1. 数据绑定与响应式 2. 条件与循环 3. 组件化开发;1. 路由管理与导航 2. 状态管理与Vuex 3. Vue.js的生命周期)
14 1
|
10天前
|
JavaScript 前端开发 网络架构
Vue如何实现页面跳转路由,实现单页面跳转
Vue如何实现页面跳转路由,实现单页面跳转
|
9天前
|
JavaScript
Vue搭配ELEMENT组件,路由不能正确跳转bug
Vue搭配ELEMENT组件,路由不能正确跳转bug
Vue搭配ELEMENT组件,路由不能正确跳转bug
|
13天前
|
JavaScript 前端开发 网络架构
4.vue路由
4.vue路由
13 1
|
2天前
|
JavaScript 数据安全/隐私保护
vue实战——路由访问权限【详解】
vue实战——路由访问权限【详解】
8 0