Vue2和Vue3中常用组件通信方法有哪些

发布时间:2023-05-08 16:08:21 作者:iii
阅读:223
Vue开发者专用服务器,限时0元免费领! 查看>>

Vue2和Vue3中常用组件通信方法有哪些

目录

  1. 引言
  2. Vue2中的组件通信方法
    1. Props和Events
    2. 自定义事件
    3. Event Bus
    4. Vuex
    5. Provide/Inject
    6. $refs
    7. \(parent和\)children
  3. Vue3中的组件通信方法
    1. Props和Emits
    2. 自定义事件
    3. Event Bus
    4. Vuex
    5. Provide/Inject
    6. Refs
    7. Teleport
    8. Composition API
  4. Vue2和Vue3组件通信方法的对比
  5. 总结

引言

在Vue.js中,组件是构建用户界面的基本单位。随着应用规模的增大,组件之间的通信变得尤为重要。Vue2和Vue3提供了多种组件通信的方法,每种方法都有其适用的场景和优缺点。本文将详细介绍Vue2和Vue3中常用的组件通信方法,并对它们进行对比分析。

Vue2中的组件通信方法

Props和Events

在Vue2中,最常用的组件通信方式是通过propsevents。父组件通过props向子组件传递数据,子组件通过events向父组件发送消息。

// 父组件
<template>
  <ChildComponent :message="parentMessage" @update="handleUpdate" />
</template>

<script>
export default {
  data() {
    return {
      parentMessage: 'Hello from parent'
    };
  },
  methods: {
    handleUpdate(newMessage) {
      this.parentMessage = newMessage;
    }
  }
};
</script>

// 子组件
<template>
  <div>
    <p>{{ message }}</p>
    <button @click="updateMessage">Update Message</button>
  </div>
</template>

<script>
export default {
  props: ['message'],
  methods: {
    updateMessage() {
      this.$emit('update', 'Hello from child');
    }
  }
};
</script>

自定义事件

除了使用propsevents,Vue2还支持自定义事件。通过$emit方法,子组件可以向父组件发送自定义事件。

// 子组件
<template>
  <button @click="sendCustomEvent">Send Custom Event</button>
</template>

<script>
export default {
  methods: {
    sendCustomEvent() {
      this.$emit('custom-event', 'Custom event data');
    }
  }
};
</script>

// 父组件
<template>
  <ChildComponent @custom-event="handleCustomEvent" />
</template>

<script>
export default {
  methods: {
    handleCustomEvent(data) {
      console.log('Custom event received:', data);
    }
  }
};
</script>

Event Bus

Event Bus是一种全局事件总线,允许组件之间进行通信,而不需要直接的父子关系。通过创建一个全局的Vue实例作为事件总线,组件可以通过$on$emit方法进行通信。

// eventBus.js
import Vue from 'vue';
export const EventBus = new Vue();

// 组件A
<template>
  <button @click="sendMessage">Send Message</button>
</template>

<script>
import { EventBus } from './eventBus';
export default {
  methods: {
    sendMessage() {
      EventBus.$emit('message', 'Hello from Component A');
    }
  }
};
</script>

// 组件B
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
import { EventBus } from './eventBus';
export default {
  data() {
    return {
      message: ''
    };
  },
  created() {
    EventBus.$on('message', (data) => {
      this.message = data;
    });
  }
};
</script>

Vuex

Vuex是Vue.js的官方状态管理库,适用于大型应用中的状态管理。通过Vuex,组件可以共享状态,而不需要通过propsevents进行通信。

// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    message: 'Hello from Vuex'
  },
  mutations: {
    updateMessage(state, newMessage) {
      state.message = newMessage;
    }
  },
  actions: {
    updateMessage({ commit }, newMessage) {
      commit('updateMessage', newMessage);
    }
  }
});

// 组件A
<template>
  <button @click="updateMessage">Update Message</button>
</template>

<script>
export default {
  methods: {
    updateMessage() {
      this.$store.dispatch('updateMessage', 'New message from Component A');
    }
  }
};
</script>

// 组件B
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  computed: {
    message() {
      return this.$store.state.message;
    }
  }
};
</script>

Provide/Inject

ProvideInject是Vue2.2.0引入的一种高级组件通信方式,允许祖先组件向所有子孙组件注入依赖。

// 祖先组件
<template>
  <div>
    <ChildComponent />
  </div>
</template>

<script>
export default {
  provide() {
    return {
      message: 'Hello from ancestor'
    };
  }
};
</script>

// 子组件
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  inject: ['message']
};
</script>

$refs

$refs是Vue2中用于访问子组件或DOM元素的引用。通过$refs,父组件可以直接调用子组件的方法或访问子组件的属性。

// 父组件
<template>
  <ChildComponent ref="child" />
  <button @click="callChildMethod">Call Child Method</button>
</template>

<script>
export default {
  methods: {
    callChildMethod() {
      this.$refs.child.childMethod();
    }
  }
};
</script>

// 子组件
<template>
  <div>
    <p>Child Component</p>
  </div>
</template>

<script>
export default {
  methods: {
    childMethod() {
      console.log('Child method called');
    }
  }
};
</script>

\(parent和\)children

$parent$children是Vue2中用于访问父组件和子组件的引用。通过$parent,子组件可以访问父组件的属性和方法;通过$children,父组件可以访问子组件的属性和方法。

// 父组件
<template>
  <ChildComponent />
  <button @click="callChildMethod">Call Child Method</button>
</template>

<script>
export default {
  methods: {
    callChildMethod() {
      this.$children[0].childMethod();
    }
  }
};
</script>

// 子组件
<template>
  <div>
    <p>Child Component</p>
  </div>
</template>

<script>
export default {
  methods: {
    childMethod() {
      console.log('Child method called');
    }
  }
};
</script>

Vue3中的组件通信方法

Props和Emits

在Vue3中,propsemits仍然是组件通信的主要方式。与Vue2相比,Vue3中的emits更加明确,需要在组件中声明。

// 父组件
<template>
  <ChildComponent :message="parentMessage" @update="handleUpdate" />
</template>

<script>
export default {
  data() {
    return {
      parentMessage: 'Hello from parent'
    };
  },
  methods: {
    handleUpdate(newMessage) {
      this.parentMessage = newMessage;
    }
  }
};
</script>

// 子组件
<template>
  <div>
    <p>{{ message }}</p>
    <button @click="updateMessage">Update Message</button>
  </div>
</template>

<script>
export default {
  props: ['message'],
  emits: ['update'],
  methods: {
    updateMessage() {
      this.$emit('update', 'Hello from child');
    }
  }
};
</script>

自定义事件

Vue3中的自定义事件与Vue2类似,但需要在组件中明确声明emits

// 子组件
<template>
  <button @click="sendCustomEvent">Send Custom Event</button>
</template>

<script>
export default {
  emits: ['custom-event'],
  methods: {
    sendCustomEvent() {
      this.$emit('custom-event', 'Custom event data');
    }
  }
};
</script>

// 父组件
<template>
  <ChildComponent @custom-event="handleCustomEvent" />
</template>

<script>
export default {
  methods: {
    handleCustomEvent(data) {
      console.log('Custom event received:', data);
    }
  }
};
</script>

Event Bus

Vue3中仍然可以使用Event Bus,但由于Vue3的响应式系统发生了变化,建议使用mitt等第三方库来实现事件总线。

// eventBus.js
import mitt from 'mitt';
export const EventBus = mitt();

// 组件A
<template>
  <button @click="sendMessage">Send Message</button>
</template>

<script>
import { EventBus } from './eventBus';
export default {
  methods: {
    sendMessage() {
      EventBus.emit('message', 'Hello from Component A');
    }
  }
};
</script>

// 组件B
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
import { EventBus } from './eventBus';
export default {
  data() {
    return {
      message: ''
    };
  },
  created() {
    EventBus.on('message', (data) => {
      this.message = data;
    });
  }
};
</script>

Vuex

Vue3中仍然可以使用Vuex进行状态管理,但由于Vue3的Composition API的引入,Vuex的使用方式有所变化。

// store.js
import { createStore } from 'vuex';

export default createStore({
  state: {
    message: 'Hello from Vuex'
  },
  mutations: {
    updateMessage(state, newMessage) {
      state.message = newMessage;
    }
  },
  actions: {
    updateMessage({ commit }, newMessage) {
      commit('updateMessage', newMessage);
    }
  }
});

// 组件A
<template>
  <button @click="updateMessage">Update Message</button>
</template>

<script>
import { useStore } from 'vuex';
export default {
  setup() {
    const store = useStore();
    const updateMessage = () => {
      store.dispatch('updateMessage', 'New message from Component A');
    };
    return {
      updateMessage
    };
  }
};
</script>

// 组件B
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
import { computed } from 'vue';
import { useStore } from 'vuex';
export default {
  setup() {
    const store = useStore();
    const message = computed(() => store.state.message);
    return {
      message
    };
  }
};
</script>

Provide/Inject

Vue3中的ProvideInject与Vue2类似,但可以在setup函数中使用。

// 祖先组件
<template>
  <div>
    <ChildComponent />
  </div>
</template>

<script>
import { provide } from 'vue';
export default {
  setup() {
    provide('message', 'Hello from ancestor');
  }
};
</script>

// 子组件
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
import { inject } from 'vue';
export default {
  setup() {
    const message = inject('message');
    return {
      message
    };
  }
};
</script>

Refs

Vue3中的refs与Vue2类似,但可以在setup函数中使用。

// 父组件
<template>
  <ChildComponent ref="child" />
  <button @click="callChildMethod">Call Child Method</button>
</template>

<script>
import { ref } from 'vue';
export default {
  setup() {
    const child = ref(null);
    const callChildMethod = () => {
      child.value.childMethod();
    };
    return {
      child,
      callChildMethod
    };
  }
};
</script>

// 子组件
<template>
  <div>
    <p>Child Component</p>
  </div>
</template>

<script>
export default {
  methods: {
    childMethod() {
      console.log('Child method called');
    }
  }
};
</script>

Teleport

Teleport是Vue3中引入的新特性,允许将组件的内容渲染到DOM中的任意位置。通过Teleport,组件可以跨越层级进行通信。

// 父组件
<template>
  <div>
    <ChildComponent />
    <Teleport to="body">
      <ModalComponent />
    </Teleport>
  </div>
</template>

<script>
import { ref } from 'vue';
export default {
  setup() {
    const showModal = ref(false);
    return {
      showModal
    };
  }
};
</script>

// 子组件
<template>
  <button @click="showModal = true">Show Modal</button>
</template>

<script>
export default {
  setup() {
    const showModal = ref(false);
    return {
      showModal
    };
  }
};
</script>

// 模态框组件
<template>
  <div v-if="showModal">
    <p>This is a modal</p>
    <button @click="showModal = false">Close</button>
  </div>
</template>

<script>
export default {
  props: ['showModal']
};
</script>

Composition API

Vue3的Composition API提供了一种新的方式来组织组件的逻辑。通过Composition API,组件可以更加灵活地进行通信。

// useMessage.js
import { ref } from 'vue';

export function useMessage() {
  const message = ref('Hello from Composition API');
  const updateMessage = (newMessage) => {
    message.value = newMessage;
  };
  return {
    message,
    updateMessage
  };
}

// 组件A
<template>
  <button @click="updateMessage">Update Message</button>
</template>

<script>
import { useMessage } from './useMessage';
export default {
  setup() {
    const { updateMessage } = useMessage();
    return {
      updateMessage
    };
  }
};
</script>

// 组件B
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
import { useMessage } from './useMessage';
export default {
  setup() {
    const { message } = useMessage();
    return {
      message
    };
  }
};
</script>

Vue2和Vue3组件通信方法的对比

通信方法 Vue2支持 Vue3支持 适用场景 优点 缺点
Props和Events 父子组件通信 简单易用,官方推荐 不适合跨层级通信
自定义事件 父子组件通信 灵活,适合复杂场景 需要手动管理事件
Event Bus 跨组件通信 简单易用,适合小型应用 不适合大型应用,容易导致事件混乱
Vuex 大型应用状态管理 集中管理状态,适合大型应用 学习曲线较陡,不适合小型应用
Provide/Inject 祖先组件与子孙组件通信 适合跨层级通信 不适合兄弟组件通信
$refs 父组件访问子组件 直接访问子组件,适合简单场景 不适合复杂场景,容易导致代码耦合
\(parent和\)children 父子组件通信 直接访问父组件或子组件 不适合跨层级通信,容易导致代码耦合
Teleport 跨层级渲染组件 适合模态框等跨层级渲染场景 仅适用于特定场景
Composition API 组织组件逻辑 灵活,适合复杂场景 学习曲线较陡,不适合简单场景

总结

Vue2和Vue3提供了多种组件通信的方法,每种方法都有其适用的场景和优缺点。在Vue2中,propsevents是最常用的通信方式,而Vuex则适用于大型应用的状态管理。在Vue3中,Composition API的引入使得组件通信更加灵活,Teleport则提供了跨层级渲染的能力。开发者应根据具体需求选择合适的通信方式,以确保应用的稳定性和可维护性。

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

推荐阅读:
  1. spring boot+vue 的前后端分离与合并方案实例详解
  2. 在Spring boot项目中使用 mybatis 与Vue实现对数据进行增删改查操作

开发者交流群:

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

原文链接:https://juejin.cn/post/6999687348120190983

vue

上一篇:遍历LinkedList要用增强型for循环的原因是什么

下一篇:东八区springboot怎么配置序列化

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》
开发者交流群×