• Vue3中组件通讯的方式


    Vue3中组件通讯的方式

    1 🤖GPT🤖: (答案有点问题混淆了vue2的内容)

    父组件向子组件传递数据

    1. props 子组件通过 props 属性从父组件接收数据。
    2. emit事件子组件通过emit 事件 子组件通过 emit事件子组件通过emit 发射事件向父组件发送消息。
    3. provide / inject 父组件通过 provide 提供数据,子组件通过 inject 注入数据。
    4. ref 父组件通过 ref 获取子组件实例,然后调用子组件的方法。
    5. Slots 在父组件中使用Slots向子组件传递内容,子组件可以通过$slots来获取这些内容,并将它们渲染到自己的视图中。

    子组件向父组件传递数据

    emit事件使用emit 事件 使用 emit事件使用emit 发射事件,父组件通过 v-on 监听该事件。
    provide/inject 子组件通过 inject 注入父组件提供的数据,然后触发 Action 修改该数据,父组件的数据也就变了。
    Ref 父组件通过 ref 获取子组件的实例,子组件调用 ref 内容,父组件监听其变化。
    Vuex 使用 Vuex 管理共享状态,子组件通过 mutation 或 action 修改状态,父组件监听状态变化。
    Event Bus 利用 Vue 的实例作为 EventBus ,子组件通过 Bus.$emit 触发事件,父组件监听该事件的变化。

    兄弟组件之间的数据传递

    EventBus 可以使用EventBus来创建一个全局的事件总线,从而在兄弟组件之间进行数据传递。通过在兄弟组件中使用emit和emit和emit和on来触发和监听事件,从而实现数据的传递。
    Provide 和 Inject Vue 3中的Provide和Inject API也可以用于兄弟组件之间的数据传递,可以通过在父组件中使用Provide来提供数据,然后在兄弟组件中使用Inject来获取这些数据,从而实现兄弟组件之间的数据传递。
    Vuex Vuex是Vue 3中的状态管理库,可以用于管理全局的数据状态,从而实现兄弟组件之间的数据传递。
    在这里插入图片描述

    父组件向子组件传递数据:(父传子)

    1. props:

    逐级透传

    父组件

    <template>
    	<ChildComponent  :msg="message" />
    template>
    <script setup> 
    	const message = 'hello'
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    子组件:

    <template>
    	<p>{{ msg }}p> 
    template>
    
    <script setup>
    	defineProps(['msg'])
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2. provide/inject

    跨级共享

    provide(提供): 父组件中注册,传递给后代组件的数据对象
    inject( 注入):后代组件中接收父组件提供的数据对象

    父组件 Root.vue

    <template>
      <div>
        <Footer/>
      div>
    template>
    <script setup>
        import { ref,provide } from 'vue'
        import Footer from './Footer.vue' //导入子组件Footer
        //父组件中注册给共享后代组件的信息
        provide(/* 注入名 */ 'mgs', /* 值 */ '父组件信息!')  
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    子组件 Footer.vue

    <template>
        <DeepChild/>
    template>
    <script setup>
    import DeepChild from './DeepChild.vue' //导入子组件Footer
    //在子组件Footer中可以不需要接收父组件Root共享的数据,在后代组件中,直接接收,实现跨级传递
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    子孙组件DeepChild.vue

    不需要父组件Footer传递,就能跨级获取祖先组件Root传递的数据

    <template>
        <div>
            {{ msg }}
        div>
    template>
    <script setup>
        import { inject } from 'vue'
        const msg = inject('msg') //跨级接收祖先组件的共享的信息
        console.log(msg) //父组件信息
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    父组件向子组件传递信息,如果是多层组件嵌套(父>子>孙>孙孙…) ,props逐级透传十分麻烦,props可用但不优雅,更推荐 provide/inject依赖注入的方式;
    provide/inject依赖注入中父组件向后代组件通讯,如果说props是传递,逐级透传的,那么依赖注入更准确来说是在父组件中与后代组件共享数据,可实现跨级共享;

    3. 透传 Attributes(非props和非emit)

    “透传 attribute”指的是传递给一个组件,却没有被该组件声明为 props 或 emits 的 attribute 或者 v-on 事件监听器。最常见的例子就是 class、style 和 id

    作用: 在父组件标签上声明的参数/事件监听,会透传到子组件中

    3.1 Attributes透传参数

    父组件

    
    <MyButton class="large" />
    
    
    • 1
    • 2
    • 3

    子组件 MyButton.vue

    <button>click mebutton>
    
    • 1

    最终渲染的html标签

    <button class="btn large">click mebutton>
    
    • 1
    3.2 Attributes透传事件监听(有点像冒泡事件)

    父组件

     
     <MyButton @click="onClick1"  />
     
     <script setup>
         import  MyButton from './MyButton.vue'
         const onClick = ()=>{
           cosole.log("透传事件监听,从父组件触发")
         }
     script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    子组件 MyButton.vue

    <button @click ="onClick2">click mebutton>
    
    • 1

    当点击子组件的按钮时:
    父组件的onClick1 和子组件的onClick2 都触发

    3.3 useAttrs 像defineProps获取透传Attributes

    父组件

    
    <Child  msg="父组件中传递数据"  />
    
    <script setup>
        import  Child from './child.vue'
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    子组件child.vue

     <script setup>
    import { useAttrs } from 'vue'
    //useAttrs像defineProps获取透传Attributes
    const attrs = useAttrs()
    cosole.log(attrs.msg) //父组件中传递数据
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4. slot 插槽

    父组件向子组件指定位置插入html内容渲染

    4.1 默认插槽(传递html/组件)

    父组件

    <template>
      <Child>
        <div>插入的html,将会在子组件中指定slot的位置渲染出来div>
      Child>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    子组件

    <template>
       <slot><slot/>
    template>
    
    • 1
    • 2
    • 3
    4.2 具名插槽(父->子)

    当需要渲染不同的内容时,默认插槽显然不够用,需要按插槽的name名进行区别渲染

    父组件

    #XX == v-slot:XX 这2个写法都是插槽name名在父组件的写法

    <>
      <template #XX1> 插槽1 template>
      <template v-slot:XX2>插槽2template>
    >
    
    • 1
    • 2
    • 3
    • 4

    子组件

    <template>
       <slot name="XX1"><slot/>
       <slot name="XX2"><slot/>  
    template>
    
    • 1
    • 2
    • 3
    • 4
    4.3 作用域插槽 (子>父)

    作用插槽分为: 默认作用域插槽和 具名作用域插槽
    elementUI中table组件插入按钮就是使用了默认作用域插槽

    4.3.1. 默认作用域插槽: v-slot:defalut = #defalut = v-slot

    父组件

    <>
      <template #default="slotProps">
          {{slotProps.XX}}
      template>
    >
    
    • 1
    • 2
    • 3
    • 4
    • 5

    子组件

    <slot :XX="子组件数据">slot>
    
    • 1
    4.3.2. 具名作用域插槽

    父组件

     <>
      <template #slotName="slotProps">
          {{slotProps.XX}}
      template>
    >
    
    • 1
    • 2
    • 3
    • 4
    • 5

    子组件

    <slot name="slotName"  :XX="子组件数据">slot>
    
    • 1

    Element-PlusUI组件框架中table组件

    table组件中就用到了作用域插槽

    <el-table :data="tableData" style="width: 100%" max-height="250">
      <el-table-column fixed prop="date" label="Date" width="150" />
      <el-table-column fixed="right" label="Operations" width="120">
        <template #default="scope">
            {{scope.row.date}}
        template>
      el-table-column>
    el-table>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    子组件向父组件传递数据:(子传父)

    1.组件事件emit

    父组件中v-on(简写@)监听
    子组件中$emit触发

    父组件

    父组件中v-on(简写@)监听

     <template>
      <child @some-event="callback" />
    template>
    <script setup>
    import child from './child.vue'
    const callback = (target) => {
      console.log('父组件-callback ')
      console.log(target) //子组件传递的数据
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    子组件

    子组件中$emit触发

     <templete>
      在templete中使用$emit触发,不需要defineEmits声明    
      <button @click="$emit('someEvent', '子组件传递的数据')">click mebutton>  
        触发方法中的emit,需要defineEmits声明      
       <button @click="buttonClick()">click mebutton>  
    templete>
    
    <script setup>
    //setup语法糖中显示声明emit    
    const emit = defineEmits(['someEvent'])
    function buttonClick() {
      //触发emit  
      emit('someEvent', '子组件传递的数据')
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2. defineExpose/ ref

    子组件中通过defineExpose向外暴露数据或方法
    父组件中通过ref获取子组件暴露的数据或调用子组件的方法

    父组件

    在父组件中需要声明子组件的ref, 如:const childRef = ref()

     <template>
      <child ref="childRef" />
    template>
    <script setup>
    import { ref, onMounted } from 'vue'
    // 引入子组件
    import child from './child.vue'
        
    const childRef = ref()
    onMounted(() => {
      console.log(childRef.value.data1) // 子组件数据
      childRef.value.fn() // 子组件中的方法
    })
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    子组件

    子组件中通过defineExpose向外暴露数据或方法

     <script setup>
    import { ref } from 'vue'
    const data1 = ref('子组件数据')
    const fn = () => {
      console.log('子组件中的方法')
    }
    //通过defineExpose向外暴露数据或方法
    defineExpose({
      data1,
      fn
    })
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    跨组件通讯-全局状态共享(状态管理库): Vuex /Pinia

    在Vue3已经逐渐用Pinia这个菠萝替代Vuex了

    Pinia,官方文档描述:符合直觉的 Vue.js 状态管理库 hook的写法!
    其实Pinia的官方文档就写得很清楚了:🛬🛬🛬🛬🛬🛬🛬🛬🛬🛬🛬🛬为什么你应该使用 Pinia?

  • 相关阅读:
    php中mcrypt_encrypt升级到openssl_encrypt
    海量数据去重的Hash与BloomFilter学习笔记
    Linux 关闭某个服务失败处理方法
    时间序列预测实战(十五)PyTorch实现GRU模型长期预测并可视化结果
    17 HAP 覆盖特性与链路损耗特性分析
    算法导论第16章 贪心算法之活动选择
    Redis实战篇(1)
    Scala 高阶:Scala中的模式匹配
    45.Redis核心数据结构实战与高性能原理剖析
    【LeetCode】按公因数计算最大组件大小 [H](并查集)
  • 原文地址:https://blog.csdn.net/qq_36877763/article/details/136372805