route/router带参数的路由跳转

  1. 1. 一、测试代码
  2. 2. 二、测试结果
  3. 3. 三、对应文档内容
    1. 3.1. 路由的渲染
    2. 3.2. 使用 route 获取路由信息
    3. 3.3. 使用 router 操作路由
    4. 3.4. 使用 router-link 标签跳转
      1. 3.4.1. 基础跳转
      2. 3.4.2. 带参数的跳转
      3. 3.4.3. 不生成 a 标签

一、测试代码

歌手导航栏组件

SingerNav.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
<div>
<span id="space" @click="clickme(1)">全部歌手</span>
<span id="space" @click="clickme(2)">男歌手</span>
<span id="space" @click="clickme(3)">女歌手</span>
</div>
</template>
<script setup>
import { useRouter } from "vue-router";
name: "SingerNav";
const router = useRouter();

function clickme(param) {
router.push({
name: "singer", // 要对应路由index.js 文件的路由name属性
params: {
type: param,
},
});
}
</script>

Singer.vue

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
28
29
30
31
32
33
34
35
36
37
38
39
40
<template>
singer
<button @click="goback">回退</button>
<div>{{ state.artists }}</div>
</template>

<script setup>
import { toRefs, ref, reactive } from "vue";
import { useRoute, useRouter } from "vue-router";
import axios from "axios";

name: "singer"; // 不影响跳转,为啥?
const route = useRoute();
const router = useRouter();
console.log(route.name); // 获取路由名称
const typeId = route.params.type;
console.log(route.params.type); // 获取路由参数

const state = reactive({
artists: {
type: Array,
},
});

const url =
"http://localhost:3000/artist/list?type=" + typeId + "&area=96&initial=b";

function initSinger() {
axios.get(url).then((response) => {
state.artists = response.data.artists;
});
}

initSinger(); // 初始化数据

function goback() {
// 返回上一页
router.back();
}
</script>

二、测试结果

随便点击一个

三、对应文档内容

路由的渲染

所有路由组件,要在访问后进行渲染,都必须在父级组件里带有 <router-view /> 标签。

<router-view /> 在哪里,路由组件的代码就渲染在哪个节点上。

一级路由的父级组件,当然就是 src 下的 App.vue

最基础的配置

最简单的基础格式,就是 template 里面直接就是 <router-view /> ,整个页面就是路由组件。

1
2
3
<template>
<router-view />
</template>

带有全局的公共组件

比如有全站统一的页头、页脚,只有中间区域才是路由。

1
2
3
4
5
6
7
8
9
10
<template>
<!-- 全局页头 -->
<Header />

<!-- 路由 -->
<router-view />

<!-- 全局页脚 -->
<Footer />
</template>

部分路由全局,部分路由带公共组件

比如大部分页面都需要有侧边栏,但登录页、注册页不能带。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<!-- 登录 -->
<Login v-if="route.name === 'login'" />

<!-- 注册 -->
<Register v-else-if="route.name === 'register'" />

<!-- 带有侧边栏的其他路由 -->
<div v-else>
<!-- 固定在左侧的侧边栏 -->
<Sidebar />

<!-- 路由 -->
<router-view />
</div>
</template>

使用 route 获取路由信息

和 2.x 可以直接在组件里使用 this.$route 来获取当前路由信息不同,在3.x 的组件里,Vue实例既没有了 this,也没有了 $route

要牢记一个事情就是,3.x 用啥都要导入,所以,获取当前路由信息的正确用法是:

1、导入路由组件

1
import { useRoute } from 'vue-router'

2、定义路由变量

刚刚导入的 useRoute 是一个函数,需要在 setup 里定义一个变量来获取路由信息。

1
const route = useRoute();

3、读取路由信息

接下来就可以通过定义好的变量 route 去获取当前路由信息了。

当然,如果要在 template 里使用路由,记得把 routesetup 里return出去。

1
2
3
4
5
// 获取路由名称
console.log(route.name);

// 获取路由参数
console.log(route.params.id);
带参数的路由跳转,可以在跳转后的页面获取这个参数,跳转的name属性要是路由配置(router—> index. js )组件name名

使用 router 操作路由

route 一样,在 3.x 也不再存在 this.$router ,也必须通过导入路由组件来使用。

1、导入路由组件

1
import { useRouter } from 'vue-router'

2、定义路由变量

useRoute 一样, useRouter 也是一个函数,需要在 setup 里定义一个变量来获取路由信息。

1
const router = useRouter();

3、操作路由

接下来就可以通过定义好的变量 router 去操作路由了。

1
2
3
4
5
6
7
// 跳转首页
router.push({
name: 'home'
})

// 返回上一页
router.back();

router-link 是一个路由组件,可直接在 template 里使用,基础的用法在 2.x 和 3.x 一样。

默认会被转换为一个 a 标签,对比写死的 <a href="..."> ,使用 router-link 会更加灵活。

基础跳转

最基础的用法就是把它当成一个 target="_self" 的a标签使用,但无需重新刷新页面,因为是路由跳转,它的体验和使用 router 去进行路由导航的效果完全一样。

1
2
3
<template>
<router-link to="/home">首页</router-link>
</template>

等价于 routerpush

1
2
3
router.push({
name: 'home'
})

你可以写个 span 然后绑定 click 事件来达到 router-link 的效果(但你看是不是麻烦很多emm…

1
2
3
4
5
6
7
8
9
10
<template>
<span
class="link"
@click="router.push({
name: 'home'
})"
>
首页
</span>
</template>

带参数的跳转

使用 router 的时候,可以轻松的带上参数去那些有id的内容页、用户资料页、栏目列表页等等。

比如你要访问一篇文章 https://chengpeiquan.com/article/123 ,用 push 的写法是:

1
2
3
4
5
6
router.push({
name: 'article',
params: {
id: 123
}
})

同理,从基础跳转的写法,很容易就能get到在 router-link 里应该怎么写:

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<router-link
class="link"
:to="{
name: 'article',
params: {
id: 123
}
}"
>
这是文章的标题
</router-link>
</template>

不生成 a 标签

router-link 默认是被转换为一个 a 标签,但根据业务场景,你也可以把它指定为生成其他标签,比如 spandivli 等等,这些标签因为不具备 href 属性,所以在跳转时都是通过 click 事件去执行。

在 2.x,指定为其他标签只需要一个 tag 属性即可:

1
2
3
<template>
<router-link tag="span" to="/home">首页</router-link>
</template>

但在 3.x ,tag 属性已被移除,需要通过 customv-slot 的配合来渲染为其他标签。

比如要渲染为一个带有路由导航功能的 div

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<template>
<router-link
to="/home"
custom
v-slot="{ navigate }"
>
<span
class="link"
@click="navigate"
>
首页
</span>
</router-link>
</template>

渲染后就是一个普通的 span 标签,当你点击的时候,它会通过路由的导航把你带到指定的路由页:

1
<span class="link">首页</span>

关于这2个属性,他们的参数说明如下:

  1. custom ,一个布尔值,用于控制是否需要渲染为 a 标签,当不包含 custom 或者把 custom 设置为 false 时,则依然使用 a 标签渲染。
  2. v-slot 是一个对象,用来决定标签的行为,它包含了:
字段 含义
href 解析后的URL,将会作为一个 a 元素的 href 属性
route 解析后的规范化的地址
navigate 触发导航的函数,会在必要时自动阻止事件,和 router-link 同理
isActive 如果需要应用激活的 class 则为 true,允许应用一个任意的 class
isExactActive 如果需要应用精确激活的 class 则为 true,允许应用一个任意的 class

一般来说,v-slot 必备的只有 navigate ,用来绑定元素的点击事件,否则元素点击后不会有任何反应,其他的可以根据实际需求来添加。

TIP

要渲染为非 a 标签,切记两个点:

  1. router-link 必须带上 customv-slot 属性
  2. 最终要渲染的标签,写在 router-link 里,包括对应的 className 和点击事件