1. 父子组件通信
1.1 props/$emit
这种方式是父子组件通信最常用的方式。子组件通过 props 属性来接受父组件的数据,父组件在子组件上注册监听事件,子组件通过 emit 触发自定义事件来向父组件发送数据。
vue2写法
父传子
// Parent.vue <template> <child :msg="msg"></child> </template>
// Parent.vue <template> <child :msg="msg"></child> </template>
子传父
// Parent.vue <template> <child @sendMsg="getChildMsg"></child> </template> export default { methods:{ getChildMsg(msg){ console.log(msg) //身体健康 } } }
// Child.vue export default { data(){ return { msg: "身体健康" } }, methods: { handleClick(){ this.$emit("sendMsg",this.msg)//emit触发自定义事件 } }, }
vue3写法
vue3中子组件通过defineProps获取父组件传递的数据,并且不需要引入,可以直接使用
父传子
//Parent.vue <template> <Child info="身体健康" :money="money"></Child> </template> <script setup lang="ts"> import Child from "./Child.vue"; import { ref } from "vue"; let money = ref(10000); </script>
<template> <Child @xxx="handler"></Child> </template> <script setup lang="ts"> import Child from "./Child.vue"; const handler = (param1: any, param2: any) => { console.log(param1, param2); //好好学习,天天向上 }; </script>
子传父
利用defineEmits方法返回函数来触发自定义事件,同样不需要引入,可以直接使用
<template> <Child @xxx="handler"></Child> </template> <script setup lang="ts"> import Child from "./Child.vue"; const handler = (param1: any, param2: any) => { console.log(param1, param2); //好好学习,天天向上 }; </script>
<template> <button @click="handler">子传父</button> </template> <script setup lang="ts"> //利用defineEmits方法返回函数触发自定义事件 let emit = defineEmits(["xxx"]); const handler = () => { emit("xxx", "好好学习", "天天向上"); }; </script>
1.2 ref/$parent
通过 ref 和 $parent ,也可以实现父子组件通信。
ref 如果在普通的DOM元素上,引用指向的就是该DOM元素;如果在子组件上,引用的指向就是子组件实例,然后父组件就可以通过可以通过实例来访问组件的数据和方法
使用 $parent,可以让子组件访问父组件的实例,访问的是上一级父组件的属性和方法
vue2写法
子传父:通过ref属性
//Parent.vue <template> <child ref="child"></child> </template> <script> import child from './child.vue' export default { components: { child }, mounted () { console.log(this.$refs.child.name); // 小心 this.$refs.child.sayHello(); // hello } } </script>
// Child.vue export default { data () { return { name: '小心' } }, methods: { sayHello () { console.log('hello') } } }
父传子:使用$parent
// Child.vue export default{ mounted(){ this.$parent.sayHello() // 调用父组件的方法 this.$parent.name // 获取父组件中的属性 } }
vue3写法
注意点:vue3中使用 script setup 的组件是默认关闭的,外部不能访问,如果想获取要获取某个组件的数据和方法,需要在该组件中通过defineExpose来指定需要对外暴露的属性或方法。
子传父:通过ref父组件获取子组件的属性或者调用子组件方法
// Parent.vue <template> <child ref="son"></child> <button @click="handlerClick">按钮</button> </template> <script setup> import child from "./child.vue" import { ref } from "vue" const son = ref(null) const handlerClick = () => { console.log(son.value.childName) // 1000000000000 } </script>
// Child.vue <script setup> // defineExpose指定需要对外暴露的属性或方法,不需要引入 defineExpose({ money: ”1000000000000“ }) </script>
父传子:通过$parent在子组件中获取父组件的数据和方法
// Parent.vue <template> <Child></Child> </template> <script setup lang="ts"> import Child from "./Child.vue"; import { ref } from "vue"; let money = ref(1000000000000); // defineExpose指定需要对外暴露的属性或方法,不需要引入 defineExpose({ money }); </script>
// Child.vue <template> <div class="dau"> <button @click="handler($parent)">点击获取父组件实例</button> </div> </template> <script setup lang="ts"> const handler = ($parent) => { console.log($parent.money); //1000000000000 }; </script>