复合组件模式允许你创建一组相互关联的组件,这些组件一起工作来实现特定的功能。
这里以一个简单的 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(树形)组件等等记住要根据实际需求来调整组件的结构和通信方式。
网友回复
腾讯混元模型广场里都是混元模型的垂直小模型,如何api调用?
为啥所有的照片分辨率提升工具都会修改照片上的图案细节?
js如何在浏览器中将webm视频的声音分离为单独音频?
微信小程序如何播放第三方域名url的mp4视频?
ai多模态大模型能实时识别视频中的手语为文字吗?
如何远程调试别人的chrome浏览器获取调试信息?
为啥js打开新网页window.open设置窗口宽高无效?
浏览器中js的navigator.mediaDevices.getDisplayMedia屏幕录像无法录制SpeechSynthesisUtterance产生的说话声音?
js中mediaRecorder如何录制window.speechSynthesis声音音频并下载?
python如何直接获取抖音短视频的音频文件url?