1.2.0 • Published 10 months ago

@meleon/uni-ui v1.2.0

Weekly downloads
-
License
ISC
Repository
github
Last release
10 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

10 months ago

1.1.13

11 months ago

1.1.12

11 months ago

1.1.11

1 year ago

1.1.10

1 year ago

1.1.9

1 year ago

1.1.8

1 year ago

1.1.7

1 year ago

1.1.6

1 year ago

1.1.5

1 year ago

1.1.4

1 year ago

1.1.3

1 year ago

1.1.2

1 year ago

1.1.1

1 year ago

1.1.0

1 year ago

1.0.1

1 year ago

1.0.0

1 year ago