The way of communication between vue3 components (setup syntax sugar writing)
1. Props method
This method is used for parent-to-child transmission. The parent component declares the data to be transmitted in the form of data binding, and the child component creates a props object through the defineProps() method to get the data from the parent component.
// 父组件
<template>
<div>
<son :msg="state.msg" />
</div>
</template>
<script setup lang="ts">
import son from "./son.vue";
import { reactive } from "vue";
const state = reactive({
msg: "父组件的值"
});
</script>
// 子组件
<template>
<div>
{
{ msg }}
</div>
</template>
<script setup lang="ts">
const props = defineProps({
msg: {
type: String,
default: ""
}
});
</script>
2. Emit mode
emit
The method is also the most common component communication method in Vue, which is used to pass from child to parent.
// 父组件
<template>
<div>
<son @myClick="handleClick" />
</div>
</template>
<script setup lang="ts">
import son from "./son.vue";
const handleClick = val => {
console.log(val);
};
</script>
// 子组件
<template>
<div>
<button @click="handleClick">点击</button>
</div>
</template>
<script setup lang="ts">
const emit = defineEmits(["myClick"]);
const handleClick = () => {
emit("myClick", "我是子组件的值");
};
</script>
3、defineExpose
Use defineExpose+ref to get the methods and variables in the component
// 父组件
<template>
<div>
<son ref="sonRef" />
<button @click="handleClick">点击</button>
</div>
</template>
<script setup lang="ts">
import son from "./son.vue";
import { ref } from "vue";
const sonRef = ref(null);
const handleClick = val => {
console.log(sonRef.value.msg);
};
</script>
// 子组件
<template>
<div>
son
</div>
</template>
<script setup lang="ts">
defineExpose({
msg: "我是子组件"
});
</script>
4. provide/inject
Provide/inject is a pair of APIs provided in Vue. No matter how deep the hierarchy is, the API can realize data transfer from parent components to descendant components.
// 父组件
<template>
<div>
<son />
</div>
</template>
<script setup lang="ts">
import son from "./son.vue";
import { provide } from "vue";
provide("msg", "我是父组件");
</script>
// 子组件
<template>
<div>
{
{ data }}
</div>
</template>
<script setup lang="ts">
import { inject } from "vue";
const data = inject("msg");
</script>
5、attrs
attrs can accept attributes other than props, style, and class.
// 父组件
<template>
<div>
<son :msg="state.msg" :hello="state.hello" />
</div>
</template>
<script setup lang="ts">
import son from "./son.vue";
import { reactive } from "vue";
const state = reactive({
msg: "我是父组件",
hello: "hello"
});
</script>
// 子组件
<template>
<div>
son
</div>
</template>
<script setup lang="ts">
import { useAttrs } from "vue";
const attrs = useAttrs();
console.log(attrs.msg); // 我是父组件
</script>
6. v-model method
v-model cannot be strictly a data transmission method, but actually only reduces the amount of code.
// 父组件
<template>
<div>
<son v-model:msg="state.msg" />
{
{ state.msg }}
</div>
</template>
<script setup lang="ts">
import son from "./son.vue";
import { reactive } from "vue";
const state = reactive({
msg: "我是父组件"
});
</script>
The subcomponent needs to emit an event called update:xxx, and then pass the responsive data to be updated to the second parameter of the emit method.
// 子组件
<template>
<div>
son
<button @click="handleClick">点击</button>
</div>
</template>
<script setup lang="ts">
const props = defineProps({
msg: {
type: String,
default: ""
}
});
console.log(props.msg);
// 子组件需要emit一个叫update:xxx的事件,再把需要更新的响应式数据传给emit方法的第二个参数即可
const emit = defineEmits(["msg"]);
const handleClick = () => {
emit("update:msg", "我是子组件");
};
</script>
7. Vuex / Pinia
Vuex and Pinia are state management tools in Vue 3. Using these two tools can easily realize component communication. For specific usage methods, please refer to the official documentation.