摘要
UniApp 作为一款支持多端编译的框架,封装通用组件可以大大提高代码复用率,减少重复开发成本。本文将介绍如何封装高复用性的 UniApp 组件,并适配多个平台,实现真正的 一次开发,多端运行。
# 一、为什么要封装通用组件?
在 UniApp 开发中,如果直接在每个页面写 UI 组件,可能会导致以下问题:
❌ 代码冗余:同样的 UI 逻辑在多个页面重复出现,后期维护困难。
❌ 不易维护:如果一个 UI 逻辑需要调整,就得改多个页面,容易出错。
❌ 平台差异:不同端(H5、小程序、App)可能存在细微的 UI 差异,统一管理更方便。
因此,我们需要封装 可复用、可配置、跨平台适配 的通用组件。
# 二、封装通用组件的基本方法
# 1️⃣ 组件结构
在 UniApp 中,封装组件的基本结构如下:
/components
├── CustomButton
│ ├── CustomButton.vue // 组件文件
│ ├── index.js // 组件导出
├── CustomModal
│ ├── CustomModal.vue
│ ├── index.js
每个组件独立管理,所有组件都存放在 components 目录下,便于维护。
# 2️⃣ 组件基础封装
以 CustomButton.vue 为例,我们封装一个通用按钮组件:
<template>
<button
class="custom-button"
:class="[type]"
:style="{ backgroundColor: bgColor, color: textColor }"
@click="handleClick"
>
<slot></slot>
</button>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
type: { type: String, default: 'primary' }, // 按钮类型
bgColor: { type: String, default: '#007AFF' }, // 背景颜色
textColor: { type: String, default: '#ffffff' } // 文字颜色
});
const emit = defineEmits(['click']);
const handleClick = () => {
emit('click');
};
</script>
<style scoped>
.custom-button {
padding: 10px 20px;
border-radius: 5px;
font-size: 16px;
border: none;
}
.primary { background-color: #007AFF; color: white; }
.secondary { background-color: #ccc; color: black; }
</style>
✅ 组件特点:
- 通过
props接收外部参数,可配置按钮样式。 - 使用
slot让按钮内容可自定义。 - 通过
emit('click')让父组件监听按钮点击事件。
# 3️⃣ 在页面中使用组件
<template>
<view>
<CustomButton type="primary" @click="handlePrimaryClick">确定</CustomButton>
<CustomButton type="secondary" @click="handleSecondaryClick">取消</CustomButton>
</view>
</template>
<script setup>
import CustomButton from '@/components/CustomButton.vue';
const handlePrimaryClick = () => console.log('Primary 按钮点击');
const handleSecondaryClick = () => console.log('Secondary 按钮点击');
</script>
# 三、封装可跨平台适配的组件
不同端 UI 存在差异,比如:
- H5 端 可能需要
div - 微信小程序 需要
view - App 端 可能需要
button
# 1️⃣ 适配不同平台
我们可以用 uni.getSystemInfoSync() 判断运行平台,并动态调整 UI:
<template>
<view v-if="platform === 'H5'">H5 显示</view>
<button v-else-if="platform === 'APP'">App 按钮</button>
<text v-else>小程序显示</text>
</template>
<script setup>
import { ref, onMounted } from "vue";
const platform = ref("");
onMounted(() => {
const systemInfo = uni.getSystemInfoSync();
platform.value = systemInfo.platform;
});
</script>
✅ 这样,不同平台会自动选择合适的 UI 元素!
# 四、封装弹窗组件(支持传入插槽内容)
很多业务场景需要弹窗,我们可以封装一个通用弹窗 CustomModal.vue:
<template>
<view v-if="visible" class="modal-mask">
<view class="modal-content">
<slot></slot> <!-- 这里可以传入任意内容 -->
<button @click="closeModal">关闭</button>
</view>
</view>
</template>
<script setup>
import { defineProps, defineEmits } from "vue";
const props = defineProps({
visible: { type: Boolean, default: false },
});
const emit = defineEmits(["update:visible"]);
const closeModal = () => {
emit("update:visible", false);
};
</script>
<style scoped>
.modal-mask {
position: fixed;
top: 0; left: 0; width: 100%; height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex; align-items: center; justify-content: center;
}
.modal-content {
background: white;
padding: 20px;
border-radius: 10px;
width: 80%;
}
</style>
# 使用方式
<template>
<view>
<CustomButton @click="showModal = true">打开弹窗</CustomButton>
<CustomModal v-model:visible="showModal">
<text>这是一个通用弹窗</text>
</CustomModal>
</view>
</template>
<script setup>
import { ref } from "vue";
import CustomModal from "@/components/CustomModal.vue";
const showModal = ref(false);
</script>
✅ 组件特点:
visible控制显示隐藏,支持v-model。<slot>允许插入任意内容,复用性更强。
# 五、组件封装的最佳实践
✅ 1. 组件功能单一化:避免让一个组件做太多事情,每个组件尽可能只负责一件事。
✅ 2. 组件参数可配置:使用 props 让组件可定制,避免硬编码。
✅ 3. 适配不同平台:考虑 uni.getSystemInfoSync() 进行适配,确保组件能在所有端正常运行。
✅ 4. 组件间通信:使用 emit 事件机制让父组件和子组件交互,而不是直接操作数据。
# 六、总结
🚀 完整组件封装流程:
- 创建基础组件(如按钮、弹窗)。
- 封装通用逻辑(支持
props配置,使用slot让内容可定制)。 - 适配多端 UI 差异(使用
uni.getSystemInfoSync()判断平台)。 - 组件间交互(使用
emit事件通信)。
封装通用组件后,开发效率提高 50%+,代码复用率提升,维护成本降低! 🎯
👉 如果你觉得有帮助,欢迎点赞、收藏! 🚀