vue3.0和2.0的区别 知乎(在vue3+ts项目里使用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 引入路由跳转方法useRouter import { 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 } }) } </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,//路由命名 为路由跳转作准备 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是一个对象类型 所以我们定义的基本类型数据不能直接赋值 要给对象式写法 {}
像以下两种写法都是报错的
<script lang=ts setup> import { ref } from vue // 1 引入路由跳转方法useRouter import { useRouter } from vue-router // 2 拿到实例 const router = useRouter() // 3 ref定义基本数据 const name = ref(梨花白) // 4 query传参 const toList = ()=>{ router.push({ path:/list, query:name //报错 不能将类型“Ref<string> ”分配给类型“LocationQueryRaw ” 。 //类型“Ref<string> ”中缺少类型“string ”的索引签名 }) } </script> <script lang=ts setup> import { ref } from vue // 1 引入路由跳转方法useRouter import { 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 ” }) } </script>接收方组件
list.vue
<template> <div class=c> <p>query接参</p> <!-- 4 展示数据 --> <p>name: <span>{{ name }}</span></p> </div> </template> <script lang=ts setup> // 1 引入useRoute路由信息方法 import { useRoute } from vue-router // 2 获取实例 const route = useRoute() // 3 解构赋值 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>效果:
动态效果:
以上 我们可以得知 当使用query传参时 ,参数的详细内容都会在地址栏完整的展示出来 。
这对于数据安全来说是致命的
当然也有它自有的优势:刷新不会丢失数据
下面看看使用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 引入路由跳转方法useRouter import { useRouter } from vue-router // 2 拿到实例 const router = useRouter() // 3 ref定义基本数据 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>效果:
动态效果:
两者效果别无二致 也有同学说我在传入引用类型数据时老是报错 怎搞嘞
好的 下面开始传递引用类型数据
传递方组件
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 引入路由跳转方法useRouter import { 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 ?传参 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 展示数据 --> <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 获取实例 const route = useRoute(); // 3 使用JSON.parse()方法把传过来的字符串参数转回对象 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>效果:
动态效果:
所以是
在使用?传参传入引用类型数据时 传递时要使用JSON.stringify()方法转成字符串类型
在接收时 要使用JSON.parse()方法再转回最初的类型
易错点如下:
query 传参方式③
其实也就是声明式路由跳转时带参
传递方组件
home.vue
<template> <div class=c> <p>query传参</p> <router-link //to的对象式写法 与编程式路由跳转传参的对象式写法相对应 :to="{ path:/list, //或 name:List query:{ arr:JSON.stringify(arr) } }"> <el-button type="success"> to list</el-button> </router-link> //<router-link //to的字符串写法 与编程式路由跳转的?传参写法相对应 // :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 引入路由跳转方法useRouter import { 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[]) </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 引入路由跳转方法useRouter import { 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 } }) } </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 展示数据 --> <p>str: <span>{{ str?str:刷新我就不见啦! }}</span></p> </div> </template> <script lang="ts" setup> // 1 引入useRoute路由信息方法 import { useRoute } from "vue-router"; // 2 获取实例 const route = useRoute(); // 3 解构赋值 刷新页面 参数丢失 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传参时 参数详情在请求体里 不会展示在地址栏中 这对数据安全来说是友好的
但弊端就是刷新页面数据丢失
其实在实际项目里 ,数据多是请求数据赋值来的
所以接下来我们尝试home.vue组件里请求数据后传递给list.vue组件展示数据
传递方组件
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 引入路由跳转方法useRouter import { 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.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 展示数据 --> <div class="c" v-for="item in list" :key="item.userId"> <p>名称:<span>{{ item.name }}</span></p> <p>城市:<span>{{ item.city }}</span></p> <p>地区:<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 获取实例 const route = useRoute(); // 3 声明赋值 刷新页面 参数丢失 这里报错 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传参时 如何避免页面刷新导致参数丢失问题呢?
那就是 params 的第二种传参方式了:动态路由传参
params 传参方式②
1 既然名叫动态路由传参 那首先第一步就是在router/index.ts里配置动态路由
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,//路由命名 为路由跳转作准备 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 引入路由跳转方法useRouter import { 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.list router.push({ name:List, params:{ //动态路由配置/: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 展示数据 --> <div class="c" v-for="item in list" :key="item.userId"> <p>名称:<span>{{ item.name }}</span></p> <p>城市:<span>{{ item.city }}</span></p> <p>地区:<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 获取实例 const route = useRoute(); // 3 声明赋值 刷新页面 参数不会丢失 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传参有毛区别?参数都会在地址栏显示
从效果上看是这样的 没有区别
只是query传参有长度限制,而params无
params的声明式路由跳转传参就不赘述了 ,会了编程式路由跳转传参 ,那声明式就不在话下 。
注意query和path或name都可搭配使用,而params只能和name搭配就行了
在尝试写vue3+ts项目时 ,遇到的绝大多数问题都是数据类型定义相关的 也就是ts问题突出
都说any大法好 ,这也就失去了类型限定即ts的意义 这又和js毫无分别了
所以ts还是重点学习的方面
最后提醒一句:
如果你在vue3+ts项目里使用params传参时 ,尽管代码核实几遍都是对的 ,可还是报错 ,
那可能不是你的问题 ,尝试下载 vue-router@4.0.1 版本 ,然后重启项目 ,你可能就惊奇的发现
参数就这么展示在自己眼前了
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!