返回

Vue 组件通信的 10 种方法:打造高效交互式应用

前端

  1. Props:父子组件之间的直接对话

Props 是最基本也是最常见的 Vue 组件通信方法。它允许父组件将数据传递给子组件,就像是在传递函数参数一样。Props 具有单向数据流的特性,这意味着子组件无法直接修改父组件传递的数据。

// 父组件
<template>
  <ChildComponent :message="message" />
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello from parent!'
    }
  }
}
</script>

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

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

2. EventBus:组件之间的事件中转站

EventBus 是一个全局事件总线,它允许组件之间通过发布和订阅事件来进行通信。EventBus 可以帮助解耦组件之间的关系,使组件之间的通信更加灵活。

// EventBus.js
export default new Vue();

// 父组件
<template>
  <button @click="greetChild">Greet Child</button>
</template>

<script>
import EventBus from './EventBus.js';

export default {
  methods: {
    greetChild() {
      EventBus.$emit('greet-child', 'Hello from parent!');
    }
  }
}
</script>

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

<script>
import EventBus from './EventBus.js';

export default {
  data() {
    return {
      message: ''
    }
  },
  mounted() {
    EventBus.$on('greet-child', (message) => {
      this.message = message;
    });
  }
}
</script>

3. Vuex:组件之间的共享状态管理

Vuex 是一个状态管理工具,它允许组件共享应用程序的全局状态。Vuex 通过一个集中式的存储来管理状态,并通过严格的规则来控制状态的修改。

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

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++
    }
  }
});

export default store;

// 父组件
<template>
  <button @click="incrementCount">Increment Count</button>
</template>

<script>
import { mapMutations } from 'vuex';

export default {
  methods: {
    ...mapMutations([
      'incrementCount'
    ])
  }
}
</script>

// 子组件
<template>
  <p>{{ count }}</p>
</template>

<script>
import { mapState } from 'vuex';

export default {
  computed: {
    ...mapState([
      'count'
    ])
  }
}
</script>

4. $parent:父子组件之间的直接通信

$parent 属性允许子组件直接访问父组件的实例。这对于某些场景下需要访问父组件的数据或方法非常有用。

// 父组件
<template>
  <ChildComponent />
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello from parent!'
    }
  },
  methods: {
    greetChild() {
      this.$children[0].greet();
    }
  }
}
</script>

// 子组件
<template>
  <p>{{ message }}</p>
  <button @click="greetParent">Greet Parent</button>
</template>

<script>
export default {
  data() {
    return {
      message: ''
    }
  },
  methods: {
    greet() {
      this.$parent.message = 'Hello from child!';
    },
    greetParent() {
      this.$parent.greetChild();
    }
  }
}
</script>

5. $emit:子组件向父组件发送事件

$emit 方法允许子组件向父组件发送事件。父组件可以通过在模板中使用 v-on 指令来监听子组件发出的事件。

// 父组件
<template>
  <ChildComponent @greet="handleGreet" />
</template>

<script>
export default {
  methods: {
    handleGreet(message) {
      alert(message);
    }
  }
}
</script>

// 子组件
<template>
  <button @click="greetParent">Greet Parent</button>
</template>

<script>
export default {
  methods: {
    greetParent() {
      this.$emit('greet', 'Hello from child!');
    }
  }
}
</script>

6. provide/inject:祖孙组件之间的通信

provide/inject 允许祖孙组件之间进行通信。祖先组件可以通过 provide 方法提供数据或方法,后代组件可以通过 inject 方法注入这些数据或方法。

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

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

// 子组件
<template>
  <GrandchildComponent />
</template>

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

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

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

7. Ref:组件之间的引用

Ref 允许组件之间相互引用。这对于某些场景下需要访问另一个组件的实例非常有用。

// 父组件
<template>
  <ChildComponent ref="child" />
</template>

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

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

<script>
export default {
  data() {
    return {
      message: ''
    }
  },
  methods: {
    greet() {
      this.message = 'Hello from child!';
    }
  }
}
</script>

8. 自定义事件:组件之间的自定义通信

自定义事件允许组件之间进行自定义的通信。这对于某些场景下需要组件之间进行特殊通信非常有用。

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

<script>
export default {
  methods: {
    handleCustomEvent(data) {
      alert(data);
    }
  }
}
</script>

// 子组件
<template>
  <button @click="triggerCustomEvent">Trigger Custom Event</button>
</template>

<script>
export default {
  methods: {
    triggerCustomEvent() {
      this.$emit('custom-event', 'Hello from child!');