vue3setup语法中组件间通信方式

86 阅读1分钟

父子间传值

通过defineProps和defineEmits

父组件传信息到子组件

父组件代码

<script setup>
import { onBeforeMount, ref, reactive } from "vue";
import { getUserInfoInterface } from "@/api/login";
import Children from "./Children.vue"

let userInfo = reactive({
  username:""
});

onBeforeMount(async () => {
  const { username } = await getUserInfoInterface();
  userInfo.username = username;
  console.log(userInfo);
})

</script>

<template>
  <div>
    <h1>home组件</h1>
    <children :message = "userInfo"></children>
  </div>
</template>

子组件代码

<script setup>

defineProps({
  message: String
})
</script>

<template>
  <div class="children">
    <h1>子组件</h1>
    <div>父组件传过来的值为<h3>{{message}}</h3></div>
  </div>
</template>

子组件传信息到父组件

子组件代码

<script setup>
const emits = defineEmits(['sendDataToParent'])
const emitDataToParent = () => {
  emits('sendDataToParent', 'childrenData')
}
</script>

<template>
  <div class="children">
    <h1>子组件</h1>
    <button @click="emitDataToParent">点击发送内容给父组件</button>
  </div>
</template>

父组件代码

<script setup>
import { onBeforeMount, ref, reactive } from "vue";
import Children from "./Children.vue"

const childrenData = ref("");

const receiveDataFromChildren = (data) => {
  childrenData.value = data;
}
</script>

<template>
  <div>
    <h1>home组件</h1>
    <children @sendDataToParent = "receiveDataFromChildren"></children>
    <div class="children_data" v-if="childrenData">这是子组件传递过来的值:<h2>{{childrenData}}</h2></div>
  </div>
</template>

通过ref和defineExpose

在父组件可以通过 ref拿到子组件传递过来的数据,并在父组件中对子组件数据进行操作。

子组件代码

<script setup>
import { ref,reactive } from "vue";


const info = reactive({
  name: "张三",
  age: 18,
});
const sex = ref("男");
const number = ref(0);
defineExpose({
  ...info,
  sex,
  number,
})

</script>

<template>
  <div>
    {{number}}
  </div>
</template>

<style lang="less" scoped>
</style>

父组件代码

<script setup>
import { ref } from "vue";
import Children2 from "./Children2.vue"


const children2Ref = ref(null);
const handleAddCounter = ()=>{
  children2Ref.value.number++;
  console.log(children2Ref.value.name);
  console.log(children2Ref.value.sex);
  
}
</script>

<template>
  <div>
    <children2 ref="children2Ref"></children2>
    <div class="children2">
      <h2>子组件2{{children2Ref}}</h2>
      <button @click="handleAddCounter">递增</button>
    </div>
  </div>
</template>

<style lang="less" scoped>
.children2{
    width: 200px;
    height: 200px;
    background-color: skyblue;
    font-size: 12px;
}
</style>

跨组件通信

使用Provide和Inject实现

  1. Provide在祖先组件使用,用于提供数据或方法给后代组件;
  2. Inject在后代组件中使用,用于接收祖先组件提供的数据或方法。

祖先组件代码

<script setup>
import { ref, provide } from "vue";
import Children from "./Children.vue"
import Children2 from "./Children2.vue"

const numberData = ref(100)
provide("numberData",numberData);
</script>

<template>
  <div>
    <div>这个是操作跨组件间通信例子,全局数据<h2>{{numberData}}</h2></div>
  </div>
</template>

<style lang="less" scoped>

</style>

后代A组件代码

<script setup>
import { ref,reactive,inject } from "vue";

const numberData = inject('numberData');
const handleSubNumber = () => {
  numberData.value--;
}

</script>

<template>
  <div>
    <button @click="handleSubNumber">全局递减A</button>
  </div>
</template>

<style lang="less" scoped>
</style>

后代B组件代码

<script setup>
import { ref,reactive,inject } from "vue";

const numberData = inject('numberData');
const handleSubNumber = () => {
  numberData.value--;
}

</script>

<template>
  <div>
    <button @click="handleSubNumber">全局递减B</button>
  </div>
</template>

<style lang="less" scoped>
</style>

全局通信

pinia/vuex