Vue3-路由详解

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

1.路由的理解

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

 各种方式

  1. 非编程式路由导航

  2. 编程式路由导航

展示区

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

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

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

  1. 普通组件一般需要手动写在某组件的<templete>标签体中,而路由组件是写在管理路由规则的文件中,通俗易懂的来说,普通组件写在html中,而路由组件写在js或ts中;

  2. 根据Vue3工程化写法的规则,普通组件存在于components命名的文件夹中,而路由组件存在于pages或views命名的文件夹中。

普通组件 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

创建

  1. 创建router文件夹,创建index.ts文件,这里是工程化创建方式,不一定非要这样命名。
  2. 从vue-router中引入创建路由的api,称createRouter;引入要创建路由的模式,一个历史模式,一个哈希模式。
    // src/router/index.ts
    import { createRouter, createWebHistory, createWebHashHistory  } from "vue-router"
    createWebHistory(History模式) 与 createWebHashHistory(Hash模式)的优缺点:
    createWebHistory(History模式)createWebHashHistory(Hash模式)
    路径中没有#,很美观路径中有#,不美观
    需要后端配合处理不需要后端处理
    常用在购物网,产品介绍网站常用在公司后台管理系统

  3. 引入路由组件(创建组件这里省略过程,跟普通组件一样,注意创建的位置就行)
    // 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'
  4. 创建路由规则,选择模式,不要忘记最后要把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
  5. 在入口文件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

接收参数

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

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

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

    // 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,
      }
    ]
  2. 简便收参:子组件直接通过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属性的详解。

所以编程式路由导航不仅简单,而且更加实用!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值