vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > Vue3的路由使用

Vue3中的路由使用解读

作者:在夜深人静的时候

本文总结了Vue3中路由相关的知识,包括路由的理解、路由的引入与创建、非编程式路由导航和编程式路由导航

今天总结下Vue3中路由相关的知识,大致分为以下4点:路由的理解,路由的引入与创建,非编程式路由导航,编程式路由导航。

1.路由的理解

单页面应用中,通过各种方式(点击或自动或条件跳转等等操作)使展示区中呈现路由组件

各种方式

展示区

写法为<routerView/>,vue-router提供的组件,使用时不需要引入,用于固定需要展示路由组件的位置。

路由组件和普通组件的区别

可以和普通组件做区分,路由组件和普通组件的区别:

普通组件 Header:
// src/App.vue
<script setup lang="ts">
import Header from './components/Header.vue'; 
</script>

<template>
  <Header/>
</template>
<style scoped>

</style>



路由组件 Home:
// src/router/index.ts
import Home from '@/pages/Home.vue'
const router = createRouter({
  history: createWebHashHistory(),
  routes: [
    {
      name: 'shouye',
      path: '/home',
      component: Home
    },
    
})

export default router

2.路由的引入和创建

引入

npm i vue-router

创建

创建router文件夹,创建index.ts文件,这里是工程化创建方式,不一定非要这样命名。

从vue-router中引入创建路由的api,称createRouter;引入要创建路由的模式,一个历史模式,一个哈希模式。

// src/router/index.ts
import { createRouter, createWebHistory, createWebHashHistory  } from "vue-router"

createWebHistory(History模式) 与 createWebHashHistory(Hash模式)的优缺点:

createWebHistory(History模式)createWebHashHistory(Hash模式)
路径中没有#,很美观路径中有#,不美观
需要后端配合处理不需要后端处理
常用在购物网,产品介绍网站常用在公司后台管理系统

引入路由组件(创建组件这里省略过程,跟普通组件一样,注意创建的位置就行)

// src/router/index.ts
import { createRouter, createWebHistory, createWebHashHistory  } from "vue-router"

import Home from '@/pages/Home.vue'
import About from '@/pages/About.vue'
import News from '@/pages/News.vue'
import Details from '@/pages/Details.vue'

创建路由规则,选择模式,不要忘记最后要把router暴露出去。

// src/router/index.ts
import { createRouter, createWebHistory, createWebHashHistory  } from "vue-router"
import Home from '@/pages/Home.vue'
import About from '@/pages/About.vue'
import News from '@/pages/News.vue'
import Details from '@/pages/Details.vue'

const router = createRouter({
  history: createWebHashHistory(),
  // createWebHistory:History模式  
  // createWebHashHistory:Hash模式
  routes: [
    {
      name: 'shouye',
      path: '/home,
      component: Home,
    },
    {
      name: 'guanyu',
      path: '/about',
      component: About,
    },
    {
      name: 'xinwen',
      path: '/news',
      component: News,
      children: [
        {
          name: 'xiangqing',
          path: 'details',
          component: Details
        }
      ]
    }
  ]
})

export default router

在入口文件main.ts中引入刚才创建好的路由规则,并且让vue使用它。这样我们的路由就已经创建好并使用规则了。

import './assets/main.css'
import { createApp } from 'vue'
import App from './App.vue'
import router from "@/router"; // 引入刚才创建的路由规则

const app = createApp(App) 
app.use(router) // 一定要在挂载之前使用这个规则
app.mount('#app')

3. 非编程式路由导航

上方已经创建好了路由规则,我们该在路由组件中去创建路由导航区和路由展示区了。

使用场景

点击路由导航区来切换展示区中的路由组件。

路由导航区

vue-router提供类似于a标签的组件<routerLink/>,标签体中可以写属性(push / replace)来决定跳转方法,默认为push方法。

replace 属性替换当前路由,没有不可回退;而push添加新的历史记录,支持回退。

// src/App.ts
<script setup lang="ts">
</script>

<template>
  <router-link to="/home" replace>首页</router-link> |
  <router-link to="/about" push>关于</router-link>|
  <router-link to="/news" push>新闻</router-link>
  <router-view/>
</template>

<style scoped>

</style>

标签属性

to属性(重点)

通过to属性可以指定目标路由,to属性支持6种传参方式,如下:

// const userId = ref('aaaaa')
// const userName= ref('bbbbbb')

// 1.to的字符串写法传递query参数
<router-link to="/detail/?userId=${userId}&userName=${userName}">详情</router-link> 

// 2.to的字符串写法传递param参数
<router-link to="/detail/${userId}/${userName}">详情</router-link> 

// 3.to的对象写法通过path方式传递query参数
<router-link :to="{path: '/detail', query: {userId, userName}">详情</router-link> 

// 4.to的对象写法通过path方式传递params参数
<router-link :to="{path: '/detail', params: {userId, userName}">详情</router-link> 

// 5.to的对象写法通过name方式传递query参数
<router-link :to="{name: 'xiangqing', query: {userId, userName}">详情</router-link> 

// 6.to的对象写法通过name方式传递params参数
<router-link :to="{name: 'xiangqing', params: {userId, userName}">详情</router-link> 

不同传参类型的路由规则配置

to传递不同类型的参数(query或params),会影响路由规则中path属性的写法。

// src/router/index.ts
import { createRouter, createWebHashHistory } from "vue-router"
import News from '@/pages/News.vue'
import Detail from '@/pages/Detail.vue'

const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      name: 'xinwen',
      path: '/news',
      component: News,
      // 注意:子组件path开头不加斜杠
      children: [
        {
          name: 'xiangqing',
          path: 'detail', // 1.传递query参数时,不用写占位符
          component: Detail,
        }
        
        {
          name: 'xiangqing',
          path: 'detail/:userId/:userName' // 2.传递param参数时,path必须用占位符
          component: Detail,
        }
      ]
    }
  ]
})

export default router

接收参数

子组件接收参数的方式也多种多样,这里距离两种常见的收参方式:

这里不展示同时传递两种类型参数的写法了,我选其中一种来进行演示。有兴趣的朋友可以自行研究一下,是可以同时传递的。

普通收参:子组件中拿到路由对象后需要手动解构出参数,对应的路由规则中不需要做任何额外变动。

// src/pages/detail.vue
<template>
    <div>我是{{ query.userId}}-{{ query.userName}}</div> // 或者
    <div>我是{{ params.userId}}-{{ params.userName}}</div>
</template>
<script setup lang="ts">
 import { toRefs } from "vue";
 import { useRoute } from "vue-router"; // 拿到路由
 const route = useRoute()
 // 响应式的数据解构出来的属性并不会是响应式的,需要toRefs手动响应式
 const { query, params } = toRefs(route)
</script>

<style scoped>
</style>
// src/router/index.ts 不需要添加其他额外属性
children: [
  {
    name: 'xiangqing',
    path: 'detail', 
    component: Detail,
  }
]

简便收参:子组件直接通过defineProps把参数定义出来就可以使用了,但对应的路由规则需要添加props属性,props有两种写法。

// src/pages/detail.vue
<template>
    <div>我是{{ userId }}-{{ userName }}</div> // 两种参数类型都可以直接用
</template>
<script setup lang="ts">
defineProps(['userId ','userName ']) // 定义出参数就可以用了
</script>

<style scoped>
</style>
// src/router/index.ts  对应的子组件路由规则
// 1.布尔类型props 
.....略.....
children: [
  {
    name: 'xiangqing',
    path: 'detail', 
    component: Detail,
    props: true  // 布尔写法只能处理params参数
  }
]
// 2.函数类型props
children: [
  {
    name: 'xiangqing',
    path: 'detail', 
    component: Detail,
    props(to) { // 函数写法既可以处理query参数,又可以处理params参数。
       return {
         query: to.query, 
         params: to.params
       } 
    }, 
  }
]
.....略.....

4. 编程式路由导航

理解

已经到这里了,没有仔细看前面非编程式路由导航的朋友一定要回去瞅瞅,你会发现你对编程式路由导航的学习成本为0,不信?请您继续看。

vue-router提供了一个API,叫useRouter,使用其实例中的跳转方法(push / replace)来切换展示区中的路由组件。

使用场景

需要根据条件切换路由组件。

写法示例

需求:点击不同的按钮,不同秒数后携带不同的参数进行不同方式路由跳转。

// src/pages/detail.vue
<template>
    <div>详情组件</div>
    <button @click="jump(3000, true)">点击我3秒后使用默认模式push进入详情1</button>
    <button @click="jump(5000, false)">点击我5秒后使用replace模式进入详情2</button>
    <router-view/>
</template>
<script setup lang="ts">
import { useRouter } from "vue-router";
const router = useRouter() // 引入路由器
let timer = null
function jump(delay: number, jumpType: boolean) {
  timer = setTimeout(() => {
    if(jumpType){
      router.push({ // 默认为push模式,可回退记录
        name: 'xiangqing',
        params: {
          id: '11',
          content: '1111'
        },
      })
    }else{
      router.replace({ // replace模式,不可回退。
        name: 'xiangqing',
        params: {
          id: 'params1',
          content: 'params2'
        },
        query: {
          id: 'query3',
          content: 'query4'
        },
      })
    }
  }, delay)
}
</script>

<style scoped>

</style>
  

发现没有朋友们,router.push(obj), 这个obj的写法,和前面的非编程式路由导航中的to写法一摸一样,没看懂的朋友可以看看前面对非编程式导航对to属性的详解。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文