@yymojo-tec/mojo-ui

Mojo UI 是 YYmojo 旗下维护的 UI 组件库。
9,973
Install
npm install @yymojo-tec/mojo-ui
Latest Version:1.12.10
Vue:3
License:MIT
Last Updated:Aug 26, 2026
Links: npm
Maintainer: reset.cn

mojo-ui

mojo-ui 鏄竴涓熀浜?Vue 3銆乀ypeScript 鍜?Headless UI 灏佽鐨勭粍浠跺簱锛屾彁渚涙槑鏆椾袱濂椾富棰樻牱寮忋€?

瀹夎

pnpm add @yymojo-tec/mojo-ui

涔熷彲浠ヤ娇鐢?npm锛?

npm install @yymojo-tec/mojo-ui

鍏ㄩ噺寮曞叆

import { createApp } from "vue";
import MojoUi from "@yymojo-tec/mojo-ui";
import "@yymojo-tec/mojo-ui/style.css";
import App from "./App.vue";

createApp(App).use(MojoUi).mount("#app");

鎸夐渶寮曞叆

<script setup lang="ts">
import { MoButton } from "@yymojo-tec/mojo-ui";
import "@yymojo-tec/mojo-ui/style.css";
</script>

<template>
  <MoButton type="primary" theme="dark">鐢熸垚</MoButton>
</template>

涓婚

缁勪欢閫氳繃 theme 鍙傛暟鎺у埗浜壊鍜屾殫鑹诧細

<MoButton theme="light">Light</MoButton>
<MoButton theme="dark">Dark</MoButton>

缁勪欢

Button

<MoButton type="primary" round size="small">鐢熸垚闊宠壊</MoButton>

<MoButton theme="dark">
  <template #prefix>鉁?/template>
  閲嶆柊鐢熸垚
</MoButton>

<MoButton icon>
  <template #icon>鈫?/template>
</MoButton>

Row / Col

<MoRow :gutter="12">
  <MoCol :span="8">A</MoCol>
  <MoCol :span="8">B</MoCol>
  <MoCol :span="8">C</MoCol>
</MoRow>

Card

<MoCard theme="dark" shadow="hover" border-style="solid">
  鍗$墖鍐呭
</MoCard>

<MoCard theme="dark" selectable v-model:selected="selected">
  <template #selected-icon>鈾?/template>
  OrcaSlicer
</MoCard>

Form

<script setup lang="ts">
import { reactive } from "vue";
import { requiredRule, phoneRule } from "@yymojo-tec/mojo-ui";

const model = reactive({ name: "", phone: "" });
const rules = {
  name: [requiredRule("璇疯緭鍏ュ悕绉?)],
  phone: [requiredRule("璇疯緭鍏ユ墜鏈哄彿"), phoneRule()]
};
</script>

<template>
  <MoForm :model="model" :rules="rules" label-position="top">
    <MoFormItem label="鍚嶇О" prop="name" required>
      <MoInput v-model="model.name" placeholder="杈撳叆鍚嶇О" />
    </MoFormItem>
  </MoForm>
</template>

Input

<MoInput v-model="name" :maxlength="15" show-word-limit placeholder="杈撳叆鍚嶇О" />

<MoInput
  v-model="intro"
  type="textarea"
  :rows="4"
  :maxlength="1000"
  show-word-limit
  placeholder="杈撳叆寮€鍦虹櫧"
/>

<MoInput
  v-model="keyword"
  v-model:tags="tags"
  taggable
  placeholder="杈撳叆鍚庢寜鍥炶溅娣诲姞"
/>

Tabs

<MoTabs v-model="active" :items="tabs" size="large">
  <template #label="{ item }">
    {{ item.label }}
  </template>

  <template #panel="{ item }">
    {{ item.value }}
  </template>
</MoTabs>

Select

<MoSelect v-model="value" :options="options" theme="dark" />

Menu

<MoMenu :items="items" theme="dark" @select="handleSelect">
  <template #trigger>
    <MoButton theme="dark">鍙戝竷</MoButton>
  </template>
</MoMenu>

Upload

<MoUpload
  theme="dark"
  accept="image/png,image/jpeg,image/webp"
  :limit="1"
  :max-size="10"
  crop
  crop-shape="circle"
  :crop-size="96"
  hint="PNG/JPG/WebP锛屾渶澶?0MB"
/>

鑷畾涔変笂浼犲尯鍩燂細

<MoUpload theme="dark">
  <template #dropzone>
    <div class="upload-icon">+</div>
    <div>鎷栨嫿鏂囦欢鍒拌繖閲?/div>
    <div>鎴栫偣鍑讳笂浼?/div>
  </template>
</MoUpload>

鐭╁舰瑁佸垏锛?

<MoUpload crop crop-shape="rect" :crop-width="320" :crop-height="180" />

鏈湴寮€鍙?

pnpm install
pnpm dev

鏋勫缓

pnpm build

鍙戝竷鍓嶆鏌?

pnpm release:dry

Upload SDK

MoUpload 默认只负责选择文件、预览、裁切和维护文件状态,不会在选择文件后自动上传,也不会执行模拟上传。需要上传时,由外部手动触发:

<script setup lang="ts">
import { ref } from "vue";
import type { UploadFileItem } from "@yymojo-tec/mojo-ui";

const uploadRef = ref<{ submit: () => Promise<unknown[]> }>();

function submitUpload() {
  uploadRef.value?.submit();
}

function handleSuccess(file: UploadFileItem, response: unknown) {
  console.log(file, response);
}
</script>

<template>
  <MoUpload
    ref="uploadRef"
    action="/api/upload"
    :headers="{ Authorization: `Bearer ${token}` }"
    :data="{ scene: 'avatar' }"
    name="file"
    @success="handleSuccess"
  />

  <MoButton @click="submitUpload">开始上传</MoButton>
</template>

如果业务需要完全接管上传请求,可以传 request:

<MoUpload :request="customUpload" />
async function customUpload({ file, onProgress }) {
  const formData = new FormData();
  formData.append("file", file);

  await axios.post("/api/upload", formData, {
    onUploadProgress(event) {
      if (event.total) {
        onProgress((event.loaded / event.total) * 100);
      }
    }
  });
}

也可以独立使用上传 SDK:

import { uploadFile } from "@yymojo-tec/mojo-ui";

await uploadFile({
  file,
  action: "/api/upload",
  headers: { Authorization: `Bearer ${token}` },
  data: { scene: "avatar" },
  onProgress(percent) {
    console.log(percent);
  }
});

Scrollbar

MoScrollbar 绑定一个外部滚动容器,滚动条会显示在该容器右侧 border 内侧、padding 外侧,并使用外部容器的高度作为滚动轨道。

<script setup lang="ts">
import { ref } from "vue";

const panelRef = ref<HTMLElement>();
</script>

<template>
  <div ref="panelRef" class="panel">
    <div class="content">...</div>
  </div>

  <MoScrollbar :target="panelRef" theme="dark" />
</template>

<style scoped>
.panel {
  position: relative;
  height: 360px;
  overflow: auto;
  padding: 16px;
  border: 1px solid rgba(255, 255, 255, 0.12);
}
</style>

常用参数:

  • target: 外部滚动容器 ref 或元素
  • size: 滚动条宽度,默认 6
  • minThumbSize: 滑块最小高度,默认 28
  • offset: 距离右侧 border 的偏移量,默认 0
  • always: 是否常显
  • hideNative: 是否隐藏原生滚动条,默认 true

Dialog

MoDialog 基于 Headless UI Dialog 封装,使用 v-model 控制显示,默认带标题和关闭按钮。

<script setup lang="ts">
import { ref } from "vue";

const visible = ref(false);
</script>

<template>
  <MoButton @click="visible = true">打开弹窗</MoButton>

  <MoDialog v-model="visible" title="创建智能体" theme="dark" :padding="24">
    <p>这里放弹窗内容。</p>

    <template #footer>
      <MoButton theme="dark" type="ghost" @click="visible = false">取消</MoButton>
      <MoButton theme="dark" type="primary" @click="visible = false">确认</MoButton>
    </template>
  </MoDialog>
</template>

隐藏右上角关闭按钮:

<MoDialog v-model="visible" title="提示" :show-close="false">
  内容
</MoDialog>

常用参数:

  • v-model: 是否显示
  • title: 标题
  • theme: light | dark
  • width: 弹窗宽度,默认 520
  • padding: 内容和标题左右 padding,默认 24
  • showClose: 是否显示右上角关闭按钮,默认 true
  • closeOnOverlay: 点击遮罩或按 Esc 是否关闭,默认 true
  • lockScroll: 是否锁住页面滚动,默认 false

Tag

MoTag 目前提供实心样式,默认颜色有 purple、teal、orange、rose,也可以传入自定义背景色。

<MoTag color="purple">默认</MoTag>
<MoTag color="teal">已发布</MoTag>
<MoTag color="orange">待审核</MoTag>
<MoTag color="rose">推荐</MoTag>

<MoTag background-color="#222222">自定义</MoTag>

常用参数:

  • color: purple | teal | orange | rose
  • backgroundColor: 自定义背景色
  • textColor: 自定义文字颜色,默认 #ffffff
  • size: small | default | large
  • round: 圆角胶囊样式

MoRadioGroup

MoRadioGroup 基于 Headless UI RadioGroup 封装,当前提供分段实心样式。可以通过 background-color 修改外层背景,通过 active-background-color 修改选中项背景,图标使用 icon 插槽传入。

<script setup lang="ts">
import { ref } from "vue";

const action = ref("publish");
const radioOptions = [
  { label: "发布", value: "publish" },
  { label: "收藏", value: "favorite" },
  { label: "分享", value: "share" },
  { label: "导出", value: "export" }
];
</script>

<template>
  <MoRadioGroup
    v-model="action"
    theme="dark"
    :options="radioOptions"
    background-color="#171b24"
    active-background-color="#2e2a48"
  >
    <template #icon="{ option }">
      <PhShareNetwork v-if="option.value === 'publish'" :size="14" />
      <PhStar v-else-if="option.value === 'favorite'" :size="14" />
      <PhUploadSimple v-else-if="option.value === 'share'" :size="14" />
      <PhDownloadSimple v-else :size="14" />
    </template>
  </MoRadioGroup>
</template>

常用参数:

  • v-model: 当前选中的值
  • options: { label, value, disabled? }[]
  • theme: light | dark
  • size: small | default | large
  • backgroundColor: 外层背景色
  • activeBackgroundColor: 选中项背景色
  • textColor: 默认文字和图标颜色
  • activeTextColor: 选中文字和图标颜色

Related Packages

@mindvalley/eve-ai-ui

Eve AI - Component Library

14,409
@alanlee97/lee-ui

基于 Vue 3 的轻量级 UI 组件库

909
gwes-ui

基于vue3 + ts + vite 的前端组件库

908
@nubisco/ui

Vue 3 UI component library

35,080 1
whelk-ui

Vue3 Component Library for NearBeach

5,447

Version History

Version Released Vue License
1.12.10 ^3.5.0 MIT
1.12.9 ^3.5.0 MIT
1.12.8 ^3.5.0 MIT
1.12.7 ^3.5.0 MIT
1.12.6 ^3.5.0 MIT