声明式导航

1.3k 词

声明式导航#

导航链接#

需求:实现导航高亮效果
027声明式导航_cut_1701681895592
vue-router提供了一个全局组件router-link(取代a标签)

1
2
<a href="#/find">发现音乐</a>
<router-link to="/find">发现音乐</router-link>
  1. 能跳转,配置to属性指定路径(必须)。本质还是a标签,**to无需加#**
  2. 能高亮,默认就会提供高亮类名,可以直接设置高亮样式

在将原本导航栏的a标签替换为router-link组件后,可以发现,渲染到页面后,组件还是被解析为了a标签,不过上面多了两个类
027声明式导航_cut_1701666598353
此时要添加高亮样式,就只需通过这两个类任意一个指定其样式即可,例如:

1
2
3
.footer_wrap a.router-link-active {
background-color: #ff3555;
}

两个类名#

在上面发现router-link自动给当前导航添加了两个高亮类名

  1. router-link-active模糊匹配(用的多)
    to="/my"可以匹配/my/my/a/my/b
  2. router-link-exact-active精确匹配
    to="/my"仅可以匹配/my

实际开发过程中,多使用router-link-active

自定义匹配类名#

router-link的两个高亮类名较长,是因为要避免与其它类名冲突,是可以根据自己的需求定制这两个类名
vue 官方提供的定制方法:

1
2
3
4
5
6
const router=new VueRouter({
routes:[...],
// link自定义高亮类名
linkActiveClass: '类名1', // 配置模糊匹配类名
linkExactActiveClass: '类名2', // 精确匹配
})

跳转传参#

在跳转路由时,可以进行传值
以程序员搜索应用为例
效果如下:
点击链接
027声明式导航_cut_1701854178409
将点击关键字作为参数传递到相应页面做展示
027声明式导航_cut_1701854428085

查询参数传参#

  1. 语法格式如下:
    to="/path?参数名=值"

Home.vue:

1
2
3
<router-link to="/search?key=黑马程序员">黑马程序员</router-link>
<router-link to="/search?key=前端培训">前端培训</router-link>
<router-link to="/search?key=如何成为前端大牛">如何成为前端大牛</router-link>
  1. 对应页面组件接收传递过来的值
    $route.query.参数名

Search.vue:

1
<p>搜索关键字: {{ $route.query.key }}</p>
1
2
3
4
5
6
export default {
// ...
created() {
// 在created中,获取路由参数:this.$route.query.参数名 获取
},
};

动态路由传参#

  1. 配置动态路由
1
2
3
4
5
6
7
8
9
const router = new VueRouter({
routes: [
// ...
{
path: '/search/:words',
components: Search,
},
],
});
  1. 配置导航链接
    to="/path/参数值"
  • 对应页面组件接收传递过来的值
    $route.params.参数名

动态路由参数可选符#

问题:配了路由path:"/search/:words",按以下步骤操作,会未匹配到组件,显示空白?
027声明式导航_cut_1702011933636
原因/search/:words表示,必须要传参数。若不传递参数,也希望匹配,可以加上一个可选符"?"

1
2
3
4
5
6
const router = new VueRouter({
routes: [
{ path: '/home', component: Home },
{ path: '/search/:words?', component: Search },
],
});

两种传参方式的区别#

  1. 查询参数传参(比较适合传多个参数
    • 跳转:to="/path?参数名1=值1&参数名2=值2"
    • 获取:$route.query.参数名
  2. 动态路由传参(优雅简洁,传单个参数比较方便) - 配置动态路由:path:"/path/参数名" - 跳转:to="/path/参数值" - 获取:$route.params.参数名

源码如下:
App.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
<template>
<div id="app">
<div class="link">
<router-link to="/home">首页</router-link>
<router-link to="/search">搜索页</router-link>
</div>

<router-view></router-view>
</div>
</template>

<script>
export default {};
</script>

<style lang="less" scoped>
.link {
height: 50px;
line-height: 50px;
background-color: #495150;
display: flex;
margin: -8px -8px 0 -8px;
margin-bottom: 50px;
}
.link a {
display: block;
text-decoration: none;
background-color: #ad2a26;
width: 100px;
text-align: center;
margin-right: 5px;
color: #fff;
border-radius: 5px;
&.router-link-active {
background-color: #ff3555;
}
}
</style>

Home.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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<template>
<div class="home">
<div class="logo-box"></div>
<div class="search-box">
<input type="text" />
<button>搜索一下</button>
</div>
<div class="hot-link">
热门搜索:
<router-link to="/search/黑马程序员">黑马程序员</router-link>
<router-link to="/search/前端培训">前端培训</router-link>
<router-link to="/search/如何成为前端大牛">如何成为前端大牛</router-link>
</div>
</div>
</template>

<script>
export default {
name: 'FindMusic',
};
</script>

<style lang="less" scoped>
.logo-box {
height: 150px;
background: url('@/assets/buggy.jpg') no-repeat center;
background-size: contain;
}
.search-box {
margin-top: 10px;
display: flex;
justify-content: center;
}
.search-box input {
width: 400px;
height: 30px;
line-height: 30px;
border: 2px solid #c4c7ce;
border-radius: 4px 0 0 4px;
outline: none;
}
.search-box input:focus {
border: 2px solid #ad2a26;
}
.search-box button {
width: 100px;
height: 36px;
border: none;
background-color: #ad2a26;
color: #fff;
position: relative;
left: -2px;
border-radius: 0 4px 4px 0;
}
.hot-link {
width: 508px;
height: 60px;
line-height: 60px;
margin: 0 auto;
}
.hot-link a {
margin: 0 5px;
}
</style>

Search.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
<template>
<div class="search">
<p>搜索关键字: {{ $route.params.words }}</p>
<p>搜索结果:</p>
<ul>
<li>.............</li>
<li>.............</li>
<li>.............</li>
<li>.............</li>
</ul>
</div>
</template>

<script>
export default {
name: 'MyFriend',
created() {
// 在created中,获取路由参数:this.$route.query.参数名 获取查询参数
// 动态路由传参用this.$route.params.参数名 获取动态路由参数
// console.log(this.$route.query.key);
console.log(this.$route.params.words);
},
};
</script>

<style>
.search {
width: 400px;
height: 240px;
padding: 0 20px;
margin: 0 auto;
border: 2px solid #c4c7ce;
border-radius: 5px;
}
</style>

router/index.js 路由模块:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import Home from '@/views/Home';
import Search from '@/views/Search';
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter); // VueRouter插件初始化

// 创建了一个路由对象
const router = new VueRouter({
routes: [
{ path: '/home', component: Home },
{ path: '/search/:words?', component: Search },
],
});

export default router;