当前位置: 首页 > news >正文

vue2和vue3中的组件间通信知识点总结

vue2中组件间通信

在Vue2中,组件间的通信是构建复杂应用的关键。以下是一些常见的Vue2组件间通信方式,并附有详细说明和示例:

1. Props(父子组件通信)

Props是Vue中用于父子组件通信的一种机制。父组件通过属性(Props)将数据传递给子组件。

Vue2中的组件间通信方式多种多样,选择哪种方式取决于具体的应用场景和需求。在实际开发中,应根据组件间的关系和通信的复杂度来选择最合适的通信方式。

这种方式通常用于祖先组件向子孙组件传递数据或事件监听器

  • 示例
    <!-- 父组件 -->  
    <template>  <div>  <child-component :message="parentMessage"></child-component>  </div>  
    </template>  <script>  
    import ChildComponent from './ChildComponent.vue';  export default {  components: {  ChildComponent  },  data() {  return {  parentMessage: 'Hello from Parent'  };  }  
    };  
    </script>  <!-- 子组件 -->  
    <template>  <div>  <p>{{ message }}</p>  </div>  
    </template>  <script>  
    export default {  props: ['message']  
    };  
    </script>

    2. $emit(子父组件通信)

    子组件通过$emit触发自定义事件,父组件监听并响应这些事件,从而实现子父组件间的通信。

  • 示例
    <!-- 子组件 -->  
    <template>  <button @click="sendMessage">Send Message to Parent</button>  
    </template>  <script>  
    export default {  methods: {  sendMessage() {  this.$emit('custom-event', 'Hello from Child');  }  }  
    };  
    </script>  <!-- 父组件 -->  
    <template>  <div>  <child-component @custom-event="handleCustomEvent"></child-component>  </div>  
    </template>  <script>  
    import ChildComponent from './ChildComponent.vue';  export default {  components: {  ChildComponent  },  methods: {  handleCustomEvent(message) {  console.log('Received message from child:', message);  }  }  
    };  
    </script>

    3. EventBus(兄弟组件通信)

    通过创建一个中央事件总线EventBus,兄弟组件可以通过emit触发自定义事件,并通过on监听这些事件,从而实现兄弟组件间的通信。

  • EventBus文件
    // EventBus.js  
    import Vue from 'vue';  
    export const EventBus = new Vue();
  • 兄弟组件1
    <template>  <button @click="sendMessage">Send Message to Brother</button>  
    </template>  <script>  
    import { EventBus } from './EventBus.js';  export default {  methods: {  sendMessage() {  EventBus.$emit('custom-event', 'Hello from Brother1');  }  }  
    };  
    </script>
  • 兄弟组件2
    <template>  <p>{{ message }}</p>  
    </template>  <script>  
    import { EventBus } from './EventBus.js';  export default {  data() {  return {  message: ''  };  },  created() {  EventBus.$on('custom-event', (message) => {  this.message = message;  });  }  
    };  
    </script>

    4. Vuex(全局状态管理)

    Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。使用Vuex可以实现任意组件之间的通信。

  • 安装Vuex
    npm install vuex --save
  • 创建Store文件
    // store/index.js  
    import Vue from 'vue';  
    import Vuex from 'vuex';  Vue.use(Vuex);  export default new Vuex.Store({  state: {  globalMessage: ''  },  mutations: {  setGlobalMessage(state, message) {  state.globalMessage = message;  }  }  
    });
  • 使用Vuex的组件
    <!-- 组件1 -->  
    <template>  <button @click="sendMessage">Send Message to Anywhere</button>  
    </template>  <script>  
    export default {  methods: {  sendMessage() {  this.$store.commit('setGlobalMessage', 'Hello from Vuex');  }  }  
    };  
    </script>  <!-- 组件2 -->  
    <template>  <p>{{ globalMessage }}</p>  
    </template>  <script>  
    export default {  computed: {  globalMessage() {  return this.$store.state.globalMessage;  }  }  
    };  
    </script>

    5. Provide/Inject(祖先与后代组件通信)

    Provide/Inject是Vue2.2.0+新增的API,用于祖先组件向其所有后代组件提供数据/方法,后代组件通过inject选项来接收。

  • 祖先组件
    <template>  <div>  <descendant-component></descendant-component>  </div>  
    </template>  <script>  
    import { provide } from 'vue';  
    import { globalMessage } from './symbols.js';  export default {  setup() {  provide(globalMessage, 'Hello from Ancestor');  }  
    };  
    </script>
  • 后代组件
    <template>  <div>  <p>{{ foo }}</p>  </div>  
    </template>  <script>  
    export default {  inject: ['foo']  
    };  
    </script>

    6. $refs

    refs是一个对象,持有注册过ref特性的所有DOM元素和组件实例。父组件可以通过refs主动获取子组件的实例,从而直接调用子组件的方法或访问子组件的数据。

    <!-- 父组件 -->  
    <template>  <div>  <child-component ref="child"></child-component>  </div>  
    </template>  <script>  
    import ChildComponent from './ChildComponent.vue';  export default {  components: {  ChildComponent  },  mounted() {  const child = this.$refs.child;  console.log(child.str); // 获取子组件的数据  child.fn('调用了子组件的方法'); // 调用子组件的方法  }  
    };  
    </script>  <!-- 子组件 -->  
    <template>  <input type="text" />  
    </template>  <script>  
    export default {  data() {  return {  str: '我是数据'  };  },  methods: {  fn(e) {  console.log(e);  }  }  
    };  
    </script>

    7. parent或root

    通过parent或root,组件可以访问其父组件或根组件的实例,从而进行通信。但这种方式通常不推荐使用,因为它破坏了组件的封装性,使组件间的依赖关系变得复杂。

    8. attrs与listeners

  • **attrs∗∗:包含了父级作用域中不作为prop被识别(且获取)的特性绑定(class和style除外)。当组件没有声明某个prop时,这个prop会作为一个特性(attribute)绑定到组件的根元素上,并可以通过attrs进行访问。
  • **listeners∗∗:包含了父级作用域中的v−on事件监听器。这些监听器可以在组件内部通过listeners进行访问,并可以绑定到组件内部的元素上。

vue3中组件间通信

在Vue3中,组件间的通信方式多种多样,以下是几种常见的通信方式及示例:

一、props(父组件向子组件传递数据)

  • 说明:父组件通过props属性将数据传递给子组件。在子组件中,可以使用defineProps来接收这些数据。
  • 示例
    <!-- 父组件 -->  
    <template>  <div>  <h1>我是父组件</h1>  <child :name="name" age="12"></child>  </div>  
    </template>  <script setup lang="ts">  
    import child from './child.vue'  
    import { ref } from 'vue'  
    const name = ref('父亲名字')  
    </script>  <!-- 子组件 -->  
    <template>  <div>  <h1>我是子组件</h1>  <p>我收到了父组件的数据: {{ name }}</p>  <p>{{ props.age }}</p>  </div>  
    </template>  <script setup lang="ts">  
    const props = defineProps(["name", "age"]);  
    </script>

    二、自定义事件(子组件向父组件发送消息)

  • 说明:子组件通过$emit触发自定义事件,并传递数据给父组件。父组件通过监听这些事件来接收数据。
  • 示例
    <!-- 父组件 -->  
    <template>  <div>  <h1>我是父组件</h1>  <child @mimi="tingmimi"></child>  <p>我听到了子组件的秘密: {{ msg }}</p>  </div>  
    </template>  <script setup lang="ts">  
    import child from './child.vue'  
    import { ref } from 'vue'  
    let msg = ref('还没听到秘密')  
    const tingmimi = function(message: any) {  msg.value = message  
    }  
    </script>  <!-- 子组件 -->  
    <template>  <div>  <h1>我是子组件</h1>  <button @click="saymimi">点我给父组件说我的秘密</button>  </div>  
    </template>  <script setup lang="ts">  
    let $emit = defineEmits(['mimi'])  
    const saymimi = function() {  $emit('mimi', '是邓紫棋的我的秘密啦')  
    }  
    </script>

    三、mitt全局事件总线(兄弟组件间通信)

  • 说明:使用mitt库创建一个全局事件总线,允许任意组件间进行通信。
  • 示例
    # 安装mitt  
    npm i mitt
    // 在utils文件创建mitt.ts文件  
    import mitt from 'mitt'  
    const $bus = mitt()  
    export default $bus
    <!-- 子组件1 -->  
    <template>  <div>  <h1>我是子组件1</h1>  <p>我收到了来自兄弟的信息: {{ message }}</p>  </div>  
    </template>  <script setup lang="ts">  
    import $bus from '../utils/mitt'  
    import { ref } from 'vue'  
    let message = ref('还不知道呢')  
    $bus.on('mimi', (msg: any) => {  message.value = msg  
    })  
    </script>  <!-- 子组件2 -->  
    <template>  <div>  <h1>我是子组件2</h1>  <button @click="sayborder">点我给兄弟发秘密</button>  </div>  
    </template>  <script setup lang="ts">  
    import $bus from '../utils/mitt'  
    const sayborder = function() {  $bus.emit('mimi', { mimi: "遗产全都给我了" })  
    }  
    </script>

    四、v-model(父子组件数据双向绑定)

  • 说明v-model可以用于父子组件间的数据双向绑定。在子组件中,需要定义propsemits来配合v-model的使用。
  • 示例
    <!-- 父组件 -->  
    <template>  <div>  <h1>我是父组件</h1>  <p>我的财产: {{ money1 }}</p>  <child v-model:money="money1"></child>  </div>  
    </template>  <script setup lang="ts">  
    import { ref } from 'vue'  
    import child from './child.vue'  
    let money1 = ref(122000)  
    </script>  <!-- 子组件 -->  
    <template>  <div>  <h1>我是子组件</h1>  <input type="text" v-model="value.money">  <p>父亲的钱: {{ money }}</p>  <button @click="sayborder()">点我偷掉父亲的钱</button>  </div>  
    </template>  <script setup lang="ts">  
    const value = defineProps(['money'])  
    const $emit = defineEmits(['update:money'])  
    const sayborder = function() {  $emit('update:money', value.money - 200)  
    }  
    </script>

    五、useAttrs(获取组件的属性)

  • 说明useAttrs可以用于获取组件上未被props声明的属性。
  • 示例
    <!-- 父组件 -->  
    <template>  <div>  <h1>我是父组件</h1>  <child :money="money" data="extraData"></child>  </div>  
    </template>  <script setup lang="ts">  
    import { ref } from 'vue'  
    import child from './child.vue'  
    const money = ref(122000)  
    </script>  <!-- 子组件 -->  
    <template>  <div>  <h1>我是子组件</h1>  <p>收到了父亲的财产: {{ money }}</p>  <p>额外数据: {{ extraData }}</p>  </div>  
    </template>  <script setup lang="ts">  
    import { useAttrs } from 'vue'  
    let attrs = useAttrs()  
    let { money, data: extraData } = attrs  
    </script>

    六、ref与$parent(父组件访问子组件实例,子组件访问父组件实例)

  • 说明:使用ref可以在父组件中获取子组件的实例,从而直接调用子组件的方法或访问其数据。同时,子组件可以通过$parent访问父组件的实例。
  • 示例(仅展示父组件访问子组件):
    <!-- 父组件 -->  
    <template>  <div>  <h1>我是父组件</h1>  <child ref="mychildref"></child>  <button @click="accessChild">访问子组件</button>  </div>  
    </template>  <script setup lang="ts">  
    import child from "./child.vue"  
    import { ref } from "vue"  
    const mychildref = ref(null)  
    const accessChild = () => {  console.log(mychildref.value.someChildMethod()) // 假设子组件有一个someChildMethod方法  
    }  
    </script>  <!-- 子组件 -->  
    <template>  <div>  <h1>我是子组件</h1>  </div>  
    </template>  <script setup lang="ts">  
    const someChildMethod = () => {  return "我是子组件的方法"  
    }  
    defineExpose({  someChildMethod // 对外暴露方法,以便父组件访问  
    })  
    </script>

    七、Provide/Inject(跨层级组件通信)

  • 说明Provide/Inject是Vue3中新增的一种组件通信方式,用于实现跨层级的组件通信。祖先组件通过provide提供数据,后代组件通过inject获取数据。
  • 示例
    <!-- 祖先组件 -->  
    <template>  <div>  <h1>我是祖先组件</h1>  <parent></parent>  </div>  
    </template>  <script setup lang="ts">  
    import { provide } from 'vue'  
    import parent from './parent.vue'  
    provide('sharedData', '这是共享的数据')  
    </script>  <!-- 父组件 -->  
    <template>  <div>  <h1>我是父组件</h1>  <child></child>  </div>  
    </template>  <script setup lang="ts">  
    import child from './child.vue'  
    </script>  <!-- 子组件 -->  
    <template>  <div>  <h1>我是子组件


http://www.mrgr.cn/news/45005.html

相关文章:

  • 深入理解 JavaScript 中的表达式、运算符、语句和声明概念
  • 二进制求和
  • Bianchi模型、python计算及ns3验证_关于E[P*]的补充
  • Kubernetes 洞察:DaemonSet 全解析
  • Facebook 正式推出了一项专为 Z 世代设计的全新改版
  • 【时间盒子】-【9.任务设置项】自定义任务名称、任务时长等设置项组件
  • 软件测试比赛-学习
  • github项目学习——ruoyi-vue-pro
  • 音视频入门基础:FLV专题(14)——FFmpeg源码中,解码Script Tag的实现
  • 基于Python的美术馆预约系统【附源码】
  • [Algorithm][贪心][合并区间][无重叠区间][用最少数量的箭引爆气球]详细讲解
  • 数据结构 ——— 相交链表(链表的共节点)
  • CART回归树中的 方差减少量 计算步骤和示例
  • Ancient City Ruins 古代城市遗址废墟建筑游戏场景
  • 在数据中,如何删除表中的记录?
  • Cesium的一些神奇概念及技术流程(1)
  • 告别音乐小白!字节跳动AI音乐创作工具,让你一键变作曲家!
  • linux下cmake编译64位,32位,ARM,ARM64程序
  • 什么是 JavaScript 的数组空槽
  • 请散户股民看过来,密切关注两件大事