1.2.0 • Published 9 months ago

@meleon/uni-ui v1.2.0

Weekly downloads
-
License
ISC
Repository
github
Last release
9 months ago

开发指南

一、快速上手

演示

使用微信扫描下方的小程序码,在线查看组件的渲染效果。

注:如果因为网络等原因,小程序码图片无法加载,也可以直接输入 Meleon Uni-ui 关键字查询

image-20231007221035897

安装
# npm
npm install @meleon/uni-ui
引入

H5 端

import MeleonUI from "@meleon/uni-ui"

export function createApp() {
  const app = createSSRApp(App)
  app.use(MeleonUI)
    
  return { app }
}

微信小程序端

对比分别在项目入口文件 main.ts 和组件库的入口文件 meleon-ui.ts 里注册的组件,被编译到微信小程序上的结果:

// main.ts
import { createSSRApp } from 'vue'
import MeleonUI from "@meleon/uni-ui";
import MlButton from '@meleon/uni-ui/lib/ml-button/index.vue'
import App from './App.vue'

export function createApp() {
  const app = createSSRApp(App)
  app.use(MeleonUI)

  app.component('MlButtonGlobal', MlButton)

  return {
    app
  }
}
// meleon-ui.ts
import type { App, Plugin } from 'vue'
import MlButton from './ml-button'

const components: Record<string, Plugin> = {
    MlButton,
}
const install = (app: App) => {
    for (const key in components) {
        if (Object.prototype.hasOwnProperty.call(components, key)) {
            app.use(components[key])
        }
    }
}

const MeleonUI = { install }

export default MeleonUI

// ml-button/index.ts
import type { App } from 'vue'
import _Button from './index.vue'

const install = async (app: App) => {
    app.component('MlButton', _Button)
}

export default { install }

虽然本质上都是使用 app.component 实现注册组件,但 uniapp 编译的结果却并不完全相同

main.ts 中注册 MlButtonGroup 组件被编译成函数

meleon-ui.ts 里的组件被编译成对象

在使用时也是前者可以被正常渲染成组件展示到页面上

因此,如果希望在微信小程序端实现批量注册组件,需要使用 uniapp 提供的 easycom 方法

详细内容可跳转:https://uniapp.dcloud.net.cn/collocation/pages.html#easycom

// page.json
{
  "easycom": {
    "custom": {
      "^ml-(.*)": "@meleon/uni-ui/lib/ml-$1/index.vue"
    }
  }
}

二、定制主题

MeleonUI 为用户提供了自定义主题的方法,可以通过向 ml-config-provider 组件传入 themes 属性,同时修改当前页面所有 ml- 组件的主题色

<!-- template -->
<ml-config-provider :themes="themes">
  <!-- 消息提示 -->
  <ml-message ref="messageRef" />
  <!-- 导航栏 -->
  <ml-navigator
    :title="$t('home.navigation.title')"
    title-color="#FFFFFF"
    background="#7A98B3"
  ></ml-navigator>
  <ml-button
    type="primary"
    @click="onNavigate('/pages/componentList/index')"
  >
    {{ $t('home.actions.start') }}
    <ml-icon icon="ml-arrow-right--line" color="#FFFFFF" />
  </ml-button>
</ml-config-provider>
// script
import type { ConfigProviderProps } from '@meleon/uni-ui'

const themes: ConfigProviderProps['themes'] = {
    primary: '#D74B4B',
}

themes 支持以下属性,可根据项目的设计风格批量修改,当然,直接通过 CSS 修改样式也是可以的。

export type ColorType = 'primary' | 'info' | 'success' | 'warning' | 'danger'

三、类型声明

在使用组件时,为了得到更好的类型提示,可以在 tsconfig.json 中注入 MeleonUI 的类型声明文件,如下所示。 如果你的编辑器中安装了 Volar 插件,注入成功后应该可以看到组件标签的颜色发生了变化,且当尝试传入组件 props 时,编辑器也会给出可选值的提示信息。

{
  "types": ["@dcloudio/types", "@meleon/uni-ui"]
}

四、更新日志

  • 1.2.0
    • refactor: 打包结果调整
      • 去除初始的 .ts 文件
      • 去除用于 重新导出index.jsindex.d.ts 文件
      • 使用 terser 压缩代码,大幅降低组件库构建到小程序后的体积
      • @meleon/uni-ui小程序主包的构建体积从优化前的 2.2MB 降低到现在的 958KB
      • 注:如果准备将 1.1 版本升级到 1.2版本,最好检查下之前对组件库内部方法、类型的引用路径是否存在问题,避免出现 bug
    • feat: 调整 ml-form 组件,添加下拉选框、多选、日期选择器、开关等表单项
  • 1.1.13
    • feat: 新增 ml-form 组件【暂时仅支持 input 组件作为表单项】
    • feat: 新增 ml-transition 组件
  • 1.1.12
    • style: ml-drawer 组件添加动效
    • fix: ml-list 组件修改虚拟列表插槽名称错误
    • feat: 新增 ml-datetime-pickerml-time-picker 两个时间选择组件
  • 1.1.11
    • feat: 调整 ml-navigator 组件的结构,完善功能
    • feat: 添加 ml-switch 组件
    • feat: ml-cell 组件添加 SWITCH 类型
    • fix: ml-cell 组件传入的 value 发生变化时未触发页面更新
    • feat: 新增 ml-list 组件,初步支持基础列表和虚拟列表功能
  • 1.1.10
    • fix: ml-checkbox 设置 direction 失效的问题
    • fix: ml-image 预览层层级过低的问题
    • fix: ml-select 无激活样式的问题
    • fix: ml-input-tag 确认后未触发新增标签
    • docs: @meleon/uni-ui上线微信小程序,可体验各个组件的使用效果【微信扫描“演示”小程序码】
  • 1.1.9
    • fix: ml-loading 图标缺失,ml-button 组件设置 loading 不生效
    • feat: 新增 ml-image 组件
    • feat: ml-tree 组件模块拆分,支持自定义 title 节点
    • feat: 新增 ml-icon-switcher 小组件
    • fix: ml-button 单图标按钮图标偏移的问题
    • feat: ml-tree 组件基本功能完善,支持文本选中、复选框选择、自定义标题节点等
    • fix: 去除 ml-checkbox 组件无文本时样式的偏移
    • feat: ml-tree 组件新增对外暴露的 expand、check 及 select 等方法
  • 1.1.8
    • feat: 新增 ml-cellml-cell-group 组件
    • feat: 新增 ml-uploader 组件
  • 1.1.7
    • feat: 新增 ml-config-provider 组件
    • docs: 调整项目接口,补全TS类型,新增 README 文档

组件

头像 Avatar

基本使用

如果头像内容是文字的话,会自动调节字体大小,来适应头像框

<!-- 基础使用 -->
<ml-avatar>Meleon</ml-avatar>
<!-- 设置尺寸 -->
<ml-avatar :size="36">Meleon</ml-avatar>
<!-- 设置形状 -->
<ml-avatar :size="28" shape="circle">Meleon</ml-avatar>
<!-- 插入图片 -->
<ml-avatar shape="circle">
  <image src="@/assets/home/avatar.png" mode="widthFix" />
</ml-avatar>
APIs
proptypedefault
sizenumber32
shapesquare | circlesquare
Slots
namedesc
default默认插槽,传递文本或图片

头像组 AvatarGroup

基本使用

除了 maxCount 等属性,还可以传入 Avatar 的 size、shape 等属性实现批量设置

<ml-avatar-group :size="36" :offset="10" shape="circle">
    <ml-avatar>Meleon</ml-avatar>
    <ml-avatar>Aliee</ml-avatar>
    <ml-avatar>Bob</ml-avatar>
</ml-avatar-group>
APIs
proptypedefaultdesc
maxCountnumber3多出的部分会显示剩余的 count
offsetnumber0头像组件之前的偏移量
sizenumber32头像组件的尺寸
shapesquare | circlesquare头像组件的形状

按钮 Button

基本使用
<ml-button
  type="primary"
  size="mini"
  status="success"
>
    Primary
</ml-button>

<ml-button
  type="secondary"
  size="mini"
  shape="round"
  status="success"
>
    Secondary
</ml-button>

<ml-button
  type="outline"
  size="mini"
  status="success"
>
    Outline
</ml-button>

<ml-button
  type="text"
  size="mini"
  status="success"
  @click="handleClick"
>
    Text
</ml-button>
APIs
proptypedesc
typeprimary | secondary | outline | text按钮类型
sizemini | small | medium | large按钮尺寸
shapesquare | round | circle按钮形状
statusnormal | success | warning | danger按钮状态
loadingboolean是否加载中
disabledboolean是否禁用
Slots
namedesc
default默认插槽
icon图标插槽【位于默认插槽左侧】
Emits
eventdessc
click点击事件

单元格 Cell

基本使用
<ml-cell-group title="测试分组" style="width: 100%">
    <ml-cell
        :type="CellTypeEnum.TEXT"
        label="测试标题"
        value="测试内容"
        description="测试描述"
        disabled
        allow-edit
        style="width: 100%"
        @change="handleCellChange"
    ></ml-cell>
    <ml-cell
        :type="CellTypeEnum.BUTTON"
        label="测试按钮"
        btn-status="danger"
        disabled
        style="width: 100%"
        @btn-click="handleClick"
    ></ml-cell>
    <ml-cell
        :type="CellTypeEnum.NAV"
        label="测试回到首页"
        value="回首页"
        url="/pages/home/index"
        :disabled="false"
        style="width: 100%"
    >
        <template #rightIcon>
          <ml-icon name="ml-arrow-right--line" color="var(--info-color-7)"></ml-icon>
        </template>
        <template #value>
          <text style="font-size: 14px; color: var(--info-color-7)">通过插槽展示内容</text>
        </template>
    </ml-cell>
</ml-cell-group>
APIs
proptypedefaultdesc
labelstring''左侧标题
descriptionstring''左侧描述
valuestring''右侧 值
typetext | button | navigatortext单元格类型【推荐使用 CellTypeEnum 枚举变量赋值】
disabledbooleanfalse是否禁用
allowEditbooleanfalse文本单元格是否允许修改
btnStatusnormal | success | warning | dangernormal按钮单元格的按钮类型
urlstring''导航单元格的跳转地址【小程序页面地址需要保留前面的 / 字符】
Slots
namedesc
label左侧标题插槽【会覆盖默认的 label 和 description 区域】
value右侧内容插槽
rightIcon导航单元格生效【覆盖右侧图标】
Emits
namedesc
change文本单元格修改内容后触发
btnClick按钮单元格点击触发
navigate导航单元格点击跳转后触发【暂不暴露,考虑有没有必要放出来】
CellGroup APIs
proptypedefaultdesc
titlestring''分组名称
CellGroup Slots
namedesc
title标题插槽【覆盖标题内容】

选择框 Checkbox

基本使用
<ml-checkbox v-model:checked="checked1">Radio</ml-checkbox>
<ml-checkbox indeterminate>Radio</ml-checkbox>
<ml-checkbox v-model:checked="checked1" disabled>Radio</ml-checkbox>
APIs
propstypedefaultdesc
checkedbooleanfalse是否选中
indeterminatebooleanfalse是否为半选状态
disabledbooleanfalse是否禁用
valuestring | number''CheckboxGroup 下的 value 标识
Slots
namedesc
default选择框右侧内容
Emits
eventdesc
update:checked切换事件

选择框分组 CheckboxGroup

基本使用
<ml-checkbox-group
  v-model:checked-list="checked3"
  mode="multi"
  :max="3"
  :min="1"
>
    <ml-checkbox value="A">RadioA</ml-checkbox>
    <ml-checkbox value="B">RadioB</ml-checkbox>
    <ml-checkbox value="C">RadioC</ml-checkbox>
    <ml-checkbox value="D">RadioD</ml-checkbox>
    <ml-checkbox value="E">RadioE</ml-checkbox>
</ml-checkbox-group>
APIs
proptypedefaultdesc
checkedListArray<string | number>必填选中的选项列表
minnumber0至少选中数量
maxmaxInfinity至多选中数量
directionvertical | horizontalhorizontal纵向或横向排列
modesingle | multisingle切换单选或多选
Emits
eventdesc
update:checkedList更新选中的列表

全局配置 ConfigProvider

基本使用

设置全局主题色

<ml-config-provider :themes="themes">
    <ml-button type="primary"></ml-button>
    <ml-button type="success"></ml-button>
    <ml-button type="warning"></ml-button>
    <ml-button type="danger"></ml-button>
</ml-config-provider>
import type { ConfigProviderProps } from '~/lib/ml-config-provider/index.interface'

const themes: ConfigProviderProps['themes'] = {
  primary: '#D74B4B'
}
APIs
proptypeexample
themesConfigProviderProps'themes'{ primary: '#D74B4B' }

数值显示 CountTo

基本使用
<ml-count-to
    :from="0"
    :to="1250.44"
    animation
    :animation-duration="5000"
    :value-style="{ color: '#0fbf60' }"
>
    <template #suffix>
      <text>%</text>
    </template>
</ml-count-to>
APIs
proptypedefaultdesc
fromnumber0起始值
tonumberrequired结束时展示的数据,必填
animationbooleanfalse是否开启动画
animationDurationnumber1000动画持续时间
showSeperatorbooleanfalse是否显示千分位分隔符
valueStyleRecord<string, any>{}数据的样式
Slots
namedesc
prefix数值左侧的内容
suffix数值右侧的内容
Expose
namedesc
start开启动画
pause暂停动画
restart继续动画

时间选择器 DatetimePicker

基本使用
<ml-datetime-picker
    v-model="value"
    mode="date"
    :disabled-date="isDateDisabled"
    style="width: 100%"
    @change="handleValueChange"
>
    <template #trigger>
        <ml-cell
            label="日期选择器"
            :value="formatToDateTime(value)"
            style="width: 100%"
        ></ml-cell>
    </template>
</ml-datetime-picker>
const value = ref(new Date())

const isDateDisabled = (current: Date) => {
    return current.getTime() < new Date().getTime() - 24 * 60 * 60 * 1000
}

const handleValueChange = (value: DatetimePickerProps['modelValue']) => {
    console.log('change', value)
}
APIs
proptypedefaultdesc
modelValueDate, string, number''选择的日期时间
defaultModelValueDate, string, number''默认展示的日期时间
pickerValueDate, string, number''面板头部展示的时间
defaultPickerValueDate, string, number''面板头部默认展示的时间
localeRecord<string, any>{}自定义面板中展示的文本
mode'date', 'year', 'month''date'选择器模式
formatstring'YYYY-MM-DD'时间转换格式
disabledDate(current: Date) => booleanundefined判断日期是否禁用
Emits
nametypedesc
change(value: Date) => void选中值发生变化时触发
update:modelValue(value: Date) => void双向绑定选中日期

抽屉 Drawer

基本使用
<ml-drawer
  v-model:visible="modelVisible"
  :placement="placement"
  :has-nav="hasNav"
>
    <template #title>自定义标题</template>
    <text>
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Magni, dolor libero
        blanditiis distinctio commodi totam recusandae aliquam fugit officiis sequi
        perspiciatis non animi, eaque facilis sed reiciendis in aut vel.
    </text>
    <template #footer>
        <ml-button>自定义页脚</ml-button>
    </template>
</ml-drawer>
APIs
proptypedefaultdesc
hasNavbooleantrue当前页面有无导航栏,以控制 drawer 高度
visiblebooleanrequired是否显示
placementleft | right | top | bottomright展开的方向
widthnumber250placement 为 left | right 时,抽屉的宽度
heightnumber250placement 为 top | bottom 时,抽屉的高度
radiusnumber0抽屉圆角
okTextstring确定底部确认按钮的文本
cancelTextstring取消底部取消按钮的文本
Slots
namedesc
default主体内容
title标题内容
footer底部内容
Emits
namedesc
update:visible显示状态变化触发
close点击取消按钮
ok点击确认按钮

图标 Icon

基本使用
<ml-icon :name="icon" :size="24" color="#808080" />
export default {
  id: '4118979',
  name: 'MeleonUI',
  font_family: 'ml-icon',
  css_prefix_text: 'ml-',
  description: '',
  glyphs: [
    {
      icon_id: '8106223',
      name: 'cancel',
      font_class: 'close--circle',
      unicode: 'e698',
      unicode_decimal: 59032
    },
    {
      icon_id: '8106241',
      name: 'information',
      font_class: 'info--circle',
      unicode: 'e6a5',
      unicode_decimal: 59045
    },
    {
      icon_id: '8106248',
      name: 'selection',
      font_class: 'selection--circle',
      unicode: 'e6a6',
      unicode_decimal: 59046
    },
    {
      icon_id: '11992738',
      name: 'github',
      font_class: 'github',
      unicode: 'e6a9',
      unicode_decimal: 59049
    },
    {
      icon_id: '18531280',
      name: 'right arrow',
      font_class: 'arrow-right--line',
      unicode: 'e701',
      unicode_decimal: 59137
    },
    {
      icon_id: '38175316',
      name: 'right arrow',
      font_class: 'arrow-left--line',
      unicode: 'e87f',
      unicode_decimal: 59519
    },
    {
      icon_id: '12865674',
      name: 'night',
      font_class: 'night',
      unicode: 'e6ef',
      unicode_decimal: 59119
    },
    {
      icon_id: '12865690',
      name: 'day',
      font_class: 'day',
      unicode: 'e6f1',
      unicode_decimal: 59121
    },
    {
      icon_id: '702307',
      name: 'drag',
      font_class: 'drag',
      unicode: 'e7d0',
      unicode_decimal: 59344
    },
    {
      icon_id: '11488125',
      name: 'seleted',
      font_class: 'selected',
      unicode: 'e763',
      unicode_decimal: 59235
    },
    {
      icon_id: '10678428',
      name: 'mirror light ctrl',
      font_class: 'filter',
      unicode: 'e6e0',
      unicode_decimal: 59104
    },
    {
      icon_id: '5772874',
      name: '复制',
      font_class: 'copy',
      unicode: 'e617',
      unicode_decimal: 58903
    },
    {
      icon_id: '4936963',
      name: 'CodeSandbox',
      font_class: 'code-sandbox',
      unicode: 'e87e',
      unicode_decimal: 59518
    },
    {
      icon_id: '8106210',
      name: 'bluetoothon',
      font_class: 'bluetoothon',
      unicode: 'e697',
      unicode_decimal: 59031
    },
    {
      icon_id: '8106293',
      name: 'wifi',
      font_class: 'wifi',
      unicode: 'e6a4',
      unicode_decimal: 59044
    },
    {
      icon_id: '10678426',
      name: 'message',
      font_class: 'message',
      unicode: 'e6df',
      unicode_decimal: 59103
    },
    {
      icon_id: '10678434',
      name: 'search',
      font_class: 'search',
      unicode: 'e6e1',
      unicode_decimal: 59105
    },
    {
      icon_id: '10678439',
      name: 'scan QR',
      font_class: 'scan',
      unicode: 'e6e2',
      unicode_decimal: 59106
    },
    {
      icon_id: '10678401',
      name: 'back',
      font_class: 'arrow-left',
      unicode: 'e6db',
      unicode_decimal: 59099
    },
    {
      icon_id: '8106272',
      name: 'next',
      font_class: 'arrow-right',
      unicode: 'e6a3',
      unicode_decimal: 59043
    },
    {
      icon_id: '8106251',
      name: 'increase',
      font_class: 'plus',
      unicode: 'e69f',
      unicode_decimal: 59039
    },
    {
      icon_id: '8106217',
      name: 'delete',
      font_class: 'delete',
      unicode: 'e699',
      unicode_decimal: 59033
    },
    {
      icon_id: '8106245',
      name: 'close',
      font_class: 'close',
      unicode: 'e69e',
      unicode_decimal: 59038
    },
    {
      icon_id: '10670577',
      name: 'address',
      font_class: 'address',
      unicode: 'e6a7',
      unicode_decimal: 59047
    },
    {
      icon_id: '12865660',
      name: 'connect device',
      font_class: 'connect',
      unicode: 'e6e7',
      unicode_decimal: 59111
    },
    {
      icon_id: '12865665',
      name: 'done work',
      font_class: 'donework',
      unicode: 'e6e9',
      unicode_decimal: 59113
    },
    {
      icon_id: '12865672',
      name: 'like',
      font_class: 'like',
      unicode: 'e6eb',
      unicode_decimal: 59115
    },
    {
      icon_id: '12865673',
      name: 'mark',
      font_class: 'mark',
      unicode: 'e6ec',
      unicode_decimal: 59116
    },
    {
      icon_id: '12865685',
      name: 'share',
      font_class: 'share',
      unicode: 'e6ee',
      unicode_decimal: 59118
    },
    {
      icon_id: '12865693',
      name: 'setting',
      font_class: 'setting',
      unicode: 'e6f0',
      unicode_decimal: 59120
    },
    {
      icon_id: '8106224',
      name: 'down',
      font_class: 'arrow-down',
      unicode: 'e69b',
      unicode_decimal: 59035
    },
    {
      icon_id: '8106260',
      name: 'upward',
      font_class: 'arrow-up',
      unicode: 'e6a1',
      unicode_decimal: 59041
    },
    {
      icon_id: '8106276',
      name: 'visible',
      font_class: 'eye-close',
      unicode: 'e6a2',
      unicode_decimal: 59042
    },
    {
      icon_id: '8106285',
      name: 'eye_protection',
      font_class: 'eye',
      unicode: 'e6a0',
      unicode_decimal: 59040
    }
  ]
}

图片 Image

基本使用
proptypedefaultdesc
hasNavbooleantrue当前页面是否有导航栏,会计算系统导航栏高度,预览区域下移一段距离
srcstring必填项图片的资源路径
modeImageModeEnumImageModeEnum.ASPECT_FIT图片的填充模式,可参照uniapp官方提供的 Image 组件的 mode 值
widthnumber100图片宽度
heightnumber100图片高度
toolsstringzoomIn,zoomOut,rotate,reset由这四种工具随意组合,【,】拼接而成的字符串
showPreviewbooleantrue是否允许点击图片后展示预览
showLoadingbooleanfalse是否展示加载中标识
showErrorbooleanfalse是否展示加载失败提示
Slots
namedesc
loading调整加载中提示
error覆盖加载失败提示
Emits
namedesc
loaded加载成功触发
error加载失败触发
click点击图片

输入框 Input

基本使用
<ml-input v-model:model-value="modelValue" placeholder="提示文字可自定义" />

<ml-input v-model:model-value="modelValue" :size="inputSize" />

<ml-input v-model:model-value="modelValue" type="password" />

<ml-input v-model:model-value="modelValue" disabled :size="inputSize" />

列表 List

基本使用

基础列表使用示例

<ml-list
    ref="listRef"
    v-model:error="error"
    :data="mockData"
    :loading="loading"
    :loading-text="'自定义的加载中文本...'"
    :finished="finished"
    :height="400"
    style="width: 100%"
    @load="handleLoad"
>
    <template #item="{ item }">
        <ml-cell
            :label="item.label"
            :description="item.description"
            :value="item.value"
            allow-edit
        />
    </template>
</ml-list>
import type { ListInstance, MessageInstance } from '@meleon/uni-ui'

const mockData = ref(
    new Array(20).fill(0).map((_, index) => {
        return {
            id: `id-${index}`,
            label: `标题${index}`,
            description: `描述${index}`,
            value: `值${index}`
        }
    })
)

const listRef = ref<ListInstance>()
const messageRef = ref<MessageInstance>()
const finished = ref(false)
const loading = ref(false)
const error = ref(true)
const handleLoad = () => {
    if (!messageRef.value) return
    if (mockData.value.length >= 60) {
        finished.value = true
    }

    if (finished.value) {
        messageRef.value.success({
            content: '所有数据加载完成',
            duration: 2000
        })
    } else {
        messageRef.value.primary({
            content: '触发 load 事件',
            duration: 2000
        })

        mockData.value = [
            ...mockData.value,
            ...new Array(20).fill(0).map((_, index) => {
                const idx = mockData.value.length + index
                return {
                    id: `id-${idx}`,
                    label: `标题${idx}`,
                    description: `描述${idx}`,
                    value: `值${idx}`
                }
            })
        ]
    }
}

onMounted(() => {
  if (listRef.value) listRef.value.scrollIntoView('id-10')
})

虚拟列表使用示例

区别于基础列表,虚拟列表不支持调用 load 加载新数据,使用时需要准备好完整的初始数据

默认情况下,页面上仅展示15条数据节点,可以通过传入 pageSize 自定义每页展示的数量

<ml-list :data="mockData" :height="400" virtual-list style="width: 100%">
    <template #virtual="{ data }">
        <ml-cell
            v-for="item in data"
            :key="item.id"
            :label="item.label"
            :description="item.description"
            :value="item.value"
            allow-edit
        ></ml-cell>
    </template>
</ml-list>
const mockVirtualData = ref(
    new Array(100).fill(0).map((_, index) => {
        return {
            id: `id-${index}`,
            label: `标题${index}`,
            description: `描述${index}`,
            value: `值${index}`
        }
    })
)
APIs
proptypedefaultdesc
dataWithId[][]列表数据,需要提供 id 字段用以定位等操作
heightnumber必填列表容器的高度
itemHeightnumber58列表项的高度,可控制提示文本的高度及滚动阈值
loadingbooleanfalse是否处于加载状态
loadingTextstring加载中...加载状态底部的提示文本
finishedbooleanfalse是否加载完成
finishedTextstring没有更多了加载完成时,底部的提示文本
errorbooleanfalse是否加载失败
errorTextstring加载失败,点击重试加载失败时,底部的提示文本【可点击,重新触发 load 事件】
virtualListbooleanfalse是否开启虚拟列表
pageSizenumber15虚拟列表中展示的数量
Slots
namedesc
loading加载中
error加载异常
finished加载完成
virtual虚拟列表
item普通列表的列表项
Methods
nametypedesc
scrollToTop() => void滚动到顶部
scrollIntoView(id: string | number | symbol) => void滚动到指定节点【仅支持普通列表】
Events
namedesc
update:error更新 error 属性
load列表滚动到底部触发

选择器 Select

基本使用
<ml-select v-model:modelValue="modelValue" multiple :max-tag-count="1">
    <ml-option value="1" label="选项1" />
    <ml-option value="2" label="选项2" />
    <ml-option value="3" label="选项3" />
</ml-select>

开关 Switch

基本使用
<ml-switch v-model="isActive"></ml-switch>

<ml-switch v-model="isActive" type="circle"></ml-switch>

<ml-switch v-model="isActive" type="line"></ml-switch>
APIs
proptypedefaultdesc
modelValuebooleanfalse是否开启
typecircle | square |linesquare开关类型
checkedColorstringvar(--info-color-7)激活状态颜色
uncheckedColorstringvar(--primary-color-6)未激活状态颜色
disabledbooleanfalse是否禁用
beforeSwitch(newVal: boolean) => boolean | Promise() => true切换前触发

表格 Table

基本使用
<ml-table
  :data="tableData"
  size="mini"
  stripe
  border
  :height="200"
  :loading="false"
  :refresher-enabled="true"
  :refresher-interval="2000"
  style="width: 100%"
  @row-click="onRowClick"
  @cell-click="onCellClick"
>
    <template #cell="{ column, row }">
        <block v-if="column.property === 'gender'">
            <ml-tag :model-value="row[column.property]" type="primary" size="mini"></ml-tag>
        </block>
        <block v-else-if="column.property === 'age'">
            <ml-count-to
                         :to="row[column.property]"
                         animation
                         :value-style="{ fontSize: '14px', color: 'var(--info-color-8)' }"
                         ></ml-count-to>
        </block>
        <text v-else>{{ column.property && row[column.property] }}</text>
    </template>
    <!-- 。。。这操作有点多余,后面改改 -->
    <ml-table-column type="index" fixed="left"></ml-table-column>
    <ml-table-column prop="name" label="姓名" fixed></ml-table-column>
    <ml-table-column prop="age" label="年龄"></ml-table-column>
    <ml-table-column prop="gender" label="性别"></ml-table-column>
</ml-table>

消息提示 Message

基本使用
<ml-message ref="messageRef" />
import type { MessageInstance, MessageOptions } from '@meleon/uni-ui'

const messageRef = ref<MessageInstance>()

const showMessage = (type: MessageOptions['type']) => {
    if (!messageRef.value || !type) return
    messageRef.value[type]({
      content: type + idx.value++,
      duration: 2000
    })
}

头部导航栏 Navigator

基本使用
<ml-navigator
  title="ml-navigator"
  title-color="#FFFFFF"
  has-back
  icon-color="#FFFFFF"
  background="#7A98B3"
/>
APIs
proptypedefaultdesc
backgroundstringvar(--primary-color-6)导航栏背景,支持纯色、渐变或图片
titlestring''导航栏标题
titleColorstring#FFFFFF标题颜色
titleStyleObject{}标题样式
hasBackbooleantrue是否有回退图标
iconColorstring#FFFFFF图标颜色
iconStyleObject{}图标样式
toolsArray[]图标列表
NavigatorToolEntity
proptypedesc
iconstring图标名
colorstring图标颜色
typereturn | navigator点击图标的事件的类型
deltanumber可选type = return 时,delta 表示回退的页面数
pathstring可选type = navigator 时,path 表示跳转的页面地址
Slots
namedesc
icon图标插槽
default主体内容插槽

时间轴 TimeLine

基本使用
<ml-timeline :reverse="reverseCheckedList[0] === 'reverse'">
    <ml-timeline-item>
        <template #label>
          <text>2023-09-08</text>
        </template>
        <view>The first milestone content</view>
    </ml-timeline-item>
    <ml-timeline-item>
        <template #label>
          <text>2023-09-09</text>
        </template>
        <view>
            <view>The second milestone</view>
            <view>The second milestone</view>
            <view>The second milestone</view>
        </view>
    </ml-timeline-item>
    <ml-timeline-item>
        <template #label>
          <text> 2023-09-25 </text>
        </template>
        <view>The third milestone </view>
    </ml-timeline-item>
</ml-timeline>

时间选择器 TimePicker

基本使用
<ml-time-picker v-model="value" style="width: 100%">
    <template #trigger>
        <ml-cell
            label="时间选择器"
            :value="value"
            style="width: 100%"
        ></ml-cell>
    </template>
</ml-time-picker>

进度条 Progress

基本使用
<ml-progress :percent="percent" status="success" />

<ml-progress :percent="templateMap[0].percent">
  <template #text="{ percent, decimal }">
    <text>进度 {{ (percent * 100).toFixed(decimal) }}%</text>
  </template>
</ml-progress>

<ml-progress :percent="percent" type="circle" :size="curSize" status="primary" />

标签页 Tabs

基本使用
<ml-tabs active="a">
    <ml-tab value="a" title="标签1" closable>内容1</ml-tab>
    <ml-tab value="b" title="标签2" disabled>内容2</ml-tab>
    <ml-tab value="c" title="标签3" disabled closable>内容3</ml-tab>
    <ml-tab value="d" title="标签4">内容4</ml-tab>
    <ml-tab value="e" title="标签5">内容5</ml-tab>
</ml-tabs>

标签 Tag

基本使用
<ml-tag model-value="标签2" type="primary" plain />

<ml-tag model-value="标签3" size="medium" />

<view>closeable: 添加 ml-close 图标,点击可触发 close 事件</view>
<ml-tag model-value="标签1" closable @close="hanldeTagClose" />

<view>editable: 点击后标签会切换成 input 输入框,可修改标签内容 </view>
<ml-tag model-value="标签2" checkable @click="hanldeTagClick" />

<view>checkable: 添加点击样式,触发 click 事件</view>
<ml-tag v-model:model-value="tagValue" editable />

树 Tree

基本使用
<ml-tree
  class="tree-wrapper"
  ref="treeRef"
  v-model:expanded-keys="expandedKeys"
  v-model:checked-keys="checkedKeys"
  v-model:selected-keys="selectedKeys"
  v-model:indeterminate-keys="indeterminateKeys"
  :data="treeData"
  checkable
  selectable
  multiple
  :auto-expand-parent="false"
  @check="handleCheck"
  @select="handleSelect"
  @expand="handleExpand"
></ml-tree>

<view class="btn-list">
    <ml-button type="primary" @click="handleExpandAll">
        {{ isExpandAll ? 'Close All' : 'Expand All' }}
    </ml-button>

    <ml-button type="primary" @click="handleCheckAll">
        {{ isCheckAll ? 'Unheck All' : 'Check All' }}
    </ml-button>

    <ml-button type="primary" @click="handleSelectAll">
        {{ isSelectAll ? 'Unselect All' : 'Select All' }}
    </ml-button>

    <ml-button type="primary" @click="handleExpandNode"> Expand Root </ml-button>

    <ml-button type="primary" @click="handleCheckNode"> Check Root </ml-button>

    <ml-button type="primary" @click="handleSelectNode"> Select Root </ml-button>
</view>
  import type {
    TreeDataEntity,
    TreeCheckPayload,
    TreeExpandPayload,
    TreeSelectPayload,
    TreeInstance
  } from '@meleon/uni-ui/index'

  const treeRef = ref<TreeInstance>()
  const rootKey = ref('0-0')
  const expandedKeys = ref<string[]>(['0-0-0'])
  const checkedKeys = ref<string[]>([])
  const selectedKeys = ref<string[]>([])
  const indeterminateKeys = ref<string[]>([])
  
  // 监听 tree 触发的事件
  const handleCheck = (val: string[], payload: TreeCheckPayload) => {
    console.log('onCheck', val, payload)
  }
  const handleExpand = (val: string[], payload: TreeExpandPayload) => {
    console.log('onExpand', val, payload)
  }
  const handleSelect = (val: string[], payload: TreeSelectPayload) => {
    console.log('onSelect', val, payload)
  }

  // 手动调用组件暴露的方法
  
  // 展开节点
  const isExpandAll = ref(false)
  const handleExpandAll = () => {
    if (!treeRef.value) return
    isExpandAll.value = !isExpandAll.value
    treeRef.value.expandAll(isExpandAll.value)
  }
  const handleExpandNode = () => {
    if (!treeRef.value) return
    treeRef.value.expandNode(rootKey.value, true)
  }

  // 选中节点复选框
  const isCheckAll = ref(false)
  const handleCheckAll = () => {
    if (!treeRef.value) return
    isCheckAll.value = !isCheckAll.value
    treeRef.value.checkAll(isCheckAll.value)
  }
  const handleCheckNode = () => {
    if (!treeRef.value) return
    treeRef.value.checkNode(rootKey.value, true)
  }

  // 选中节点
  const isSelectAll = ref(false)
  const handleSelectAll = () => {
    if (!treeRef.value) return
    isSelectAll.value = !isSelectAll.value
    treeRef.value.selectAll(isSelectAll.value)
  }
  const handleSelectNode = () => {
    if (!treeRef.value) return
    treeRef.value.selectNode(rootKey.value, true)
  }

  // 节点数据
  const treeData: TreeDataEntity[] = [
    {
      title: 'Trunk 0-0',
      key: '0-0',
      children: [
        {
          title: 'Branch 0-0-0',
          key: '0-0-0',
          disabled: false,
          children: [
            {
              title: 'Leaf',
              key: '0-0-0-0'
            },
            {
              title: 'Leaf',
              key: '0-0-0-1'
            }
          ]
        },
        {
          title: 'Branch 0-0-1',
          key: '0-0-1',
          children: [
            {
              title: 'Leaf',
              key: '0-0-1-0'
            }
          ]
        }
      ]
    }
  ]
APIs
proptypedefaultdesc
dataTreeDataEntity[]必填树形数据
checkablebooleanfalse是否显示复选框
checkedKeysstring[]undefined选中复选框的节点键值列表
defaultCheckedKeysstring[][]默认选中复选框的节点键值列表
indeterminateKeysstring[][]半选状态的节点键值列表
expandedKeysstring[]必填展开的节点键值列表
defaultExpandedKeysstring[][]默认展开的节点键值列表
autoExpandParentbooleantrue是否自动展开父级节点
selectablebooleanfalse是否支持点击文本选中
selectedKeysstring[]undefined选中的文本节点键值列表
defaultSelectedKeysstring[][]默认选中的文本节点键值列表
multiplebooleantrue点击文本节点的选择是否支持多选
Slots
namedescprop
title自定义文本节点内容title
Emits
namedescparams
update:expandedKeys更新 expandedKeys【v-model】expandedKeys: string[]
expand展开时触发1. expandedKeys: string[]2. { expanded: boolean node: TreeNodeEntity nodeData: TreeDataEntity}
update:selectedKeys更新 selectedKeys【v-model】selectedKeys: string[]
select点击文本节点时触发1. selectedKeys: string[]2. { selected: boolean node: TreeNodeEntity nodeData: TreeDataEntity}
update:checkedKeys更新 checkedKeys【v-model】checkedKeys: string[]
check点击节点复选框时触发1. checkedKeys: string[]2. { checked: boolean checkedKeys: string[] indeterminateKeys: string[] node: TreeNodeEntity nodeData: TreeDataEntity}
update:indeterminateKeys更新 indeterminateKeys【v-model】indeterminateKeys: string[]
Events
namedescparams
getExpandedNodes获取展开的节点() => TreeNodeEntity[]
expandNode展开指定的节点(key: string | string[], expand: boolean) => void
expandAll展开所有节点(expandAll: boolean = true) => void
getSelectedNodes获取选中的节点() => TreeNodeEntity[]
selectNode选择指定的节点(key: string | string[], selected: boolean) => void
selectAll选择所有节点(selectAll: boolean = true) => void
getCheckedNodes获取选中复选框的节点() => TreeNodeEntity[]
getIndeterminateNodes获取半选状态的节点() => TreeNodeEntity[]
checkNode选中指定节点的复选框(key: string | string[], checked: boolean) => void
checkAll选中所有节点的复选框(checkAll: boolean = true) => void

上传组件 Uploader

基本使用
<template>
    <ml-uploader
        ref="uploadRef"
        v-model:file-list="fileList"
        action="http://localhost:3000/api/file/upload"
        multiple
        show-file-list
        :disabled="false"
        :auto-upload="false"
        :on-change="handleOnChange"
        @delete="handleDelete"
    >
        <template #trigger>
          <ml-button type="primary">选择文件</ml-button>
        </template>
    </ml-uploader>

  <ml-button
    type="primary"
    status="success"
    @click="handleSubmit"
  >
        上传
  </ml-button>
</template>

<script lang="ts" setup>
    import type { FileItem, UploaderInstance } from '@meleon/uni-ui/ml-uploader'
    
    const fileList = ref<FileItem[]>([])
    const handleDelete = () => {
    console.log('a', fileList.value)
  }

  const handleOnChange = (files: FileItem[]) => {
    console.log('a', files)
  }

  const uploadRef = ref<UploaderInstance>()
  const handleSubmit = () => {
    if (!uploadRef.value) return
    uploadRef.value.submit()
  }
</script>
APIs
propstypedefaultdesc
actionstring | () => string''文件上传的地址
autoUploadbooleanfalse是否自动上传
fieldNamestringfile上传时文件对应的字段名
headersRecord<string, string>{}上传时携带的请求头
dataRecord<string, any>{}上传时 FromData 里其他的数据
fileListFileItem必填项展示的文件列表
multiplebooleanfalse是否支持同时选择多个文件
limitnumber9最多缓存的文件数量
previewSizenumber100预览区域尺寸
disabledbooleanfalse是否禁用
showFileListbooleanfalse是否展示文件列表
sourceTypeUploaderSourceTypeEnum''支持相机或相册,默认都支持
beforeUpload(files: FileItem[]) => boolean | Promise() => true上传前的钩子函数
beforeDelete(file: FileItem) => boolean | Promise() => true删除前的钩子函数
Types
FileItem
propdesc
path图片路径
id图片id
deletable是否可以被删除
UploaderSourceTypeEnum
enumdesc
ALBUMalbum
CAMERAcamera
Emits
namedesc
delete文件在缓存中被删除
uploaded文件上传成功
update:fileList文件列表更新
Methods
nametypedesc
submit() => void手动上传当前展示的所有文件
updateFile(id: string, file: FileItem) => void指定id,更新文件对象
1.2.0

9 months ago

1.1.13

10 months ago

1.1.12

10 months ago

1.1.11

12 months ago

1.1.10

12 months ago

1.1.9

12 months ago

1.1.8

12 months ago

1.1.7

12 months ago

1.1.6

12 months ago

1.1.5

12 months ago

1.1.4

12 months ago

1.1.3

12 months ago

1.1.2

12 months ago

1.1.1

12 months ago

1.1.0

12 months ago

1.0.1

1 year ago

1.0.0

1 year ago