一 query 传参 (类似get请求)
query 传参方式①
传递方组件
home.vue
query传参
to listimport { ref } from 'vue'// 1 引入路由跳转方法useRouterimport { useRouter } from 'vue-router'// 2 拿到实例const router = useRouter()// 3 ref定义基本类型数据const name = ref('梨花白')// 4 query传参const toList = ()=>{router.push({//这种对象式传参写法 query除开和path搭配外还可以和name一起使用path:'/list',//或者这样 path和name任选其一//name:'List',query:{name:name.value}})}.c{width: 80%;padding: 20px;margin: 0 auto;border:1px solid red;}.c>p>span{color:coral;}
看下 router/index.ts 文件
import { createRouter,createWebHistory,RouteRecordRaw } from 'vue-router'const routes:Array = [{path:'/',component:()=>import('../pages/home.vue')},{path:'/home',name:'Home',//路由命名component:()=>import('../pages/home.vue')},{path:'/list',name:'List',//路由命名 为路由跳转作准备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
有两个注意点
① ref定义响应式基本类型数据后,修改和赋值要带上 .value
② query是一个对象类型 所以我们定义的基本类型数据不能直接赋值 要给对象式写法 {}
像以下两种写法都是报错的
import { ref } from 'vue'// 1 引入路由跳转方法useRouterimport { useRouter } from 'vue-router'// 2 拿到实例const router = useRouter()// 3 ref定义基本数据const name = ref('梨花白')// 4 query传参const toList = ()=>{router.push({path:'/list',query:name //报错 不能将类型“Ref”分配给类型“LocationQueryRaw”。 //类型“Ref”中缺少类型“string”的索引签名})}
import { ref } from 'vue'// 1 引入路由跳转方法useRouterimport { useRouter } from 'vue-router'// 2 拿到实例const router = useRouter()// 3 ref定义基本数据const name = ref('梨花白')// 4 query传参const toList = ()=>{router.push({path:'/list',query:name.value //报错 不能将类型“string”分配给类型“LocationQueryRaw” })}
接收方组件
list.vue
query接参
name: {{ name }}
// 1 引入useRoute路由信息方法import { useRoute } from 'vue-router'// 2 获取实例const route = useRoute()// 3 解构赋值const { query:{name} } = route.c{width: 80%;padding: 20px;margin: 0 auto;border:1px solid red;}.c>P>span{color:coral;}
效果:
动态效果:
以上 我们可以得知 当使用query传参时,参数的详细内容都会在地址栏完整的展示出来。
这对于数据安全来说是致命的
当然也有它自有的优势:刷新不会丢失数据
下面看看使用query传参的另一种形式:?传参
query 传参方式②
传递方组件
home.vue
query传参
to listimport { toRefs,ref,reactive } from 'vue'// 1 引入路由跳转方法useRouterimport { useRouter } from 'vue-router'// 2 拿到实例const router = useRouter()// 3 ref定义基本数据const name = ref('桃花夭')// 4 query " /> 动态效果:
两者效果别无二致 也有同学说我在传入引用类型数据时老是报错 怎搞嘞
好的 下面开始传递引用类型数据
传递方组件
home.vue
query传参
to listimport { ref,reactive } from 'vue'// 1 引入路由跳转方法useRouterimport { useRouter } from 'vue-router'// 2 拿到实例const router = useRouter()// 3 定义数据接口类型interface props {id:number,content:string}// 4 reactive定义引用类型数据const arr:props[] = reactive([{id:1,content:'关山难越,谁悲失路之人?'},{id:2,content:'萍水相逢,尽是他乡之客!'}])// 4 或这样// const arr = reactive([// {// id:1,// content:'关山难越,谁悲失路之人?'// },{// id:2,// content:'萍水相逢,尽是他乡之客!'// }// ] as props[])// 5 query " />query接参
{{ item.content }}
// 1 引入useRoute方法import { useRoute } from "vue-router";// 2 获取实例const route = useRoute();// 3 使用JSON.parse()方法把传过来的字符串参数转回对象const arr = JSON.parse(route.query.arr as string);.c {width: 80%;padding: 20px;margin: 0 auto;border: 1px solid red;}.c > P > span {color: coral;}
效果:
动态效果:
所以是
在使用?传参传入引用类型数据时 传递时要使用JSON.stringify()方法转成字符串类型
在接收时 要使用JSON.parse()方法再转回最初的类型
易错点如下:
query 传参方式③
其实也就是声明式路由跳转时带参
传递方组件
home.vue
query传参
to list//// to list//import { toRefs,ref,reactive } from 'vue'// 1 引入路由跳转方法useRouterimport { useRouter } from 'vue-router'// 2 拿到实例const router = useRouter()// 3 定义数据接口类型interface props {id:number,content:string}// 4 ref定义基本数据 但未定义数据类型const arr:props[] = reactive([{id:1,content:'关山难越,谁悲失路之人?'},{id:2,content:'萍水相逢,尽是他乡之客!'}])// 4 或这样// const arr = reactive([// {// id:1,// content:'关山难越,谁悲失路之人?'// },{// id:2,// content:'萍水相逢,尽是他乡之客!'// }// ] as props[]).c{width: 80%;padding: 20px;margin: 0 auto;border:1px solid red;}.c>p>span{color:coral;}
效果:
二 params 传参 (类似post请求)
params 传参 方式①
传递方组件
home.vue
params 传参
to list page import { toRefs,ref,reactive } from 'vue'// 1 引入路由跳转方法useRouterimport { useRouter } from 'vue-router'// 2 拿到实例const router = useRouter()// 3 ref定义基本类型数据 const str = ref('月出于东山之上,徘徊于斗牛之间。')// 4 params 传参 只能搭配name使用 path会忽略params带参const toList = ()=>{router.push({name:'List',params:{str:str.value}})}.c{width: 80%;padding: 20px;margin: 0 auto;border:1px solid red;}.c>p>span{color:coral;}
接收方组件
list.vue
params接参
str: {{ str" />// 1 引入useRoute路由信息方法import { useRoute } from "vue-router";// 2 获取实例const route = useRoute();// 3 解构赋值 刷新页面 参数丢失 const { params:{str} } = route;.c {width: 80%;padding: 20px;margin: 0 auto;border: 1px solid red;}.c > P > span {color: coral;}
效果:
在使用params传参时 参数详情在请求体里 不会展示在地址栏中 这对数据安全来说是友好的
但弊端就是刷新页面数据丢失
其实在实际项目里,数据多是请求数据赋值来的
所以接下来我们尝试home.vue组件里请求数据后传递给list.vue组件展示数据
传递方组件
home.vue
params 传参
to list page import { toRefs,ref,reactive } from 'vue'// 引入接口import { tt } from '../request/api'// 1 引入路由跳转方法useRouterimport { useRouter } from 'vue-router'// 2 拿到实例const router = useRouter()// 3 定义接口数据interface props {userId:number,city:string,address:string,name:string,zip:number,region:string,date:string}// 4 reactive定义数据let list:props[] = reactive([])// 5 params 传参 必须搭配name使用 path会忽略params带参const toList = ()=>{tt().then((res:any)=>{if(res && res.data.code === 200){list = res.data.data.listrouter.push({name:'List',params:{list:JSON.stringify(list)}})}else{alert(res.data.msg)}})}.c{width: 80%;padding: 20px;margin: 0 auto;border:1px solid red;}.c>p>span{color:coral;}
接收方组件
list.vue
params接参
名称:{{ item.name }}
城市:{{ item.city }}
地区:{{ item.region }}
地址:{{ item.address }}
日期:{{ item.date }}
编号:{{ item.zip }}
// 1 引入useRoute路由信息方法import { useRoute } from "vue-router";// 2 获取实例const route = useRoute();// 3 声明赋值 刷新页面 参数丢失 这里报错constlist= JSON.parse(route.params.list as string);.c {width: 80%;padding: 20px;margin: 0 auto;border: 1px solid red;}.c > P > span {color: coral;}
效果:
那我们在使用params传参时 如何避免页面刷新导致参数丢失问题呢?
那就是 params 的第二种传参方式了:动态路由传参
params 传参方式②
1 既然名叫动态路由传参 那首先第一步就是在router/index.ts里配置动态路由
router/index.ts
import { createRouter,createWebHistory,RouteRecordRaw } from 'vue-router'const routes:Array = [{path:'/',component:()=>import('../pages/home.vue')},{path:'/home',name:'Home',//路由命名component:()=>import('../pages/home.vue')},{path:'/list/:arr',//接收方路由配置name:'List',//路由命名 为路由跳转作准备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
2 传递方组件
home.vue
params 传参
to list page import { toRefs,ref,reactive } from 'vue'// 引入接口import { tt } from '../request/api'// 1 引入路由跳转方法useRouterimport { useRouter } from 'vue-router'// 2 拿到实例const router = useRouter()// 3 定义接口数据interface props {userId:number,city:string,address:string,name:string,zip:number,province:string,date:string}// 4 ref定义基本数据 但未定义数据类型let list:props[] = reactive([])// 5 params 传参 必须搭配name使用 path会忽略params带参const toList = ()=>{tt().then((res:any)=>{if(res && res.data.code === 200){list = res.data.data.listrouter.push({name:'List',params:{//动态路由配置/:arr 这里就是arrarr:JSON.stringify(list)}})}else{alert(res.data.msg)}})}.c{width: 80%;padding: 20px;margin: 0 auto;border:1px solid red;}.c>p>span{color:coral;}
接收方组件
list.vue
params接参
名称:{{ item.name }}
城市:{{ item.city }}
地区:{{ item.region }}
地址:{{ item.address }}
日期:{{ item.date }}
编号:{{ item.zip }}
// 1 引入useRoute路由信息方法import { useRoute } from "vue-router";// 2 获取实例const route = useRoute();// 3 声明赋值 刷新页面 参数不会丢失constlist= JSON.parse(route.params.arr as string);.c {width: 80%;padding: 20px;margin: 0 auto;border: 1px solid red;}.c > P > span {color: coral;}
效果:
可! 这和query传参有毛区别?参数都会在地址栏显示
从效果上看是这样的 没有区别
只是query传参有长度限制,而params无
params的声明式路由跳转传参就不赘述了,会了编程式路由跳转传参,那声明式就不在话下。
注意query和path或name都可搭配使用,而params只能和name搭配就行了
在尝试写vue3+ts项目时,遇到的绝大多数问题都是数据类型定义相关的 也就是ts问题突出
都说any大法好,这也就失去了类型限定即ts的意义 这又和js毫无分别了
所以ts还是重点学习的方面
最后提醒一句:
如果你在vue3+ts项目里使用params传参时,尽管代码核实几遍都是对的,可还是报错,
那可能不是你的问题,尝试下载 vue-router@4.0.1 版本,然后重启项目,你可能就惊奇的发现
参数就这么展示在自己眼前了