跳过

vue3中组件通信方法

发布时间: at 02:33
本文收录在以下合集中:

在Vue 3中,组件之间的通信可以通过多种方式进行,以下是一些常用的方法:

1. Props(父传子)

通过props,父组件可以向子组件传递数据。

// 父组件
<template>
  <ChildComponent :user="user" />
</template>
<script>
  import ChildComponent from './ChildComponent.vue'
  export default {
    components: {
      ChildComponent,
    },
    data() {
      return {
        user: 'John Doe',
      }
    },
  }
</script>

2. Emit(子传父)

子组件可以通过$emit事件向父组件发送消息。

// 子组件
<template>
  <button @click="sendToParent">Send to Parent</button>
</template>
<script>
  export default {
    methods: {
      sendToParent() {
        this.$emit('sendMessage', 'Hello from child!')
      },
    },
  }
</script>
// 父组件
<template>
  <ChildComponent @sendMessage="handleMessage" />
</template>
<script>
  import ChildComponent from './ChildComponent.vue'
  export default {
    components: {
      ChildComponent,
    },
    methods: {
      handleMessage(message) {
        console.log(message)
      },
    },
  }
</script>

3. Provide / Inject

Vue 3 提供了provideinject来跨多个组件层次传递数据,而不必一层层传递props

// 祖先组件
<script>
  import {provide} from 'vue'
  export default {
    setup() {
      const theme = 'dark'
      provide('theme', theme)
    },
  }
</script>
// 后代组件
<script>
  import {inject} from 'vue'
  export default {
    setup() {
      const theme = inject('theme')
      return {theme}
    },
  }
</script>

4. Event Bus(简单事件总线)

虽然Vue 3不再推荐使用Event Bus,但仍然可以通过创建一个简单的Vue实例作为事件总线来使用。

// event-bus.js
import {createApp} from 'vue'
const eventBus = createApp({})
export default eventBus
// 发送事件
import eventBus from './event-bus.js'
eventBus.emit('someEvent', 'Hello!')
// 监听事件
import eventBus from './event-bus.js'
eventBus.on('someEvent', message => {
  console.log(message)
})

5. Vuex(状态管理)

对于大型应用,推荐使用Vuex来管理状态。

// store.js
import {createStore} from 'vuex'
export default createStore({
  state: {
    count: 0,
  },
  mutations: {
    increment(state) {
      state.count++
    },
  },
  actions: {
    increment({commit}) {
      commit('increment')
    },
  },
})
// 组件中使用
<template>
  <button @click="increment">Increment</button>
</template>
<script>
  import {mapActions} from 'vuex'
  export default {
    methods: {
      ...mapActions(['increment']),
    },
  }
</script>

6. Refs 和 $parent/$children

通过ref属性可以获取子组件实例,从而调用子组件的方法或访问其数据。

// 父组件
<template>
  <ChildComponent ref="child" />
</template>
<script>
import {ref} from 'vue'
import ChildComponent from './ChildComponent.vue'
export default {
  components: {
    ChildComponent,
  },
  setup() {
    const child = ref(null)
    // 在适当的时机调用子组件的方法
    child.value.someMethod()
  },
}
</script>

7. attrs 和 listeners

使用v-bind="$attrs"v-on="$listeners"可以自动将父组件的属性和事件传递给子组件。

// 父组件
<template>
  <ChildComponent :title="title" @click="handleClick" />
</template>
// 子组件
<template>
  <div v-bind="$attrs" v-on="$listeners"></div>
</template>

8. Slots(插槽)

插槽是 Vue 中用于复合组件的一种内容分发机制,它允许你将组件的内容组合在一起。

默认插槽

<!-- 父组件 -->
<template>
  <ChildComponent>
    <p>This is some default content</p>
  </ChildComponent>
</template>
<!-- 子组件 -->
<template>
  <div>
    <slot>Default slot content if no content is provided</slot>
  </div>
</template>

如果父组件没有提供任何内容,那么子组件中定义的默认内容将会被渲染。

具名插槽

具名插槽允许你将内容分发到子组件的不同位置。

<!-- 父组件 -->
<template>
  <ChildComponent>
    <template v-slot:header>
      <h1>This is a header</h1>
    </template>
    <template v-slot:default>
      <p>This is the main content</p>
    </template>
    <template v-slot:footer>
      <p>This is the footer</p>
    </template>
  </ChildComponent>
</template>
<!-- 子组件 -->
<template>
  <div>
    <header>
      <slot name="header"></slot>
    </header>
    <main>
      <slot></slot>
      <!-- 默认插槽 -->
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

作用域插槽

作用域插槽允许你在父组件中访问子组件的数据。

<!-- 父组件 -->
<template>
  <ChildComponent>
    <template v-slot:default="slotProps">
      <p>{{ slotProps.user.name }} - {{ slotProps.user.age }}</p>
    </template>
  </ChildComponent>
</template>
<!-- 子组件 -->
<template>
  <div>
    <slot :user="user"></slot>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        user: {
          name: 'John Doe',
          age: 30,
        },
      }
    },
  }
</script>

在上述例子中,ChildComponent 通过 slot 属性将 user 对象传递给了插槽,而父组件通过 v-slot:default="slotProps" 接收这个对象,并在插槽内容中使用它。 以上就是 Vue 3 中组件之间通信的各种方法,每种方法适用于不同的场景,你可以根据具体需求选择合适的方法。