+
91
-

回答

复合组件模式允许你创建一组相互关联的组件,这些组件一起工作来实现特定的功能。

这里以一个简单的 Tabs 组件为例:

首先创建主组件 Tabs.vue:
<template>
  <div class="tabs">
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: 'Tabs',
  provide() {
    return {
      tabs: this
    }
  },
  data() {
    return {
      activeTab: 0,
      panels: []
    }
  },
  methods: {
    addPanel(panel) {
      this.panels.push(panel)
    },
    removePanel(panel) {
      const index = this.panels.indexOf(panel)
      if (index !== -1) {
        this.panels.splice(index, 1)
      }
    },
    setActiveTab(index) {
      this.activeTab = index
    }
  }
}
</script>
创建 TabNav 组件:
<template>
  <div class="tab-nav">
    <div
      v-for="(panel, index) in tabs.panels"
      :key="index"
      class="tab-nav-item"
      :class="{ active: tabs.activeTab === index }"
      @click="tabs.setActiveTab(index)"
    >
      {{ panel.title }}
    </div>
  </div>
</template>

<script>
export default {
  name: 'TabNav',
  inject: ['tabs']
}
</script>
创建 TabPanel 组件:
<template>
  <div v-show="tabs.activeTab === panelIndex" class="tab-panel">
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: 'TabPanel',
  inject: ['tabs'],
  props: {
    title: {
      type: String,
      required: true
    }
  },
  data() {
    return {
      panelIndex: -1
    }
  },
  created() {
    this.panelIndex = this.tabs.panels.length
    this.tabs.addPanel(this)
  },
  beforeDestroy() {
    this.tabs.removePanel(this)
  }
}
</script>
创建一个索引文件来导出所有组件:
import Tabs from './Tabs.vue'
import TabNav from './TabNav.vue'
import TabPanel from './TabPanel.vue'

export { Tabs, TabNav, TabPanel }
使用示例:
<template>
  <div>
    <Tabs>
      <TabNav />
      <TabPanel title="Tab 1">
        这是第一个标签页的内容
      </TabPanel>
      <TabPanel title="Tab 2">
        这是第二个标签页的内容
      </TabPanel>
      <TabPanel title="Tab 3">
        这是第三个标签页的内容
      </TabPanel>
    </Tabs>
  </div>
</template>

<script>
import { Tabs, TabNav, TabPanel } from './components/Tabs'

export default {
  components: {
    Tabs,
    TabNav,
    TabPanel
  }
}
</script>

<style>
.tabs {
  margin: 20px;
}

.tab-nav {
  display: flex;
  border-bottom: 1px solid #ddd;
}

.tab-nav-item {
  padding: 10px 20px;
  cursor: pointer;
}

.tab-nav-item.active {
  border-bottom: 2px solid #42b983;
}

.tab-panel {
  padding: 20px;
}
</style>

这个复合组件的特点:

组件通信: 使用 provide/inject 在组件之间共享状态灵活性: 可以自由组合各个子组件封装性: 各组件职责明确,互相配合可扩展性: 可以轻松添加新的功能或修改现有功能

使用复合组件的好处:

更好的组件封装更灵活的组件组合更清晰的组件职责更好的代码复用

你可以根据这个模式来创建其他类型的复合组件,比如:

Menu(菜单)组件Form(表单)组件Tree(树形)组件等等

记住要根据实际需求来调整组件的结构和通信方式。

网友回复

我知道答案,我要回答