全国免费咨询:

13245491521

VR图标白色 VR图标黑色
X

中高端软件定制开发服务商

与我们取得联系

13245491521     13245491521

2024-12-17_总结Vue3的13种传参通信方式,非常齐全

您的位置:首页 >> 新闻 >> 行业资讯

总结Vue3的13种传参通信方式,非常齐全 点击关注公众号,“技术干货”及时达! 前言:vue3出来很久了,也非常成熟了,平时项目只管用也没多想,直至今天想写一编关于vue3传参,然后我总结一下竟然总结出来13种方式那么多,13种我分别列了出来,由于vue3有两种setup写法,下面我将用「最简洁」的代码例子针对主流的script setup写法对每一种用法进行细说。如果有那里不对或者有补充欢迎大佬指导。 ?props父传子defineEmits子传父mitt兄弟组件传参$attrs (爷孙)refsv-model(双向)provide/inject(多层)路由传参vuex传参 (全局)pinia传参 (全局)浏览器缓存 (全局)window (全局)app.config.globalProperties (全局)?一、父传子?「思路」:父组件通过冒号:绑定变量,然后子组件用const props = defineProps({})进行接收参数。 ?「父组件代码:」 在第二行那里 :name="name" 把那么传给子组件 template child :name="name"/child/template script setupimport { ref } from 'vue'import child from './child.vue' const name = ref('天天鸭')/script「子组件代码:」 const props = defineProps({})接收后直接在标签使用 template div{{ props.name }}/div/template script setupimport { defineProps } from 'vue'const props = defineProps({ name: { type: String, default: '', },})/script二、子传父?思路:子组件用 const emits = defineEmits(['触发的方法']) 注册某个在父组件的事件,然后通过emits('触发的事件', 参数) 触发父组件事件并且带上参数。 ?「子组件代码:」 注册 addEvent 事件后, 用 emits('addEvent', name.value) 触发父组件的 addEvent事件 template div /div/template script setupimport { ref, defineEmits } from 'vue' const name = ref('天天鸭')const emits = defineEmits(['addEvent'])const handleSubmit = () = { emits('addEvent', name.value)}/script「父组件代码:」 触发addEvent事件后,在对应的方法里面直接能拿到传过来的参数 template child @addEvent="handle"/child/template script setupimport { ref } from 'vue'import child from './child.vue' const handle = value = { console.log(value); // '天天鸭'}/script三、兄弟组件传参(mitt)?以前vue2是用EventBus事件总线跨组件实现兄弟组件通信的。但vue3中没有,所以vue3目前主流使用mitt.js插件来进行替代实现兄弟通信。 ?1、npm包引入 npm install --save mitt2、在main.js文件进行全局挂载, $bus是自定义属性名import mitt from "mitt" const app = createApp(App) app.config.globalProperties.$bus = new mitt()3、传参出去的兄弟组件代码script setup import mitt from 'mitt' const emitter = mitt() emitter.emit('自定义的事件名称','参数')/script4、接收参数的兄弟组件代码script setup import mitt from 'mitt' const emitter = mitt() emitter.on('自定义的事件名称', '参数' )/script四、$attrs?注意: 以前在在vue2里面中除了$attrs,还有$listeners;但vue3直接把$listeners合并到$attrs里面了。 ??简要说明:$attrs主要作用是接收没在props里面定义,但父组件又传了过来的属性。看下面代码例子就好懂多了 ?「父组件代码:」 传两个属性过去,一个在子组件props中,一个不在 template child :name="天天鸭" data="PC9527"//template script setupimport child from './child.vue'/script「子组件代码:」 $attrs接收到props以外的内容,所以用useAttrs()打印出来没有name只有data template div {{ props.name }} // '天天鸭' /div/template script setupimport { defineProps, useAttrs } from 'vue'const props = defineProps({ name: { type: String }}) const myattrs = useAttrs()console.log(myattrs) // { "data": "PC9527" }/script五、refs传参?简单说明:父组件通过在子组件上定义 ref='ref名称',然后const ref名称 = ref(null),就能通过ref名称操控子组件的属性和方法(子组件用defineExpose对外暴露才能被操控),具体看下面例子。 ?「父组件代码:」 template child ref="myref"/child button @click="myClick"/button/template script setup import child from "./child.vue" import { ref } from "vue" const myref = ref(null) const myClick = () = { console.log(myref.value.name) // 直接获取到子组件的属性 myref.value.chileMethod() // 直接调用子组件的方法 }/script「子组件代码:」 用defineExpose对外暴露才能被操控 template div/div/template script setup import { defineExpose } from "vue" const chileMethod = () ={ console.log("我是方法") } const name = ref('天天鸭') defineExpose({ // 对外暴露 name, chileMethod })/script六、v-model?简单讲解: v-model其实语法糖,如下两行代码作用是一样, 上面是下面的简写。 ?chile v-model:title="title" / chile :title="title" @update:title="title = $event" /「父组件代码:」 直接使用v-model传参 template child v-model:name="name" v-model:num="num"/child/template script setup import child from "./child.vue" import { ref, reactive } from "vue" const name = ref("天天鸭") const num = ref("2222")/script「子组件代码:」 通过 defineEmits获取到然后用emit("update:修改的属性", 修改的内容)进行修改父组件的内容,,注意:update:是固定写法。 template button @click="myClick"/button/template script setup import { defineEmits } from "vue" const emit = defineEmits(["name","num"]) // 子组件触发使用 const myClick = () = { emit("update:name", "改个新名字") emit("update:num", "换个新号码") }/scriptv-model扩展:defineModel():?defineModel()宏的简单说明:父子组件的数据双向绑定,不用emit和props的繁重代码 版本要求:必须要3.4+ ??示例场景:父组件引入一个子组件弹窗,点击就父传子(props)弹出子组件弹窗,子组件里面有个按钮点击就子传父(emit)关闭 ?「父组件代码:」 用v-model在子组件身上绑定showDevice属性,该属性用于通知子组件是否打开弹窗。 template child v-if="showDevice" v-model="showDevice"/child/template script setup import child from "./child.vue" import { ref } from "vue" const showDevice = ref(false) // 控制子组件的显示和隐藏/script「子组件代码:」 如下的handleClickCancel方法,通过defineModel宏声明一个model,点击按钮能直接通知父组件修改属性。 template button @click="handleClickCancel"点击取消子组件弹窗/button/template script setup import { defineModel } from 'vue' const model = defineModel() // 写法一 // const model = defineModel({ type: Boolean }) // 写法二 也可以用声明类型的方法 const handleClickCancel = () = { model.value = false }/script上面例子通过defineModel宏,直接不需要props和emit就实现了父子通信效果,非常简洁好用。 七、provide/inject?简单讲解:provide和inject叫依赖注入,是vue官方提供的API,它们可以实现多层组件传递数据,无论层级有多深,都可以通过这API实现。 ?「假设这是太老爷组件:」 provide('名称', 传递的参数)向后代组件提供数据, 只要是后代都能接收 template div/div/template script setupimport { ref, provide } from 'vue'const name = ref('天天鸭')// 向后代组件提供数据, 只要是后代都能接收provide('name', name.value)/script「最深层的孙组件:」 无论层级多深,用 inject(接收什么参数) 进行接收即可 template div{{ name }}/div/template script setupimport { inject } from 'vue'// 接收顶层组件的通信const name = inject('name')/script八、路由传参?简单讲解: 路由跳转事上参数也是传参的一种,而且传参方式还不止一种呢,下面细说。 ?「1、query传参」 // 传递方const query = { id: 9527, name: '天天鸭' }router.push({ path: '/user', query }) // 接收方import { useRoute} from 'vue-router'const route = useRoute()console.log(route.query)「2、params传参」 ?注意:4.1.4 (2022-08-22) 删除了param这种方式 ?// 发送方router.push({ name: 'test', params: { name: '天天鸭' }}) // 接收方import { useRoute} from 'vue-router'const route = useRoute()console.log(route.params) // { name: '天天鸭' }「3、state传参」 // 发送方const state= { name: '天天鸭' }router.push({ path: '/user', state }) // 接收方直接使用console.log(history?.state?.name)九、vuex传参写过对应的文章,可以直接细看:对比vuex和pinia用法 十、pinia写过对应的文章,可以直接细看:对比vuex和pinia用法 十一、浏览器缓存?localStorage 和sessionStorage: 这算是用的不多,但也是必用的一种通信方式了,下面看看区别: sessionStorage(临时存储):为每一个数据源维持一个存储区域,在浏览器打开期间存在,包括页面重新加载 localStorage(长期存储):与 sessionStorage 一样,但是浏览器关闭后,数据依然会一直存在 ?下面直接上使用的语法。 // 存储数据localStorage.setItem('key', 'value');sessionStorage.setItem('key', 'value'); // 获取数据const valueFromLocalStorage = localStorage.getItem('key');const valueFromSessionStorage = sessionStorage.getItem('key'); // 删除数据localStorage.removeItem('key');sessionStorage.removeItem('key'); // 清空所有数据localStorage.clear();sessionStorage.clear();十二、通过window对象全局挂载全局对象或者属性?简单说明:直接用语法 window.name = '天天鸭' 定义然后全局通用即可。存放在内存刷新会清空。 ?「注意」:在 Vue 3 应用程序中,虽然可以直接将属性挂载到 window 对象上实现全局访问,但这并不是推荐的做法,因为直接修改全局对象可能会导致命名冲突、难以进行模块化管理以及不利于应用的封装与维护。 用法:直接定义,可以是属性也可以是对象 window.duname = '天天鸭'window.duObj = { test: '看看对象' }引用: console.log( window.duname); // 天天鸭 console.log( window.duObj); // {test: '看看对象'}十三、app.config.globalProperties?简单讲解:app.config.globalProperties 是Vue官方的一个 api,这是对 Vue 2 中 Vue.prototype 使用方式的一种替代,Vue.prototype 法在 Vue3 已经不存在了。与任何全局的东西一样,应该谨慎使用。 ?用法示例:在main.js文件挂载一个全局的 msg 属性 import { createApp } from 'vue' const app = createApp(App) app.config.globalProperties.msg = 'hello'在其它页面使用getCurrentInstance()获取 import { getCurrentInstance } from "vue"; const { proxy } = getCurrentInstance() // 使用proxy,类似于vue2的this console.log(proxy.msg); // hello总结:空闲想总结一下,纯人工肝了一天终于写好了,我尽量用最简洁易懂的方式写了,如果有什么写错了或者不够明细都欢迎大家指出。这也当笔记用了,以后忘记用法回来看一眼。创作不易,如果有幸能让你看到这里,希望给个点赞哦。 点击关注公众号,“技术干货”及时达! 阅读原文

上一篇:2021-11-29_Off-White创始人、LV男装创意总监Virgil Abloh逝世 下一篇:2019-12-30_清明节加班最多,近三成码农用两种及以上语言编程,这是15000名中国码农的日常

TAG标签:

20
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设网站改版域名注册主机空间手机网站建设网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。
项目经理在线

相关阅读 更多>>

猜您喜欢更多>>

我们已经准备好了,你呢?
2022我们与您携手共赢,为您的企业营销保驾护航!

不达标就退款

高性价比建站

免费网站代备案

1对1原创设计服务

7×24小时售后支持

 

全国免费咨询:

13245491521

业务咨询:13245491521 / 13245491521

节假值班:13245491521()

联系地址:

Copyright © 2019-2025      ICP备案:沪ICP备19027192号-6 法律顾问:律师XXX支持

在线
客服

技术在线服务时间:9:00-20:00

在网站开发,您对接的直接是技术员,而非客服传话!

电话
咨询

13245491521
7*24小时客服热线

13245491521
项目经理手机

微信
咨询

加微信获取报价