Skip to content
主题色
灰色
夜间模式组件大小小(1)中(2)大(3)组件圆角
none
small
medium
large
full
组件缩放90%95%100%105%110%

在使用本组件库之前,你需要了解自定义元素的相关知识,可参考教程MDNVue,只需知道如何使用即可,无需了解如何创建

安装

目前只发布了 alpha 版本,提供以下库:

根据需要并安装对应的库

  • 如果只需要组件,样式完全自定义的话,直接安装@lun-web/components即可
  • 如果需要主题,只需安装@lun-web/theme
  • 在 React 中使用需额外安装@lun-web/react,使用其导出的组件

React 中使用

React 是目前流行 web 框架中唯一不支持customElement的,详情见Custom Elements Everywhere。在 React 18 及之前版本中使用自定义元素,只会将属性设置为 attribute,不会自动设置为元素的 property,也无法使用onXXX监听自定义元素的事件

React 19 即将支持customElement,但目前还处于实验阶段。本文档使用的是 React 19 RC,在文档的 React 代码中可正常使用自定义元素。

对于 React 19 之前的版本,我们需要手动封装一层。@lun-web/react@lun-web/components中的每个组件都封装成了 React 组件,在 useLayoutEffect 中将属性和事件绑定到元素上,使之能够正常工作。

tsx
import { LInput } from '@lun-web/react';

export default function () {
  return <LInput onUpdate={() => {}} />;
}

全量引入

js
import { GlobalStaticConfig, defineAllComponents } from '@lun-web/components';
import {
  importCommonTheme
  importAllColors,
  importAllP3Colors,
  importAllThemes
} from '@lun-web/theme';
// 如果使用了日期组件,则必须引入日期处理预设。内部提供了dayjs实现,但需要用户手动引入
import '@lun-web/core/date-dayjs';
// 如果你想要使用其他的日期处理库,可参考左侧“数字和日期处理预设”一栏

// 定义组件前设置想要更改的全局静态配置
GlobalStaticConfig.xx = xx;

// 引入所有的预设主题色
importAllColors(); // 如果需要自定义主题色请参考顶部导航栏中的“调色”一栏
// 如果需要P3广色域支持则调用如下函数,当支持的时候会使用display-p3
// importAllP3Colors();

// 引入所有预设主题
importAllThemes();

// 定义全部组件
defineAllComponents();
  • 全局静态配置需要在组件被使用前修改,但最好在定义组件前就统一修改,因为namespace在定义时就会使用
  • 全量引入的组件会使用全局静态配置中的namespace加上组件本身的名字作为命名,例如namespace默认为l,那么button组件的默认名字便是l-button。定义组件后你便可以在任何地方使用它们
  • 在 SSR 的情况下,为保证视觉效果,你需要自行向页面添加类似于下面的样式,在组件未定义时隐藏它们,以避免它们的子元素被渲染出来而造成闪烁
css
:not(:defined) {
  visibility: hidden;
}
/** or */
:not(:defined) {
  opacity: 0;
}

动态引入

js
import { autoDefine } from '@lun-web/components';
import { autoImportTheme } from '@lun-web/theme';

autoImportTheme();
autoDefine();

动态引入会自动检测页面上的元素并自动加载引入,动态引入无法 Tree Shaking,但会动态加载需要的脚本

自定义引入

js
import { defineButton } from '@lun-web/components';
import {
  importButtonBasicTheme,
  importButtonSurfaceTheme,
} from '@lun-web/theme';

每个组件都导出了单独的 define 函数,用于单独引入该组件,没有使用的组件最终不会被打包,每个组件的主题也单独提供了 import 函数。 组件的 define 函数可以单独对该组件以及它依赖的组件进行命名,而不是使用默认命名,例如

js
importButtonBasicTheme();
importButtonSurfaceTheme();
// 第二个参数用于给该组件依赖的组件自定义命名
defineButton('my-button', {
  spin: 'my-spin',
});

// 此后你便可以直接使用<my-button></my-button>和<my-spin></my-spin>了

主题的引入除了组件维度的单独引入,还可以根据类型直接全部引入

js
import {
  importCommonTheme, // 所有组件的公共样式
  importBasicTheme, // 所有组件的基础主题
  importSurfaceTheme,
  importOutlineTheme,
  importSoftTheme,
  importSolidTheme,
} from '@lun-web/theme';

自定义引入需要注意组件的引入顺序,这在 SSR 场景下尤为重要,最先使用的组件需要最先定义,例如你可能需要在其他组件定义前先调用defineThemeProviderdefineTeleportHolder(),有明显父子关系的组件也需要注意,例如formform-item

需要这么做的原因是,大部分组件都有继承关系,部分状态由父组件提供。在 SSR 场景下,页面上的元素已经存在,如果子组件先被定义,此时它无法探测到父组件(组件未被定义时是无效组件),等父组件再被定义时子组件也不会被更新,便会出现问题

TS 支持

组件库的组件本身具有完整的类型支持,针对不同的框架,目前提供了以下类型定义:

  • @lun-web/components/elements-types-vue: Vue template 以及 JSX 的组件类型
  • @lun-web/components/elements-types-react: React JSX 组件类型
  • @lun-web/components/elements-types-html: document.createElement 组件类型支持

你需要在 TS 配置文件中对应引入它们

需要注意的是,提供的类型文件是针对默认namespace,也就是l-button, l-input等以l开头的组件,如果你自定义了命名空间,可以仿造以下示例编写

ts
// Vue
import * as Vue from 'vue';
// Vue template
declare module 'vue' {
  interface GlobalComponents {
    LButton: Vue.DefineComponent<import('@lun-web/components').ButtonProps>;
  }
}
// Vue JSX
declare module 'vue/jsx-runtime' {
  namespace JSX {
    interface IntrinsicElements {
      'l-button': Vue.HTMLAttributes & Vue.ReservedProps & import('@lun-web/components').ButtonProps;
    }
  }
}

// React
import * as React from 'react';
declare module 'react/jsx-runtime' {
  namespace JSX {
    interface IntrinsicElements {
      'l-button': React.HTMLAttributes<HTMLElement> &
        React.RefAttributes<import('./index').iButton> &
        import('@lun-web/components').ButtonProps;
    }
  }
}

每个组件都有一个 class 和两个类型,注意区分

ts
import { Button, tButton, iButton } from '@lun-web/components';
Button; // 组件的class,这是值,不是类型,一般用不到
tButton; // 组件class的类型,相当于typeof Button
iButton; // 组件实例的类型,相当于InstanceType<tButton>,这是实际DOM元素的类型

当需要组件实例类型时,你可以像下面这样使用:

ts
import { iButton } from '@lun-web/components';
const button = document.querySelector('l-button') as iButton;
button.asyncHandler = () => console.log('');

const buttonRef = ref<iButton>();
const render = () => <l-button ref={buttonRef}></l-button>;

兼容性

至少需要兼容customElement, 考虑到以下特性版本要求不高, 若不支持你需要自行 polyfill 或不使用某些特性,CSS 不兼容可考虑使用全局配置stylePreprocessor处理或自行编写样式

当前用户代理信息

某些特性需要的版本较高, 但它们在内部有做兼容处理或替代方案, 渐进式增强能给用户带来更好的体验,详细信息如下

当前浏览器支持该特性 当前浏览器不支持该特性 无法检测

Javascript

Web API

CSS

某些特性无法或不好做兼容,但它们影响不大,不使用那些功能即可