uni-oaview
v1.3.0
Published
uniapp小程序组件库
Readme
OA View SDK - uni-app 组件库
本组件项目不能直接运行,查看效果下载 https://gitlab.mockuai.com/FrontToClient/mk-uview
目录
组件列表
| 组件名 | 说明 | 位置 |
| -------------------------- | --------------------------------------- | -------------------------------------- |
| oa-area-select | 省市区选择组件 | components/oa-area-select/ |
| oa-area-select-popup | 省市区选择弹框 | components/oa-area-select-popup/ |
| oa-confirm | 确认弹框组件(配合 Message 使用) | components/oa-confirm/ |
| oa-login | 登录组件 | components/oa-login/ |
| oa-modal-wrapper | 函数式弹框容器(配合 createModal 使用) | components/oa-modal-wrapper/ |
| oa-multiple-select | 多选组件 | components/oa-multiple-select/ |
| oa-multiple-select-popup | 多选弹框 | components/oa-multiple-select-popup/ |
| oa-page | 页面容器组件(必需) | components/oa-page/ |
| oa-popup | 弹框组件(uni-popup 封装) | components/oa-popup/ |
| oa-rate | 评分组件 | components/oa-rate/ |
| oa-select | 选择组件 | components/oa-select/ |
| oa-select-popup | 选择弹框 | components/oa-select-popup/ |
| oa-skeleton | 骨架屏组件 | components/oa-skeleton/ |
| oa-toast | Toast 组件(配合 Message 使用) | components/oa-toast/ |
| oa-user-avatar | 用户头像组件 | components/oa-user-avatar/ |
| oa-vconsole | 调试工具组件 | components/oa-vconsole/ |
工具函数
createModal - 函数式弹框
基于事件总线的函数式弹框调用方案,支持多弹框叠加、自定义头部、Promise 和 subscribe 两种回调模式。
使用前请确保页面已使用 oa-page 组件包裹。
基础用法
import { createModal } from '@/uni-oaview/src/utils/create-modal';
import UserSelect from './components/user-select.vue';
// 方式 1:使用 subscribe(类似 RxJS)
createModal(UserSelect, {
title: '选择用户',
props: { list: userList.value },
}).subscribe((result) => {
console.log('选中用户:', result);
});
// 方式 2:使用 Promise(async/await)
const result = await createModal(UserSelect, {
title: '选择用户',
props: { list: userList.value },
});
console.log('选中用户:', result);API
function createModal(component: Component, options?: ModalOptions & { props?: Record<string, any> }): CreateModalReturn;
interface ModalOptions {
// uni-popup 原生属性
type?: 'center' | 'top' | 'bottom' | 'left' | 'right'; // 弹框类型
maskClick?: boolean; // 点击蒙层是否关闭(已废弃,使用 isMaskClick)
isMaskClick?: boolean; // 点击蒙层是否关闭弹框
animation?: boolean; // 是否开启动画
safeArea?: boolean; // 是否适配底部安全区
backgroundColor?: string; // 弹框背景色
maskBackgroundColor?: string; // 蒙层背景色,默认 'rgba(0, 0, 0, 0.4)'
borderRadius?: string; // 弹框圆角,默认 '16px 16px 0 0'
// 头部配置
header?: ModalHeaderOptions;
title?: string; // 弹框标题(当 header.title 不存在时使用)
// 内容区配置
contentPadding?: boolean; // 默认 true,添加 16px 内边距
maxHeight?: string; // 默认 '80vh'
// 蒙层控制
showMask?: boolean; // 是否显示蒙层,默认 true
// 回调
onHeaderAction?: (action: string, modalId: string) => void;
}
interface ModalHeaderOptions {
show?: boolean; // 是否显示头部
showClose?: boolean; // 是否显示关闭按钮
title?: string; // 头部标题文本
left?: Component | string; // 左侧内容(文本或组件)
leftProps?: Record<string, any>; // 左侧内容的属性
center?: Component | string; // 中间内容(文本或组件)
centerProps?: Record<string, any>; // 中间内容的属性
right?: Component | string; // 右侧内容(文本或组件)
rightProps?: Record<string, any>; // 右侧内容的属性
submitText?: string; // 提交按钮文本,不填则不显示提交按钮
submitProps?: Record<string, any>; // 提交按钮的属性
}
interface CreateModalReturn {
subscribe: (callback: (result: any) => void) => CreateModalReturn; // 订阅弹框关闭事件
close: (result?: any) => void; // 关闭弹框
updateProps: (props: Record<string, any>) => void; // 更新弹框内容组件的 props
then: Promise<any>['then']; // Promise then 方法
catch: Promise<any>['catch']; // Promise catch 方法
}自定义头部示例
// 方式 1:使用字符串
createModal(UserSelect, {
header: {
left: '返回',
center: '选择用户',
right: '确定',
showClose: false,
},
onHeaderAction: (action) => {
if (action === 'right-click') {
console.log('点击了确定');
}
},
});
// 方式 2:使用自定义组件
import CustomCloseBtn from './components/custom-close-btn.vue';
import CustomTitle from './components/custom-title.vue';
createModal(UserSelect, {
header: {
left: CustomCloseBtn,
leftProps: { color: '#333' },
center: CustomTitle,
centerProps: { title: '自定义标题' },
},
});
// 方式 3:无头部(完全自定义)
createModal(CustomPopup, {
header: { show: false },
});
// 方式 4:使用提交按钮(新增)
createModal(UserSelect, {
header: {
title: '选择用户',
submitText: '确定', // 显示提交按钮
},
});
// 方式 5:提交按钮和自定义按钮(提交按钮优先级高)
createModal(UserSelect, {
header: {
title: '选择用户',
submitText: '确定', // 显示提交按钮,忽略 right
right: '关闭', // 不会显示
},
});子组件规范
<!-- components/user-select.vue -->
<template>
<view class="user-select">
<!-- 内容区,无需处理头部和底部安全区 -->
<scroll-view scroll-y class="list">
<view v-for="user in props.list" :key="user.id" @click="selectUser(user)">
{{ user.name }}
</view>
</scroll-view>
</view>
</template>
<script setup lang="ts">
const props = defineProps<{
list: Array<{ id: string; name: string }>;
}>();
const emit = defineEmits(['close', 'update']);
// 点击选择用户(直接关闭弹框)
const selectUser = (user: any) => {
emit('close', user);
};
// 更新父级传入的 props(可选)
const updateList = (newList: any[]) => {
emit('update', { list: newList });
};
</script>使用提交按钮的子组件
当配置了 header.submitText 时,需要暴露 submit 方法:
<script setup lang="ts">
import { ref } from 'vue';
const formData = ref({ name: '' });
// 暴露 submit 方法(必须)
const submit = async () => {
// 表单验证失败返回 false,阻止关闭
if (!formData.value.name) {
uni.showToast({ title: '请输入名称', icon: 'none' });
return false;
}
// 异步提交
await api.save(formData.value);
// 返回结果给 subscribe 回调
return formData.value;
};
defineExpose({ submit });
</script>// 使用提交按钮
const modal = createModal(UserForm, {
header: {
title: '填写信息',
submitText: '保存',
},
});
// 接收 submit 返回的结果
modal.subscribe((result) => {
console.log('保存成功:', result);
});外部控制弹框
const modal = createModal(UserSelect, {
title: '选择用户',
props: { list: [] },
});
// 更新 props
modal.updateProps({ list: newList });
// 手动关闭
modal.close({ selected: true });
// 关闭所有弹框
import { closeAllModals } from '@/uni-oaview/src/utils/create-modal';
closeAllModals();注意事项
- 必须包裹 oa-page:每个使用
createModal的页面都需要使用oa-page组件包裹 - 最大弹框数:同时最多打开 5 个弹框,超出会自动关闭最早的弹框
- 返回键处理:在 App 端,点击返回键会优先关闭最上层弹框
- 页面卸载:页面卸载时会自动关闭所有弹框并清理事件监听
- 类型安全:所有接口已导出,可配合 TypeScript 使用
新增功能说明
蒙层控制(showMask)
// 隐藏蒙层
createModal(MyComponent, {
showMask: false,
props: {
/* ... */
},
});蒙层样式定制(maskBackgroundColor)
// 自定义蒙层颜色
createModal(MyComponent, {
maskBackgroundColor: 'rgba(0, 0, 0, 0.6)', // 更深的蒙层
props: {
/* ... */
},
});弹框圆角定制(borderRadius)
// 自定义圆角,默认 '16px 16px 0 0'
createModal(MyComponent, {
borderRadius: '10px 10px 10px 10px', // 四个角都有圆角
props: {
/* ... */
},
});提交按钮(submitText)
// 显示提交按钮,点击触发内部组件的 submit 方法
createModal(MyComponent, {
header: {
title: '选择用户',
submitText: '确定', // 提交按钮文本
},
props: {
/* ... */
},
});
// 内部组件暴露 submit 方法(支持 async)
const submit = async () => {
// 返回 false 阻止关闭
if (!valid) return false;
// 异步提交
await api.save();
// 返回结果
return result;
};
defineExpose({ submit });蒙层点击行为(isMaskClick)
// 点击蒙层关闭弹框(推荐使用 isMaskClick,maskClick 已废弃)
createModal(MyComponent, {
isMaskClick: true,
props: {
/* ... */
},
});Message - 消息提示
基于事件总线的消息提示工具,支持 Toast 和 Confirm 两种模式。
使用前请确保页面已使用 oa-page 组件包裹。
Toast 提示
import { Message } from '@/uni-oaview/src/utils/message';
// 成功提示
await Message.success('操作成功', '数据已保存');
// 警告提示
await Message.warning('注意', '请检查输入内容');
// 自定义按钮文本
await Message.success('提交成功', '等待审核', '我知道了');Confirm 确认框
import { Message } from '@/uni-oaview/src/utils/message';
try {
await Message.confirm('确定要删除吗?', '提示', '删除', '取消');
// 用户点击了确定
console.log('执行删除');
} catch {
// 用户点击了取消
console.log('取消删除');
}API
interface Message {
/**
* 成功提示
* @param title 标题
* @param content 内容
* @param confirmText 确认按钮文本(默认"我知道了")
*/
success(title: string, content: string, confirmText?: string): Promise<void>;
/**
* 警告提示
* @param title 标题
* @param content 内容
* @param confirmText 确认按钮文本(默认"我知道了")
*/
warning(title: string, content: string, confirmText?: string): Promise<void>;
/**
* 确认弹窗
* @param content 确认内容
* @param title 标题(默认"温馨提示")
* @param confirmText 确定按钮文本(默认"确认")
* @param cancelText 取消按钮文本(默认"取消")
* @returns Promise,确认 resolve,取消 reject
*/
confirm(content: string, title?: string, confirmText?: string, cancelText?: string): Promise<void>;
}页面规范
必须使用 oa-page
所有页面都需要使用 oa-page 组件作为根容器,否则 createModal 和 Message 将无法正常工作。
<template>
<oa-page>
<!-- 页面内容 -->
<view class="page-content">
<!-- ... -->
</view>
</oa-page>
</template>
<script setup lang="ts">
// 页面逻辑
</script>文件命名规范
- 组件文件:kebab-case(短横线连接)
- ✅
user-select.vue - ❌
UserSelect.vue
- ✅
- 工具函数:kebab-case
- ✅
create-modal.ts - ❌
createModal.ts
- ✅
注意事项
- 事件前缀:所有内部事件都使用
oa-ehK3Krfu#$opk^Ug!6Ce!-前缀,避免与其他库冲突 - 类型安全:建议所有组件使用 TypeScript 编写,并导出 Props 类型
- 内存管理:页面卸载时会自动清理弹框和事件监听,无需手动处理
- 样式隔离:弹框组件使用 scoped 样式,避免样式污染
License
MIT
