npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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();

注意事项

  1. 必须包裹 oa-page:每个使用 createModal 的页面都需要使用 oa-page 组件包裹
  2. 最大弹框数:同时最多打开 5 个弹框,超出会自动关闭最早的弹框
  3. 返回键处理:在 App 端,点击返回键会优先关闭最上层弹框
  4. 页面卸载:页面卸载时会自动关闭所有弹框并清理事件监听
  5. 类型安全:所有接口已导出,可配合 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 组件作为根容器,否则 createModalMessage 将无法正常工作。

<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

注意事项

  1. 事件前缀:所有内部事件都使用 oa-ehK3Krfu#$opk^Ug!6Ce!- 前缀,避免与其他库冲突
  2. 类型安全:建议所有组件使用 TypeScript 编写,并导出 Props 类型
  3. 内存管理:页面卸载时会自动清理弹框和事件监听,无需手动处理
  4. 样式隔离:弹框组件使用 scoped 样式,避免样式污染

License

MIT