如何在vue3+ts項(xiàng)目中使用query和params傳參
一 query 傳參 (類似get請求)
query 傳參方式①
傳遞方組件
home.vue
<template>
<div class='c'>
<p>query傳參</p>
<el-button type="success" @click="toList"> to list</el-button>
</div>
</template>
<script lang='ts' setup>
import { ref } from 'vue'
// 1 引入路由跳轉(zhuǎn)方法useRouter
import { useRouter } from 'vue-router'
// 2 拿到實(shí)例
const router = useRouter()
// 3 ref定義基本類型數(shù)據(jù)
const name = ref('梨花白')
// 4 query傳參
const toList = ()=>{
router.push({
//這種對象式傳參寫法 query除開和path搭配外還可以和name一起使用
path:'/list',
//或者這樣 path和name任選其一
//name:'List',
query:{
name:name.value
}
})
}
</script>
<style scoped>
.c{
width: 80%;
padding: 20px;
margin: 0 auto;
border:1px solid red;
}
.c>p>span{
color:coral;
}
</style>看下 router/index.ts 文件
import { createRouter,createWebHistory,RouteRecordRaw } from 'vue-router'
const routes:Array<RouteRecordRaw> = [
{
path:'/',
component:()=>import('../pages/home.vue')
},{
path:'/home',
name:'Home',//路由命名
component:()=>import('../pages/home.vue')
},{
path:'/list',
name:'List',//路由命名 為路由跳轉(zhuǎn)作準(zhǔn)備
component:()=>import('../pages/list.vue')
},{
//定義404頁面
path:'/404',
component:()=>import('../pages/notfound.vue')
},{
//匹配未定義路由 然后重定向至404頁面
path:'/:pathMath(.*)',
redirect:'/404'
}
]
const router = createRouter({
routes,
history:createWebHistory()
})
export default router有兩個(gè)注意點(diǎn)
① ref定義響應(yīng)式基本類型數(shù)據(jù)后,修改和賦值要帶上 .value
② query是一個(gè)對象類型 所以我們定義的基本類型數(shù)據(jù)不能直接賦值 要給對象式寫法 {}
像以下兩種寫法都是報(bào)錯(cuò)的
<script lang='ts' setup>
import { ref } from 'vue'
// 1 引入路由跳轉(zhuǎn)方法useRouter
import { useRouter } from 'vue-router'
// 2 拿到實(shí)例
const router = useRouter()
// 3 ref定義基本數(shù)據(jù)
const name = ref('梨花白')
// 4 query傳參
const toList = ()=>{
router.push({
path:'/list',
query:name //報(bào)錯(cuò) 不能將類型“Ref<string>”分配給類型“LocationQueryRaw”。
//類型“Ref<string>”中缺少類型“string”的索引簽名
})
}
</script><script lang='ts' setup>
import { ref } from 'vue'
// 1 引入路由跳轉(zhuǎn)方法useRouter
import { useRouter } from 'vue-router'
// 2 拿到實(shí)例
const router = useRouter()
// 3 ref定義基本數(shù)據(jù)
const name = ref('梨花白')
// 4 query傳參
const toList = ()=>{
router.push({
path:'/list',
query:name.value //報(bào)錯(cuò) 不能將類型“string”分配給類型“LocationQueryRaw”
})
}
</script>接收方組件
list.vue
<template>
<div class='c'>
<p>query接參</p>
<!-- 4 展示數(shù)據(jù) -->
<p>name: <span>{{ name }}</span></p>
</div>
</template>
<script lang='ts' setup>
// 1 引入useRoute路由信息方法
import { useRoute } from 'vue-router'
// 2 獲取實(shí)例
const route = useRoute()
// 3 解構(gòu)賦值
const { query:{name} } = route
</script>
<style scoped>
.c{
width: 80%;
padding: 20px;
margin: 0 auto;
border:1px solid red;
}
.c>P>span{
color:coral;
}
</style>效果:

動(dòng)態(tài)效果:

以上 我們可以得知 當(dāng)使用query傳參時(shí),參數(shù)的詳細(xì)內(nèi)容都會(huì)在地址欄完整的展示出來。
這對于數(shù)據(jù)安全來說是致命的
當(dāng)然也有它自有的優(yōu)勢:刷新不會(huì)丟失數(shù)據(jù)
下面看看使用query傳參的另一種形式:?傳參
query 傳參方式②
傳遞方組件
home.vue
<template>
<div class='c'>
<p>query傳參</p>
<el-button type="success" @click="toList"> to list</el-button>
</div>
</template>
<script lang='ts' setup>
import { toRefs,ref,reactive } from 'vue'
// 1 引入路由跳轉(zhuǎn)方法useRouter
import { useRouter } from 'vue-router'
// 2 拿到實(shí)例
const router = useRouter()
// 3 ref定義基本數(shù)據(jù)
const name = ref('桃花夭')
// 4 query ?傳參
const toList = ()=>{
router.push('/list?name=' + name.value)
//也可以使用ES6里的模板字符串
//router.push(`/list?name=${name.value}`)
}
</script>
<style scoped>
.c{
width: 80%;
padding: 20px;
margin: 0 auto;
border:1px solid red;
}
.c>p>span{
color:coral;
}
</style>效果:

動(dòng)態(tài)效果:

兩者效果別無二致 也有同學(xué)說我在傳入引用類型數(shù)據(jù)時(shí)老是報(bào)錯(cuò) 怎搞嘞
好的 下面開始傳遞引用類型數(shù)據(jù)
傳遞方組件
home.vue
<template>
<div class='c'>
<p>query傳參</p>
<el-button type="success" @click="toList"> to list</el-button>
</div>
</template>
<script lang='ts' setup>
import { ref,reactive } from 'vue'
// 1 引入路由跳轉(zhuǎn)方法useRouter
import { useRouter } from 'vue-router'
// 2 拿到實(shí)例
const router = useRouter()
// 3 定義數(shù)據(jù)接口類型
interface props {
id:number,
content:string
}
// 4 reactive定義引用類型數(shù)據(jù)
const arr:props[] = reactive([
{
id:1,
content:'關(guān)山難越,誰悲失路之人?'
},{
id:2,
content:'萍水相逢,盡是他鄉(xiāng)之客!'
}
])
// 4 或這樣
// const arr = reactive([
// {
// id:1,
// content:'關(guān)山難越,誰悲失路之人?'
// },{
// id:2,
// content:'萍水相逢,盡是他鄉(xiāng)之客!'
// }
// ] as props[])
// 5 query ?傳參
const toList = ()=>{
router.push('/list?arr=' + JSON.stringify(arr))
//也可以使用模板字符串
// router.push(`/list?arr=${JSON.stringify(arr)}`)
}
</script>
<style scoped>
.c{
width: 80%;
padding: 20px;
margin: 0 auto;
border:1px solid red;
}
.c>p>span{
color:coral;
}
</style>接收方組件
list.vue
<template>
<div class="c">
<p>query接參</p>
<!-- 4 展示數(shù)據(jù) -->
<p v-for="item in arr" :key="item.id">
<span>{{ item.content }}</span>
</p>
</div>
</template>
<script lang="ts" setup>
// 1 引入useRoute方法
import { useRoute } from "vue-router";
// 2 獲取實(shí)例
const route = useRoute();
// 3 使用JSON.parse()方法把傳過來的字符串參數(shù)轉(zhuǎn)回對象
const arr = JSON.parse(route.query.arr as string);
</script>
<style scoped>
.c {
width: 80%;
padding: 20px;
margin: 0 auto;
border: 1px solid red;
}
.c > P > span {
color: coral;
}
</style>效果:

動(dòng)態(tài)效果:

所以是
在使用?傳參傳入引用類型數(shù)據(jù)時(shí) 傳遞時(shí)要使用JSON.stringify()方法轉(zhuǎn)成字符串類型
在接收時(shí) 要使用JSON.parse()方法再轉(zhuǎn)回最初的類型
易錯(cuò)點(diǎn)如下:



query 傳參方式③
其實(shí)也就是聲明式路由跳轉(zhuǎn)時(shí)帶參
傳遞方組件
home.vue
<template>
<div class='c'>
<p>query傳參</p>
<router-link
//to的對象式寫法 與編程式路由跳轉(zhuǎn)傳參的對象式寫法相對應(yīng)
:to="{
path:'/list',
//或 name:'List'
query:{
arr:JSON.stringify(arr)
}
}">
<el-button type="success"> to list</el-button>
</router-link>
//<router-link
//to的字符串寫法 與編程式路由跳轉(zhuǎn)的?傳參寫法相對應(yīng)
// :to="`/list?arr=${JSON.stringify(arr)}`">
// <el-button type="success"> to list</el-button>
//</router-link>
</div>
</template>
<script lang='ts' setup>
import { toRefs,ref,reactive } from 'vue'
// 1 引入路由跳轉(zhuǎn)方法useRouter
import { useRouter } from 'vue-router'
// 2 拿到實(shí)例
const router = useRouter()
// 3 定義數(shù)據(jù)接口類型
interface props {
id:number,
content:string
}
// 4 ref定義基本數(shù)據(jù) 但未定義數(shù)據(jù)類型
const arr:props[] = reactive([
{
id:1,
content:'關(guān)山難越,誰悲失路之人?'
},{
id:2,
content:'萍水相逢,盡是他鄉(xiāng)之客!'
}
])
// 4 或這樣
// const arr = reactive([
// {
// id:1,
// content:'關(guān)山難越,誰悲失路之人?'
// },{
// id:2,
// content:'萍水相逢,盡是他鄉(xiāng)之客!'
// }
// ] as props[])
</script>
<style scoped>
.c{
width: 80%;
padding: 20px;
margin: 0 auto;
border:1px solid red;
}
.c>p>span{
color:coral;
}
</style>效果:

二 params 傳參 (類似post請求)
params 傳參 方式①
傳遞方組件
home.vue
<template>
<div class="c">
<p>params 傳參</p>
<el-button type="warning" @click="toList"> to list page</el-button>
</div>
</template>
<script lang='ts' setup>
import { toRefs,ref,reactive } from 'vue'
// 1 引入路由跳轉(zhuǎn)方法useRouter
import { useRouter } from 'vue-router'
// 2 拿到實(shí)例
const router = useRouter()
// 3 ref定義基本類型數(shù)據(jù)
const str = ref('月出于東山之上,徘徊于斗牛之間。')
// 4 params 傳參 只能搭配name使用 path會(huì)忽略params帶參
const toList = ()=>{
router.push({
name:'List',
params:{
str:str.value
}
})
}
</script>
<style scoped>
.c{
width: 80%;
padding: 20px;
margin: 0 auto;
border:1px solid red;
}
.c>p>span{
color:coral;
}
</style>接收方組件
list.vue
<template>
<div class="c">
<p>params接參</p>
<!-- 4 展示數(shù)據(jù) -->
<p>str: <span>{{ str?str:'刷新我就不見啦!' }}</span></p>
</div>
</template>
<script lang="ts" setup>
// 1 引入useRoute路由信息方法
import { useRoute } from "vue-router";
// 2 獲取實(shí)例
const route = useRoute();
// 3 解構(gòu)賦值 刷新頁面 參數(shù)丟失
const { params:{str} } = route;
</script>
<style scoped>
.c {
width: 80%;
padding: 20px;
margin: 0 auto;
border: 1px solid red;
}
.c > P > span {
color: coral;
}
</style>效果:

在使用params傳參時(shí) 參數(shù)詳情在請求體里 不會(huì)展示在地址欄中 這對數(shù)據(jù)安全來說是友好的
但弊端就是刷新頁面數(shù)據(jù)丟失
其實(shí)在實(shí)際項(xiàng)目里,數(shù)據(jù)多是請求數(shù)據(jù)賦值來的
所以接下來我們嘗試home.vue組件里請求數(shù)據(jù)后傳遞給list.vue組件展示數(shù)據(jù)
傳遞方組件
home.vue
<template>
<div class="c">
<p>params 傳參</p>
<el-button type="warning" @click="toList"> to list page</el-button>
</div>
</template>
<script lang='ts' setup>
import { toRefs,ref,reactive } from 'vue'
// 引入接口
import { tt } from '../request/api'
// 1 引入路由跳轉(zhuǎn)方法useRouter
import { useRouter } from 'vue-router'
// 2 拿到實(shí)例
const router = useRouter()
// 3 定義接口數(shù)據(jù)
interface props {
userId:number,
city:string,
address:string,
name:string,
zip:number,
region:string,
date:string
}
// 4 reactive定義數(shù)據(jù)
let list:props[] = reactive([])
// 5 params 傳參 必須搭配name使用 path會(huì)忽略params帶參
const toList = ()=>{
tt().then((res:any)=>{
if(res && res.data.code === 200){
list = res.data.data.list
router.push({
name:'List',
params:{
list:JSON.stringify(list)
}
})
}else{
alert(res.data.msg)
}
})
}
</script>
<style scoped>
.c{
width: 80%;
padding: 20px;
margin: 0 auto;
border:1px solid red;
}
.c>p>span{
color:coral;
}
</style>接收方組件
list.vue
<template>
<div class="c">
<p>params接參</p>
<!-- 4 展示數(shù)據(jù) -->
<div class="c" v-for="item in list" :key="item.userId">
<p>名稱:<span>{{ item.name }}</span></p>
<p>城市:<span>{{ item.city }}</span></p>
<p>地區(qū):<span>{{ item.region }}</span></p>
<p>地址:<span>{{ item.address }}</span></p>
<p>日期:<span>{{ item.date }}</span></p>
<p>編號:<span>{{ item.zip }}</span></p>
</div>
</div>
</template>
<script lang="ts" setup>
// 1 引入useRoute路由信息方法
import { useRoute } from "vue-router";
// 2 獲取實(shí)例
const route = useRoute();
// 3 聲明賦值 刷新頁面 參數(shù)丟失 這里報(bào)錯(cuò)
const list = JSON.parse(route.params.list as string);
</script>
<style scoped>
.c {
width: 80%;
padding: 20px;
margin: 0 auto;
border: 1px solid red;
}
.c > P > span {
color: coral;
}
</style>效果:

那我們在使用params傳參時(shí) 如何避免頁面刷新導(dǎo)致參數(shù)丟失問題呢?
那就是 params 的第二種傳參方式了:動(dòng)態(tài)路由傳參
params 傳參方式②
1 既然名叫動(dòng)態(tài)路由傳參 那首先第一步就是在router/index.ts里配置動(dòng)態(tài)路由
router/index.ts
import { createRouter,createWebHistory,RouteRecordRaw } from 'vue-router'
const routes:Array<RouteRecordRaw> = [
{
path:'/',
component:()=>import('../pages/home.vue')
},{
path:'/home',
name:'Home',//路由命名
component:()=>import('../pages/home.vue')
},{
path:'/list/:arr',//接收方路由配置
name:'List',//路由命名 為路由跳轉(zhuǎn)作準(zhǔn)備
component:()=>import('../pages/list.vue')
},{
//定義404頁面
path:'/404',
component:()=>import('../pages/notfound.vue')
},{
//匹配未定義路由 然后重定向至404頁面
path:'/:pathMath(.*)',
redirect:'/404'
}
]
const router = createRouter({
routes,
history:createWebHistory()
})
export default router2 傳遞方組件
home.vue
<template>
<div class="c">
<p>params 傳參</p>
<el-button type="warning" @click="toList"> to list page</el-button>
</div>
</template>
<script lang='ts' setup>
import { toRefs,ref,reactive } from 'vue'
// 引入接口
import { tt } from '../request/api'
// 1 引入路由跳轉(zhuǎn)方法useRouter
import { useRouter } from 'vue-router'
// 2 拿到實(shí)例
const router = useRouter()
// 3 定義接口數(shù)據(jù)
interface props {
userId:number,
city:string,
address:string,
name:string,
zip:number,
province:string,
date:string
}
// 4 ref定義基本數(shù)據(jù) 但未定義數(shù)據(jù)類型
let list:props[] = reactive([])
// 5 params 傳參 必須搭配name使用 path會(huì)忽略params帶參
const toList = ()=>{
tt().then((res:any)=>{
if(res && res.data.code === 200){
list = res.data.data.list
router.push({
name:'List',
params:{
//動(dòng)態(tài)路由配置/:arr 這里就是arr
arr:JSON.stringify(list)
}
})
}else{
alert(res.data.msg)
}
})
}
</script>
<style scoped>
.c{
width: 80%;
padding: 20px;
margin: 0 auto;
border:1px solid red;
}
.c>p>span{
color:coral;
}
</style>接收方組件
list.vue
<template>
<div class="c">
<p>params接參</p>
<!-- 4 展示數(shù)據(jù) -->
<div class="c" v-for="item in list" :key="item.userId">
<p>名稱:<span>{{ item.name }}</span></p>
<p>城市:<span>{{ item.city }}</span></p>
<p>地區(qū):<span>{{ item.region }}</span></p>
<p>地址:<span>{{ item.address }}</span></p>
<p>日期:<span>{{ item.date }}</span></p>
<p>編號:<span>{{ item.zip }}</span></p>
</div>
</div>
</template>
<script lang="ts" setup>
// 1 引入useRoute路由信息方法
import { useRoute } from "vue-router";
// 2 獲取實(shí)例
const route = useRoute();
// 3 聲明賦值 刷新頁面 參數(shù)不會(huì)丟失
const list = JSON.parse(route.params.arr as string);
</script>
<style scoped>
.c {
width: 80%;
padding: 20px;
margin: 0 auto;
border: 1px solid red;
}
.c > P > span {
color: coral;
}
</style>效果:

可! 這和query傳參有毛區(qū)別?參數(shù)都會(huì)在地址欄顯示
從效果上看是這樣的 沒有區(qū)別
只是query傳參有長度限制,而params無
params的聲明式路由跳轉(zhuǎn)傳參就不贅述了,會(huì)了編程式路由跳轉(zhuǎn)傳參,那聲明式就不在話下。
注意query和path或name都可搭配使用,而params只能和name搭配就行了
在嘗試寫vue3+ts項(xiàng)目時(shí),遇到的絕大多數(shù)問題都是數(shù)據(jù)類型定義相關(guān)的 也就是ts問題突出
都說any大法好,這也就失去了類型限定即ts的意義 這又和js毫無分別了
所以ts還是重點(diǎn)學(xué)習(xí)的方面
最后提醒一句:
如果你在vue3+ts項(xiàng)目里使用params傳參時(shí),盡管代碼核實(shí)幾遍都是對的,可還是報(bào)錯(cuò),
那可能不是你的問題,嘗試下載 vue-router@4.0.1 版本,然后重啟項(xiàng)目,你可能就驚奇的發(fā)現(xiàn)
參數(shù)就這么展示在自己眼前了
總結(jié)
到此這篇關(guān)于如何在vue3+ts項(xiàng)目中使用query和params傳參的文章就介紹到這了,更多相關(guān)vue3+ts用query和params傳參內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
VUE+axios+php實(shí)現(xiàn)圖片上傳
這篇文章主要為大家詳細(xì)介紹了VUE+axios+php實(shí)現(xiàn)圖片上傳,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
elementUI組件中el-date-picker限制時(shí)間范圍精確到小時(shí)的方法
現(xiàn)在需要做一個(gè)時(shí)間選擇器,可以根據(jù)小時(shí)(同時(shí)選天和小時(shí))和天?和月,節(jié)假日等類型控制日歷的選擇樣式,下面這篇文章主要給大家介紹了關(guān)于elementUI組件中el-date-picker限制時(shí)間范圍精確到小時(shí)的相關(guān)資料,需要的朋友可以參考下2023-04-04
vue 自定義指令自動(dòng)獲取文本框焦點(diǎn)的方法
今天小編就為大家分享一篇vue 自定義指令自動(dòng)獲取文本框焦點(diǎn)的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08
Element中table組件按照屬性執(zhí)行合并操作詳解
在我們?nèi)粘i_發(fā)中,表格業(yè)務(wù)基本是必不可少的,對于老手來說確實(shí)簡單,家常便飯罷了,但是對于新手小白如何最快上手搞定需求呢?本文從思路開始著手,幫你快速搞定表格2022-11-11
Vue異步請求導(dǎo)致頁面數(shù)據(jù)渲染錯(cuò)誤問題解決方法示例
這篇文章主要為大家介紹了Vue中異步請求導(dǎo)致頁面數(shù)據(jù)渲染錯(cuò)誤問題解決方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
vue項(xiàng)目如何監(jiān)聽localStorage或sessionStorage的變化
這篇文章主要介紹了vue 項(xiàng)目如何監(jiān)聽localStorage或sessionStorage的變化,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2021-01-01
Vue.js+Layer表格數(shù)據(jù)綁定與實(shí)現(xiàn)更新的實(shí)例
下面小編就為大家分享一篇Vue.js+Layer表格數(shù)據(jù)綁定與實(shí)現(xiàn)更新的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03

