在Vue 3中,我们可以通过路由的查询参数来传递数据。这意味着我们可以在不同的页面之间传递一些信息,以便页面可以根据这些信息来显示不同的内容或执行不同的操作。
查询参数的使用方式类似于在URL中添加附加信息,以便页面之间可以根据这些信息进行交互和通信。这在很多应用中都非常有用,例如搜索功能、过滤功能、分页功能等等。
举个例子,假设我们有一个商品列表页面,用户可以在搜索框中输入关键字来搜索商品。当用户点击搜索按钮时,我们可以将输入的关键字作为查询参数添加到URL中,然后跳转到商品列表页面。在商品列表页面,我们可以通过读取查询参数的值来获取用户输入的关键字,并根据关键字来展示匹配的商品。
比如我在News组件中的detail使用了<RouterLink>
组件来创建一个链接,指向径/news/detail
并且附带了查询参数a=哇哈哈,b=华为,c=小米
。{、
显示了新闻的标题。当用户点击这个链接时,URL将会变成/news/detail?a=1,b=2,c=3
。注意,查询参数使用问号(?)来分隔路径和查询字符串。
未加参数前:
加参数后:
当我点击新闻里的标题时,就会看到路径中附带的参数
但这并不是动态参数的绑定,即无论你点击哪个新闻标题,都是出现同一样的URL。
所以现在要讲到动态参数的绑定,即我点击不同的新闻标题时,可以对应出现不同的参数,
1.路由-query参数
路由的查询参数是一种在URL中传递数据的机制。它们可以用于在不同的路由之间传递参数,以便组件可以根据这些参数进行不同的行为或显示不同的内容。
1.1 query参数的第一种写法
1.News组件传递query参数。
注意:
- 在to前面加上":"
- 在to的" "内加入反引号`(数字1的左边)
- 用$ 连接对象
2.query传参后在detail组件中修改内容
解析:
以上使用了route.query
来访问查询参数。通过route.query.id
、route.query.title
和route.query.content
,可以获取URL中的id
、title
和content
查询参数的值,并将它们显示在列表项中。
在<script setup>
部分,使用useRoute()
函数从Vue Router中导入了route
对象,并将它设置为响应式变量。这样就可以在模板中使用route.query
来访问查询参数的值。
3.展示
News组件代码:
<template>
<div class="news">
<!-- 导航区 -->
<ul>
<li v-for="news in newsList" :key="news.id">
<RouterLink :to="`/news/detail?id=${news.id}&title=${news.title}&content=${news.content}`">{{news.title}}</RouterLink>
</li>
</ul>
<!-- 展示区 -->
<div class="news-content">
<RouterView></RouterView>
</div>
</div>
</template>
<script setup lang="ts" name="News">
import {reactive} from 'vue'//
import {RouterView,RouterLink} from 'vue-router'
const newsList = reactive([
{id:'title01',title:'很好的抗癌食物',content:'西篮花'},
{id:'title02',title:'如何一夜暴富',content:'学IT'},
{id:'title03',title:'震惊,万万没想到',content:'明天是周一'},
{id:'title04',title:'好消息!好消息!',content:'快过年了'}
])
</script>
<style scoped>
/* 新闻 */
.news {
padding: 0 20px;
display: flex;
justify-content: space-between;
height: 100%;
}
.news ul {
margin-top: 30px;
list-style: none;
padding-left: 10px;
}
.news li>a {
font-size: 18px;
line-height: 40px;
text-decoration: none;
color: #64967E;
text-shadow: 0 0 1px rgb(0, 84, 0);
}
.news-content {
width: 70%;
height: 90%;
border: 1px solid;
margin-top: 20px;
border-radius: 10px;
}
</style>
Detail组件代码:
<template>
<ul class="news-list">
<li>编号:{{ route.query.id }}</li>
<li>标题:{{ route.query.title }}</li>
<li>内容:{{ route.query.content }}</li>
</ul>
</template>
<script setup lang="ts" name="About">
import { useRoute } from 'vue-router';
let route = useRoute();
</script>
<style scoped>
.news-list {
list-style: none;
padding-left: 20px;
}
.news-list>li {
line-height: 30px;
}
</style>
1.2 query参数的第二种写法
跳转并携带query参数(to的对象写法)
代码:
<template>
<div class="news">
<!-- 导航区 -->
<ul>
<li v-for="news in newsList" :key="news.id">
<!-- //第一种写法
<RouterLink :to="`/news/detail?id=${news.id}&title=${news.title}&content=${news.content}`">{{news.title}}
</RouterLink> -->
<!-- 第二种写法 -->
<RouterLink
:to="{
//name:'xiang', //用name也可以跳转
path:'/news/detail',
query:{
id:news.id,
title:news.title,
content:news.content
}
}"
>
{{news.title}}
</RouterLink>
</li>
</ul>
<!-- 展示区 -->
<div class="news-content">
<RouterView></RouterView>
</div>
</div>
</template>
<script setup lang="ts" name="News">
import {reactive} from 'vue'//
import {RouterView,RouterLink} from 'vue-router'
const newsList = reactive([
{id:'title01',title:'很好的抗癌食物',content:'西篮花'},
{id:'title02',title:'如何一夜暴富',content:'学IT'},
{id:'title03',title:'震惊,万万没想到',content:'明天是周一'},
{id:'title04',title:'好消息!好消息!',content:'快过年了'}
])
</script>
<style scoped>
/* 新闻 */
.news {
padding: 0 20px;
display: flex;
justify-content: space-between;
height: 100%;
}
.news ul {
margin-top: 30px;
list-style: none;
padding-left: 10px;
}
.news li>a {
font-size: 18px;
line-height: 40px;
text-decoration: none;
color: #64967E;
text-shadow: 0 0 1px rgb(0, 84, 0);
}
.news-content {
width: 70%;
height: 90%;
border: 1px solid;
margin-top: 20px;
border-radius: 10px;
}
</style>
补充:
有时候,你会觉得比较冗余,是否能简化一下,可以的。
整体代码:
<template>
<ul class="news-list">
<li>编号:{{ query.id }}</li>
<li>标题:{{ query.title }}</li>
<li>内容:{{ query.content }}</li>
</ul>
</template>
<script setup lang="ts" name="About">
import {toRefs} from 'vue'
import {useRoute} from 'vue-router'
let route = useRoute()
let {query} = toRefs(route)
</script>
<style scoped>
.news-list {
list-style: none;
padding-left: 20px;
}
.news-list>li {
line-height: 30px;
}
</style>
2.路由-params参数
2.1 params参数的第一种写法
1.还原Detail组件
2.还原News组件
3.在index.ts文件中子路的规则下占位
4.返回News组件中传入参数
5.我们可以通过console.log(route)观察params的参数(这步骤可无)
6.修改Detail组件的展示区(开始变成响应式)
7.修改News组件的内容(也是变成响应式)
展示:(这是标题1的,后面点击其他标题展示区会对应出现内容,就不一一展开了)
2.2. params参数的第二种写法
跟query的第二种写法类似,但有一点要区分!!!
注意这里是用name配置项的 ,而不是用path配置项。
那如果我偏用path来配置呢,那就喜提报错!
Detail组件代码:
<template>
<ul class="news-list">
<li>编号:{{ route.params.id }}</li>
<li>标题:{{ route.params.title }}</li>
<li>内容:{{ route.params.content }}</li>
</ul>
</template>
<script setup lang="ts" name="About">
import {useRoute} from 'vue-router'
const route = useRoute()
console.log(route)
</script>
<style scoped>
.news-list {
list-style: none;
padding-left: 20px;
}
.news-list>li {
line-height: 30px;
}
</style>
News组件代码
<template>
<div class="news">
<!-- 导航区 -->
<ul>
<li v-for="news in newsList" :key="news.id">
<!-- //第一种写法
<RouterLink :to="`/news/detail/${news.id}/${news.title}/${news.content}`">{{news.title}}</RouterLink> -->
<!-- 第二种写法 -->
<RouterLink
:to="{
name:'xiangqing',
params:{
id:news.id,
title:news.title,
content:news.content
}
}"
>
{{news.title}}
</RouterLink>
</li>
</ul>
<!-- 展示区 -->
<div class="news-content">
<RouterView></RouterView>
</div>
</div>
</template>
<script setup lang="ts" name="News">
import {reactive} from 'vue'//
import {RouterView,RouterLink} from 'vue-router'
const newsList = reactive([
{id:'title01',title:'很好的抗癌食物',content:'西篮花'},
{id:'title02',title:'如何一夜暴富',content:'学IT'},
{id:'title03',title:'震惊,万万没想到',content:'明天是周一'},
{id:'title04',title:'好消息!好消息!',content:'快过年了'}
])
</script>
<style scoped>
/* 新闻 */
.news {
padding: 0 20px;
display: flex;
justify-content: space-between;
height: 100%;
}
.news ul {
margin-top: 30px;
list-style: none;
padding-left: 10px;
}
.news li>a {
font-size: 18px;
line-height: 40px;
text-decoration: none;
color: #64967E;
text-shadow: 0 0 1px rgb(0, 84, 0);
}
.news-content {
width: 70%;
height: 90%;
border: 1px solid;
margin-top: 20px;
border-radius: 10px;
}
</style>
补充:
参数可传可不传的情况,比如:
再次提醒:
1.传递params
参数时,若使用to
的对象写法,必须使用name
配置项,不能用path
。
2.传递params
参数时,需要提前在规则中占位。