ranui
基于 Web Components
开发方案
Feature 特点
- 高度跨框架兼容: 能够轻松适配多种主流前端框架,包括
React
、Vue
、Preact
、SolidJS
、Svelte
等,甚至任何基于JavaScript
并遵循W3C
标准的项目也能无缝集成。无论您的技术栈如何选择,我们都能提供稳定且一致的支持。 - 原生纯粹的体验: 无需依赖
npm
、React/Vue
等前端框架,也无需webpack/vite
等复杂的构建工具,真正回归Web
技术的最本质。您可以像操作原生div
标签一样轻松上手,即刻感受技术的纯粹与直观。这样的设计不仅简化了项目的结构,更降低了学习和使用的成本,让每一个开发者都能体验到Web
技术的原生魅力。 - 极致模块化设计: 采用最小模块化原则,将庞大复杂的系统或应用程序精心拆解为尺寸极小、功能独立且易于复用的组件单元。有助于提高代码的可维护性、可扩展性和可重用性
- 全面开源自由学习: 项目完全遵循
MIT
开源协议,所有源代码毫无保留地对外开放。这意味着可以自由地访问、学习、参考甚至修改我们的代码,无论是为了个人提升还是商业应用,我们都为您提供了一个开放、透明的平台。坚信,开源是促进技术进步和创新的重要途径。 - 交互式丰富文档: 提供详尽且互动性强的文档,其中所有组件实例均可进行实时交互,让您在阅读的同时能够直接体验组件功能,加深理解并快速上手。这样的设计旨在为您提供最直观、最高效的学习体验。
- 支持类型校验: 开发环境完全基于
TypeScript
构建,配备了完整的声明文件和类型定义,确保无论是JavaScript
还是TypeScript
项目都能得到顺畅的集成。通过强大的类型检查功能,我们极大地提升了代码的可读性、可维护性,以及项目的稳健性,为开发工作带来前所未有的便捷与安心。 - 更加持久和稳定:具备出色的稳定性,无需担忧类似于
React
从15
版升级到16
版(fiber
),或Vue
从2
版升级到3
版时(hooks
)可能遭遇的破坏性更新问题。我们确保您的组件不会因此被迫进行不必要的更新或重新开发,从而避免了潜在的项目中断和额外工作量。意味着选择了持续、无忧的项目运行。
Situation 项目情况
Usage 使用
大多数情况都可以像原生的 div
标签一样使用。
接下来是一些使用例子
html
js
jsx
vue
tsx
1.html
<script src="./ranui/dist/umd/index.umd.cjs"></script>
<body>
<r-button>Button</r-button>
</body>
2.js
import 'ranui';
const Button = document.createElement('r-button');
Button.appendChild('this is button text');
document.body.appendChild(Button);
3.jsx
由于react
有合成事件,为了更加方便的使用,通过react
高阶组件进行封装ranui,输出了@ranui/react
在react
中,使用@ranui/react会更加丝滑,通过高阶函数包裹后,与react
生态系统完全融合。
然而,ranui仍然可以在任何js
或者ts
中使用。
import 'ranui';
const App = () => {
return (
<>
<r-button>Button</r-button>
</>
);
};
4.vue
<template>
<r-button>Button</r-button>
</template>
<script>
import 'ranui';
</script>
5.tsx
由于react
有合成事件,为了更加方便的使用,通过react
高阶组件进行封装ranui,于是有了@ranui/react
在react
中,使用@ranui/react会更加丝滑,通过高阶函数包裹后,与react
生态系统完全融合。
然而,ranui仍然可以在任何js
或者ts
中使用。
// react 18
import type { SyntheticEvent } from 'react';
import React, { useRef } from 'react';
import 'ranui';
const FilePreview = () => {
const ref = useRef<HTMLDivElement | null>(null);
const uploadFile = (e: SyntheticEvent<HTMLDivElement>) => {
if (ref.current) {
const uploadFile = document.createElement('input');
uploadFile.setAttribute('type', 'file');
uploadFile.click();
uploadFile.onchange = (e) => {
const { files = [] } = uploadFile;
if (files && files?.length > 0 && ref.current) {
ref.current.setAttribute('src', '');
const file = files[0];
const url = URL.createObjectURL(file);
ref.current.setAttribute('src', url);
}
};
}
};
return (
<div>
<r-preview ref={ref}></r-preview>
<r-button type="primary" onClick={uploadFile}>
choose file to preview
</r-button>
</div>
);
};
jsx
在TypeScript
中定义了所有html
原生组件的类型。web component
类型不在jsx
定义中。需要手动添加。否则会有类型问题,但它实际上是有效的。
// typings.d.ts
interface RButton {
type?: string;
onClick?: React.MouseEventHandler<HTMLDivElement> | undefined;
}
interface RPreview {
src?: string | Blob | ArrayBuffer;
onClick?: React.MouseEventHandler<HTMLDivElement> | undefined;
ref?: React.MutableRefObject<HTMLDivElement | null>;
}
declare namespace JSX {
interface IntrinsicElements {
'r-preview': React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> & RPreview;
'r-button': React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> & RButton;
}
}
Import 导入方式
支持按需引入
import 'ranui/button';
对于一些全局展示的组件,比如 preview
和 message
,需要加载一些额外的样式
import 'ranui/preview';
import 'ranui/style';
也可以全局导入,更加方便,这样什么都不用考虑了,梭哈完事。
ES module
import 'ranui';
UMD
,IIFE
,CJS
<script src="./ranui/dist/umd/index.umd.cjs"></script>
Overview 组件总览
Button
Icon
Skeleton
Input
message
Tab
Radar
Progress
Player
Select
Event 事件
react
@ranui/react 是由react
高阶函数封装ranui而成,Event
事件遵循react
事件规范。跟W3C
标准略有不同。
- 现代
web
标准
在W3C
标准中,你可以使用on
属性在HTML
元素上定义事件处理程序。但这是旧的事件处理程序的方法。
现代的web
开发推荐使用addEventListener
方法。
<r-button id="button">按钮</r-button>
<script>
const button = document.getElementById('button');
button.addEventListener('click', function (event) {
alert('新的点击事件!');
});
</script>
然而,如果你确实需要使用on
属性,下面是一个示例:
<r-input onchange="change(this.value)"></r-input>
<script>
function change(e) {
console.log('e--->', e);
}
</script>
请注意,使用on
属性来定义事件处理程序有一些限制和缺点。
例如,你不能使用事件捕获或事件委托,而且每个事件类型都需要一个单独的属性。
这也是为什么现代的web
开发推荐使用addEventListener
方法的原因。
还可以使用property
的方式:
<r-input id="input"></r-input>
<script>
const input = document.getElementById("input")
input.onchange = (e) {
console.log('e--->', e)
}
</script>
style 自定义样式
::part
伪类
<r-input id="input"></r-input>
<style>
/* #input 指的是当前的自定义元素
::part(input) 中的input指的是,当前自定义元素内部的 Shadow DOM 元素的类 */
#input::part(input) {
width: 100px;
}
</style>
具体的伪类名称可以查看具体的具体介绍
通过sheet
属性传入
会在所有的组件上加一个sheet
属性,传入CSSStyleSheet
字符串。会直接插入到Shadow DOM
中
css3
变量var
通过给组件设置css3
变量,从而自定义组件内部的指定样式,比如:
<r-progress percent="0.7" type="drag"></r-progress>
<r-progress
percent="0.70"
type="drag"
style="--ran-progress-wrap:linear-gradient(to right, #ff0000, #ffff00, #00ff00, #00ffff, #0000ff, #ff00ff, #ff0000);"
></r-progress>
具体css3
变量名称可以参考每个组件的介绍和说明
Compatibility 兼容性
- 不支持
IE
,其他均有较好支持
Contributors 贡献者
Other 相关资源
- 优秀的组件设计
- 在线生成 CSS 渐变色
- 优秀设计作品,有 psd 和 sketch
- 3D UI 设计,类似于 3D 版的 figma
- 设计规范
- 优秀设计作品
- element UI 中文网
- Ant design 中文网
- 在线绘制 CSS 动画
- tailwindcss 组件库
- animate css 非常优秀的 css 动画
- can i use 检测兼容性 API 网站
- figma