Vue3组件通信全解析:利用props、emit、provide/inject跨层级传递数据,expose与ref实现父子组件方法调用
文章目录
- 一、父组件数据传递N个层级的子组件
- vue3 provide 与 inject
- A组件名称 app.vue
- B组件名称 provideB.vue
- C组件名称 provideCSetup.vue
- 二、使用v-model指令实现父子组件的双向绑定
- 父组件名称 app.vue
- 子组件名称 v-modelSetup.vue
- 三、父组件props向子组件传值
- 子组件 propsSetup.vue
- 父组件 app.vue
- 四、子组件emit向父组件传值
- vue3 events 事件
- 子组件eventsSetup.vue 定义事件
- 父组件app.vue接收子组件eventsSetup.vue的done事件
- 五、通过expose和ref来实现父组件调用子组件的方法
- 父组件 app.vue
- 子组件名称 child.vue
一、父组件数据传递N个层级的子组件
vue3 provide 与 inject
我们通过props属性可以把数据传给组件,而通过provide与inject我们可以把数据传递给N个层级的子组件,比如A组件用了B组件,B组件用了C组件,它可以把组件直接从A传给C组件,vue2使用computed来实现响应式,而vue3中 provide 使用ref或reactive定义的变量即可实现响应式。
(图片来源网络,侵删)A组件传入值,传入了userInfo对象,不用管传给谁了谁,谁都可以去接收key为provideCount的数据
A组件名称 app.vue
A组件显示:{{state.userInfo.count}} //导入 provide import { reactive,provide } from "vue"; import bcomp from "./provideB.vue"; //定义需要传递的对象 const state=reactive({userInfo:{count:1}}) //定了 provide 的 key 和 要传递的值 provide("provideCount",state.userInfo);
B组件调用C组件,但是我啥也没干
B组件名称 provideB.vue
import { reactive } from "vue"; import ccomp from "./provideCSetup.vue";
C组件获取A组件传入的值,我修改了userInfo的值,A组件也会跟着变哦。
C组件名称 provideCSetup.vue
C组件显示: {{ userInfo.count }} import { inject, reactive } from "vue"; //获取 provide 传入的值 const userInfo = inject('provideCount'); //测试响应式 setInterval(function(){userInfo.count=userInfo.count+1},1000)
二、使用v-model指令实现父子组件的双向绑定
v-model是vue3的一个内置指令,可以实现父组件变量(不能是常量)与子组件属性的双向绑定,我们在很多知名的开源库可以看到这个命令,比如我们要实现一个弹窗组件需要父组件和子组件都可以操作这个变量来实现隐藏显示统一步调。
父组件名称 app.vue
在父组件中,使用v-model指令将子组件的某个prop绑定到父组件的某个变量上
点击弹窗 import { reactive } from "vue"; import demo from "./v-modelSetup.vue"; //定义要使用v-model的变量show和message const state = reactive({ show: false, message: "https://www.itxst.com", }); //按钮事件,我们改变show的值 const showDlg = () => { state.show = true; };
v-modelSetup.vue子组件实现修改v-model的值(属性值)
(图片来源网络,侵删)子组件名称 v-modelSetup.vue
在子组件中,将子组件的某个prop绑定到子组件的某个变量上,并在该变量上使用计算属性或观察者监听该prop的变化
{{ message }} 确定 import { ref, reactive } from "vue"; // 定义了 show 和 message 属性 const props = defineProps({ show: { type: Boolean, default: false, }, message: { type: String, default: "", }, }); //修改属性的值,定义emits可修改 show 和 message 属性 const emits = defineEmits(["update:show", "update:message"]); //确定按钮的事件 const ok = () => { //关闭弹窗 emits("update:show", false); }; /* 样式省略,请在试一试中查看 */
三、父组件props向子组件传值
vue3 通过 props 来定义属性,我们可以通过属性将值传给自定义组件,比如颜色、高度宽度等等,定义属性时我们也可以定义类型和默认值,本文重点描述了如何定义属性和修改属性的值。
子组件 propsSetup.vue
{{msg}} import { ref, reactive } from "vue"; /* * 定义组件的属性 * type 表示属性类型 * default 表示默认值 */ const props = defineProps({ msg: { type: String, default: "www.itxst.com", }, color: { type: String, default: "#000", }, height:{ type:Number, default:120, } }); /* 也可以通过数组方式定义属性,缺点是不能定义类型和默认值 const props = defineProps(['msg','color']); */
使用该自定义组件
父组件 app.vue
import { ref, reactive } from "vue"; // 导入组件,因为是setup语法糖,所以无需手动注册组件 // demo为当前页的组件名称你可以随便取名, "./components/propsSetup.vue" 是组件的路径 import demo from "./components/propsSetup.vue";
四、子组件emit向父组件传值
vue3 events 事件
事件是组件开发中必不可少的部分,事件就是当你完成了某个任务后你把这个事情告诉别人的动作,比如你在组件中保存成功了数据等等,本文将介绍任何在vue3中定义事件以及调用者任何接收这个事件。
子组件eventsSetup.vue 定义事件
import { ref } from "vue"; const msg=ref('www.itxst.com'); //定义一个点击完成事件 done 和 sent 两个事件 const emits = defineEmits(["done","sent"]); //TS模式 定义emits /* const emits = defineEmits(); */ const onDone=()=>{ //触发done事件,请把用户输入的值msg传出去 emits("done", msg.value); //也可以不传参数 //emits("sent"); } .itxst{ display: inline-block; padding: 6px; }
父组件app.vue接收子组件eventsSetup.vue的done事件
{{text}} import { ref } from "vue"; import demo from './eventsSetup.vue' const text=ref(''); //接收组件里面的done事件 const onDone=(msg)=>{ text.value='你输入了:'+msg; }
五、通过expose和ref来实现父组件调用子组件的方法
vue3父组件调用子组件的方法是通过expose和ref来实现的,我们可以通过expose来控制父组件可以访问子组件那些的方法和对象,我们将通过setup api(组合式 api)和option api(选项式 api)来演示父组件如何调用子组件的方法。
父组件 app.vue
点击试一试 import { reactive, ref } from "vue"; import child from "./child.vue"; //定义子组件实例,名称要和上面的ref相同 const childComp = ref(null); //访问demo组件的方法或对象 const onTry = () => { //获取到子组件的 title 数据 let msg = childComp.value.state.title; //调用子组件的 play方法 childComp.value.play(); };
子组件名称 child.vue
{{ state.title }} import { ref, reactive } from "vue"; //定义一个变量 const state = reactive({ title: "www.itxst.com", }); //定义一个方法 const play = () => { state.title = "你调用了子组件的方法"; }; //暴露state和play方法 defineExpose({ state, play, });
(图片来源网络,侵删)
还没有评论,来说两句吧...