vue3的常见组件通信方式(使用setup语法糖以及ts)

发布时间:2024年01月08日

本文中使用到的组合式Api写法方式,可以参考vue3文档:ts与组合式Api

1.props(父传子):

?子组件接收到的值仅仅只是可读的,不可以修改

? ? ? ?用法步骤为:

1.父组件中准备一个a,值为1,标签内把a这个值传给子组件

2.子组件通过defineProps方法接收(setup语法糖写法)

? ? ? ? 相关代码如下:

? ? ? ? 父组件:

<template>
    <div>
        <h1>向子组件传递a的值</h1>
        <son :A="a"/>
    </div>
</template>

<script setup lang="ts">
import{ref} from "vue";
import Son from "@/components/son.vue";
const a=ref(10);
</script>

<style scoped>

</style>

? ? ? ?子组件:

<template>
    <div>
        a的值是:{{ value }}
    </div>
</template>

<script setup lang="ts">
import {ref} from "vue";

const props = defineProps<{
    A: number
}>()

const value = ref<number>(props.A)

</script>

<style scoped>

</style>

2.emits(子传父):

? 本质是让子组件区触发父组件的函数

?父组件值能接收过来并使用或者修改,但无法改变子组件中该属性的值

? ? ? ? 用法步骤为:

? ? ? ? 1.在父组件中定义函数,该函数用于接收子组件通过emits传过来的值以及修改父组件页面中的值

? ? ? ? 2.在子组件标签内部把该函数传递给子组件

? ? ? ? 3.子组件通过emits方式接收

? ? ? ? 4.子组件通过某种方式触发该emits

代码如下:

父组件:

<template>
    <div>
        <div>a:{{a}}</div>
        <son @changeA="triggerEvent"/>
    </div>
</template>

<script setup lang="ts">
import{ref} from "vue";
import Son from "@/components/son.vue";
const a=ref(0);
//这里的X是子组件通过emit传递过来的
const triggerEvent=(X:number)=>{
    a.value=X
}
</script>

<style scoped>

</style>

子组件:

<template>
    <div>
        <button @click="emits('changeA',20)">修改父组件A的值</button>
    </div>
</template>

<script setup lang="ts">
const emits=defineEmits<{
    (e:'changeA',value:number):void
}>()
</script>

<style scoped>

</style>

3.v-model方式:(父子互相通信)

????????父子组件都可以修改传递的值

? ? ? ? 该方式本质其实就是emits的语法糖形式,用法步骤为

1.父组件在子组件的标签内传递信息(需要使用v-model)

2.子组件通过defineProps方式与defineEmits接收(setup语法糖写法)

(第二步需要注意,对于defineEmits的方法名称有要求,不可以随便起名,接下来的代码会展示到)? ??

? ? ? ? 父组件:

? ? ? ? ? ? ? ?在模板中定义了a的值,并且通过v-model传递给了子组件 v-model:A=“a”,这里的大写A是给a的命名(在子组件中使用)

<template>
    <div>
     a的值是:{{a}}
        <button @click="a++">父组件+1</button>
        <son  v-model:A="a" />
    </div>
</template>

<script setup lang="ts">
import{ref} from "vue";
import Son from "@/components/son.vue";
const a=ref(0);
</script>

? ? ? ? 子组件:

? ? ? ? 这里用props与emits分别接收,注意,这里的emits的事件名称值要写为 “update:x”,这里的x是可以更改的。(setup语法糖写法,可以参考vue3文档 ts与组合式Api

<template>
    <div>
        <button @click="add">子组件+1</button>
    </div>

</template>

<script setup lang="ts">

import {watchEffect} from "vue";

const props = defineProps<{
    A:number
}>()
const emits=defineEmits<{
    (e:'update:A',value:number):void
}>()
watchEffect(()=>{
    console.log(props.A)
})
const add=()=>{
    emits('update:A',props.A+1)
}
</script>

这样一来无论点击父组件或者是子组件的按钮,a的值都会+1,并且二者共享父组件a的值。(父子组件都可以修改A的值)

4.provide与inject(父传孙)

? ? ? ? 父孙组件共享该数据,二者都可以对其进行修改

无论是在孙组件还是父组件中让a值+1,双方共享的a的值都会+1(与v-model通信方式类似)

?用法步骤:

1.在父组件中准备一个值a

2.父组件通过provide传递该值给孙组件

3.孙组件通过inject接收

?相关代码:

父组件:

<template>
    <div>
        <h1>父组件</h1>
        父组件的a值:{{a}}
        <button @click="add">a值+1</button>
        <hr>
        <son/>
    </div>
</template>

<script setup lang="ts">
import{ref,provide} from "vue";
import Son from "@/components/son.vue";
const a=ref<number>(0);
provide('A',a);
const add=()=>{
    a.value++;
}
</script>

<style scoped>

</style>

子组件:这里注意inject的写法,标注好a的类型(具体写法可以参考顶部的文档)

<template>
    <div>
        <h1>孙组件</h1>
        孙组件的a值:{{ a }}
        <button @click="add">a值+1</button>
    </div>
</template>

<script setup lang="ts">
import {inject, Ref} from "vue";

const a = inject<Ref<number>>('A')
const add = () => {
    if (a) {
        a.value++
    }
}
</script>

<style scoped>

</style>

文章来源:https://blog.csdn.net/qq_74637823/article/details/135445606
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。