文章

Vue3基础——路由

基本使用

使用路由需要安装依赖,使用npm i vue-router安装,在src目录下创建router目录,存放路由的.ts文件

使用路由的基本步骤

  1. 定义并导出路由,设置路由和工作模式
  2. 设置app的路由
  3. 设置host和link

定义路由

定义一个基本的路由文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import {createRouter, createWebHistory} from 'vue-router'

// 子组件
import Home from '@/components/Home.vue'
import News from '@/components/News.vue'
import About from '@/components/About.vue'

// 调用createRouter创建路由并导出
export const router = createRouter({
  // 设置路由的工作模式
  history: createWebHistory(),
  // 设置路由,每个对象包含path和component两个属性
  routes: [
    {
      path: '/home',
      component: Home,
    },
    {
      path: '/news',
      component: News,
    },
    {
      path: '/about',
      component: About,
    }
  ]
})

设置app路由

调用use函数设备app路由

1
2
3
4
5
6
7
import { createApp } from 'vue'
import App from './App.vue'
import { router } from './router'

const app = createApp(App)
app.use(router)
app.mount('#app')
  • RouterView标签设置host
  • RouterLink标签设置link
    • to属性:指定路径
    • active-class属性:设置选中样式类名
    • replace属性:导航时替换栈顶页面
1
2
3
4
5
6
7
8
9
<div class="navigate">
    <RouterLink to="/home" active-class="active">首页</RouterLink>
    <RouterLink to="/news" active-class="active">新闻</RouterLink>
    <!--to属性的对象写法-->
    <RouterLink :to="{path: '/about'}" active-class="active">关于</RouterLink>
</div>
<div class="display">
    <RouterView></RouterView>
</div>

路由工作模式

路由有两种工作模式

  • history:在URL上以传统路径显示,需要后端处理路径问题
  • hash:在URL中存在一个#,hash值出现在URL中但不会包含在请求中,对后端无影响

两种模式对应两个函数

  • history:createWebHistory()
  • hash:createdWebHashHistory()

命名路由

对routes属性中的路由对象设置name属性,在link时通过name属性绑定路由对象

1
2
3
4
5
6
7
8
9
10
export const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      name: 'home'
      path: '/home',
      component: Home,
    },
  ]
})

在link时使用to属性对象,通过设置name属性设置映射对象

1
<RouterLink :to="{name: 'home'}" active-class="active">首页</RouterLink>

嵌套路由

在定义映射时设置映射对象的children属性,传入子映射

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/news',
      component: News,
      children: [
        {
          path: 'detail'
          component: Detail
        }
      ]
    },
  ]
})

link时设置URL路径

1
<RouterLink to="/news/detail">新闻</RouterLink>

路由传参

路由参数有两种形式

  • query:直接显示在URL中的参数
  • params:RESTful风格的路径参数

参数在传递时有两种形式

  • 字符串
  • to属性对象

query参数

query参数直接写在link路径中

1
<RouterLink to="/news/detail?key1=value1&key2=value2">新闻1</RouterLink>

子组件接收参数时,需要先获取到route对象,通过route对象获取参数

1
2
3
4
5
6
7
8
9
10
11
<script setup lang="ts">
import {toRefs} from "vue";
import {useRoute} from "vue-router";
const route = useRoute();
const {query} = toRefs(route)
</script>

<template>
<div>{ {query.key1} }</div>
<div>{ {query.key2} }</div>
</template>

当传入列表项数据时,使用模板字符串或to属性对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!--模板字符串写法-->
<li v-for="item in news" :key="item.id">
    <RouterLink :to="`/news/detail?id=${item.id}&title=${item.title}&content=${item.content}`">
        { {item.title} }
    </RouterLink>
</li>

<!--对象写法-->
<li v-for="item in news" :key="item.id">
    <RouterLink :to="{
        path: '/news/detail',
        query: {
            id: item.id,
            title: item.title,
            content: item.content,
        },
    }">
        { {item.title} }
    </RouterLink>
</li>

params参数

定义路由时,在路径中规定参数的占位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
export const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/news',
      component: News,
      children: [
        {
          // 使用:param占位,后加?表示可选参数
          path: 'detail/:id/:title/:content?',
          component: Detail
        }
      ]
    },
  ]
})

在link中以路径形式传递参数

1
2
3
4
5
<li v-for="item in news" :key="item.id">
    <RouterLink :to="`/news/detail/${item.id}/${item.title}/${item.content}`">
        { {item.title} }
    </RouterLink>
</li>

params参数传递使用to属性对象时,只能使用命名路由,因此使用params参数时最好同时设置name属性

通过route对象的params属性获取参数

1
2
3
4
5
6
7
8
9
10
11
12
<script setup lang="ts">
import {useRoute} from "vue-router";
import {toRefs} from "vue";
const route = useRoute();
const {params} = toRefs(route);
</script>

<template>
<div>{ {params.id} }</div>
<div>{ {params.title} }</div>
<div>{ {params.content} }</div>
</template>

props配置

在路由对象中设置props: true,则将params参数以组件元素的属性形式传入

子组件接收时使用defineProps函数

1
2
3
4
5
6
7
8
9
<script setup lang="ts">
defineProps(['id', 'title', 'content'])
</script>

<template>
<div>{ {id} }</div>
<div>{ {title} }</div>
<div>{ {content} }</div>
</template>

传递query参数时,使用props函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
export const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/news',
      component: News,
      children: [
        {
          path: 'detail',
          component: Detail,
          props(route) {
            // 此处也可返回route.params
            return route.query
          }
        }
      ]
    },
  ]
})

命令式导航

通过router对象导航

1
2
3
4
5
6
7
import {useRouter} from "vue-router";
const router = useRouter();

function navigate() {
  // 调用replace方法替换栈顶
  router.push("/news");
}

push方法接收两种传参形式,都同时支持query参数和params参数

  • path字符串(不能接收name字符串
  • to属性对象

重定向

设置重定向路由对象,将路径重定向到已有路径

1
2
3
4
5
6
7
8
9
10
11
12
13
export const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/home',
      component: Home,
    },
    {
      path: '/',
      redirect: '/home',
    }
  ]
})
本文由作者按照 CC BY 4.0 进行授权