Component
组件相关库
monaco-editor-auto-typings ---> 自动生成导入包的类型
底层原理是使用 jsdelivr 的 CDN 服务,将包的类型文件缓存到本地,然后自动生成导入包的类型。
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
import { AutoTypings, LocalStorageCache } from 'monaco-editor-auto-typings';
const val = `
import React from 'react';
React.useEffect(0); // Type Error!
`;
// Create monaco editor instance
const editor = monaco.editor.create(document.getElementById('root')!, {
model: monaco.editor.createModel(val, 'typescript'),
});
// Initialize auto typing on monaco editor. Imports will now automatically be typed!
const autoTypings = await AutoTypings.create(editor, {
sourceCache: new LocalStorageCache(), // Cache loaded sources in localStorage. May be omitted
// Other options...
});dockview ---> dock 布局管理器
支持 Vue、React 或者原生 JS 的使用方式
<script setup lang="ts">
</script>
<template>
<div/>This is panel!</div>
</template>
<style scoped>
</style><script setup lang="ts">
</script>
<template>
<div/>This is TAB!</div>
</template>
<style scoped>
</style>import { createApp } from "vue";
import App from "./App.vue";
import Tab from "./Tab.vue";
import Panel from "./Panel.vue";
const vueApp = createApp(App);
vueApp.component("defaultTab", Tab);
vueApp.component("defaultPanel", Panel);
vueApp.mount("body");<script setup lang="ts">
import { DockviewReadyEvent, DockviewVue, themeVisualStudio } from "dockview-vue";
const onReady = (event: DockviewReadyEvent) => {
event.api.addPanel({
id: "panel_1",
component: "defaultPanel",
tabComponent: "defaultTab",
});
event.api.addPanel({
id: "panel_2",
component: "defaultPanel",
tabComponent: "defaultTab",
});
};
</script>vee-validate ---> 表单验证
在项目中不接入第三方 UI 组件库的时候,使用 vee-validate 是一个不错的选择,可以很轻松和灵活地验证表单内容
<script setup>
import { useForm } from 'vee-validate';
import * as yup from 'yup';
import CustomInput from './CustomInput.vue';
const { values, errors, defineField } = useForm({
validationSchema: yup.object({
email: yup.string().email().required(),
}),
});
const [email, emailProps] = defineField('email', {
validateOnModelUpdate: false,
});
</script>
<template>
<CustomInput v-model="email" v-bind="emailProps" />
<div>{{ errors.email }}</div>
<pre>values: {{ values }}</pre>
</template>inspira-ui ---> 非常酷炫的 UI 库
里面提供了非常多的、酷炫的组件,值得一看。使用 Vue + TailwindCSS 接入
number-flow ---> 数字滚动组件
支持 Vue、React、Svelte
import NumberFlow from '@number-flow/react'
<NumberFlow value={123} />chartist ---> 本地运行代码的沙箱组件
下面的案例来源:Lucide Icon
<script setup>
import { Sandpack } from 'sandpack-vue3'
import sandpackTheme from '../../.vitepress/theme/sandpackTheme.json'
import sizeIconExample from './examples/filled-icon-example/files.ts'
</script>
<template>
<Sandpack
template="react"
:theme="sandpackTheme"
:files="sizeIconExample"
:customSetup='{
dependencies: {
"lucide-react": "latest"
}
}'
:options="{
editorHeight: 480,
editorWidthPercentage: 60,
}"
/>
</template>专门用于 Vue3 的版本 jerrywu001/sandpack-vue3
chartist ---> 简单的响应式图表
import { BarChart } from 'chartist';
new BarChart('#chart', {
labels: ['W1', 'W2', 'W3', 'W4', 'W5', 'W6', 'W7', 'W8', 'W9', 'W10'],
series: [
[1, 2, 4, 8, 6, -2, -1, -4, -6, -2]
]
}, {
high: 10,
low: -10,
axisX: {
labelInterpolationFnc: (value, index) => (index % 2 === 0 ? value : null)
}
});sweetalert ---> alert组件
不依赖框架,使用方式很简单,直接调用即可
swal("Good job!", "You clicked the button!", "success");EditorJs ---> Block-style 编辑器
import EditorJS from '@editorjs/editorjs';
const editor = new EditorJS({
/**
* Id of Element that should contain Editor instance
*/
holder: 'editorjs'
});chakra UI ---> React组件库
accessible components library for React
$ npm i @chakra-ui/react @emotion/react @emotion/styled framer-motionmitosis ---> 通用组件
可以吧一种组件转为 Vue、React、Svelte、Qwik 等等组件,蛮有意思
import { useState } from "@builder.io/mitosis";
export default function MyComponent(props) {
const [name, setName] = useState("Steve");
return (
<div>
<input
css={{
color: "red",
}}
value={name}
onChange={(event) => setName(event.target.value)}
/>
Hello! I can run natively in React, Vue, Svelte, Qwik, and many more frameworks!
</div>
);
}
splide ---> 轮播图组件
功能丰富、灵活度高、支持多个框架
<template>
<Splide :options="{ rewind: true }" aria-label="My Favorite Images">
<SplideSlide>
<img src="image1.jpg" alt="Sample 1">
</SplideSlide>
<SplideSlide>
<img src="image2.jpg" alt="Sample 2">
</SplideSlide>
</Splide>
</template>tresjs ---> 通过写 Vue 的方式来写 threejs
const geometry = new THREE.TorusGeometry(1, 0.5, 16, 32)
const material = new THREE.MeshBasicMaterial({ color: 'orange' })
const donut = new THREE.Mesh(geometry, material)
scene.add(donut)
@formkit/auto-animate ---> drop in 动画
轻松为容器里面的元素添加动画过渡效果,参考这里
<script setup>
import { ref, onMounted } from "vue"
import autoAnimate from "@formkit/auto-animate"
const dropdown = ref() // we need a DOM node
const show = ref(false)
onMounted(() => {
autoAnimate(dropdown.value) // thats it!
})
</script>
<template>
<div ref="dropdown" class="dropdown">
<strong class="dropdown-label" @click="show = !show">
Click me to open!
</strong>
<p class="dropdown-content" v-if="show">Lorum ipsum...</p>
</div>
</template>react-admin ---> React Admin 框架
// in app.js
import * as React from "react";
import { render } from 'react-dom';
import { Admin, Resource } from 'react-admin';
import restProvider from 'ra-data-simple-rest';
import { PostList, PostEdit, PostCreate, PostIcon } from './posts';
render(
<Admin dataProvider={restProvider('http://localhost:3000')}>
<Resource name="posts" list={PostList} edit={PostEdit} create={PostCreate} icon={PostIcon} />
</Admin>,
document.getElementById('root')
);table ---> HeadLess 表格
支持 React、Svelte、Vue、Solid
import { useVueTable } from '@tanstack/vue-table'
function App() {
const table = useVueTable(options)
// ...render your table
}sortableJS ---> 拖拽排序
适用于现代浏览器和触摸设备的可重新排序的拖放列表
// Cherrypick extra plugins
import Sortable, { MultiDrag, Swap } from 'sortablejs';
Sortable.mount(new MultiDrag(), new Swap());
// Cherrypick default plugins
import Sortable, { AutoScroll } from 'sortablejs/modular/sortable.core.esm.js';
Sortable.mount(new AutoScroll());floating-ui ---> 创建一个浮动UI
例如 tooltips, popovers, dropdowns
import {computePosition} from '@floating-ui/dom';
const button = document.querySelector('#button');
const tooltip = document.querySelector('#tooltip');
computePosition(button, tooltip, {
placement: 'right',
}).then(({x, y}) => {
Object.assign(tooltip.style, {
left: `${x}px`,
top: `${y}px`,
});
});canvas-confetti ---> Canvas礼花特效
想为你的网站添加礼花特效?试试它~
var myCanvas = document.createElement('canvas');
document.body.appendChild(myCanvas);
var myConfetti = confetti.create(myCanvas, {
resize: true,
useWorker: true
});
myConfetti({
particleCount: 100,
spread: 160
// any other options from the global
// confetti function
});atropos ---> 令人惊叹的悬停视差效果
支持原生JS、Vue、React等
<!-- main Atropos container (required), add your custom class here -->
<div class="atropos my-atropos">
<!-- scale container (required) -->
<div class="atropos-scale">
<!-- rotate container (required) -->
<div class="atropos-rotate">
<!-- inner container (required) -->
<div class="atropos-inner">
<!-- put your custom content here -->
</div>
</div>
</div>
</div>
<script>
// import Atropos library
import Atropos from 'atropos';
// Initialize
const myAtropos = Atropos({
el: '.my-atropos',
// rest of parameters
});
</script>fullcalendar ---> 一个全尺寸的事件日历
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<link href='fullcalendar/main.css' rel='stylesheet' />
<script src='fullcalendar/main.js'></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth'
});
calendar.render();
});
</script>
</head>
<body>
<div id='calendar'></div>
</body>
</html>vue-draggable-plus ---> Drag and drop 组件
Vue2 & 3 组件
<template>
<VueDraggable ref="el" v-model="list">
<div v-for="item in list" :key="item.id">
{{ item.name }}
</div>
</VueDraggable>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { VueDraggable } from 'vue-draggable-plus'
const list = ref([
{
name: 'Joao',
id: 1
},
{
name: 'Jean',
id: 2
},
])
</script>tiptap ---> HeadLess 编辑器
支持多个框架
import { Editor } from '@tiptap/core'
import StarterKit from '@tiptap/starter-kit'
new Editor({
element: document.querySelector('.element'),
extensions: [
StarterKit,
],
content: '<p>Hello World!</p>',
})icoicons ---> Icon for Web component
- 易于使用
- SVG
- 自带懒加载
<script type="module" src="https://unpkg.com/ionicons@5.5.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule src="https://unpkg.com/ionicons@5.5.2/dist/ionicons/ionicons.js"></script>
<ion-icon name="heart"></ion-icon>lit ---> Web Component 框架
对于想尝试 web 组件的人,值得一试
import {LitElement, html} from 'lit';
import {customElement} from 'lit/decorators.js';
import './my-header.js';
import './my-article.js';
import './my-footer.js';
@customElement('my-page')
class MyPage extends LitElement {
render() {
return html`
<my-header></my-header>
<my-article></my-article>
<my-footer></my-footer>
`;
}
}HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="./my-page.js" type="module"></script>
<title>lit-element code sample</title>
</head>
<body>
<my-page></my-page>
</body>
</html>stencli ---> Web component 框架
Stencil 组件可以从一个与框架无关的代码库本地分发给 React、Angular、Vue 和传统 Web 开发人员
import { Component, Prop, h } from '@stencil/core';
@Component({
tag: 'my-component', // the name of the component's custom HTML tag
styleUrl: 'my-component.css', // css styles to apply to the component
shadow: true, // this component uses the ShadowDOM
})
export class MyComponent {
// The component accepts two arguments:
@Prop() first: string;
@Prop() last: string;
//The following HTML is rendered when our component is used
render() {
return (
<div>
Hello, my name is {this.first} {this.last}
</div>
);
}
}HyperUI ---> Tailwind CSS 组件
Provide some presets, And we can change them easily
<!-- bottom -->
<a
class="inline-block rounded border border-indigo-600 bg-indigo-600 px-12 py-3 text-sm font-medium text-white hover:bg-transparent hover:text-indigo-600 focus:outline-none focus:ring active:text-indigo-500"
href="/download"
>
Download
</a>ag-grid ---> Table data
The best JavaScript Data Table for building Enterprise Applications. Supports React / Angular / Vue / Plain JavaScript.
<template>
<ag-grid-vue
style="width: 500px; height: 200px"
class="ag-theme-alpine"
:columnDefs="columnDefs"
:rowData="rowData"
>
</ag-grid-vue>
</template>svg-captcha ---> 验证码生成
var svgCaptcha = require('svg-captcha');
var captcha = svgCaptcha.create();
console.log(captcha);
// {data: '<svg.../svg>', text: 'abcd'}vditor ---> editor for Markdown
import Vditor from 'vditor'
import "~vditor/src/assets/less/index"
const vditor = new Vditor(id, {options...})countupJs ---> Animates a numerical value
const countUp = new CountUp('targetId', 5234);
if (!countUp.error) {
countUp.start();
} else {
console.error(countUp.error);
}unpic-img ---> image component
- Automatically generates correct srcset and size attributes for responsive images.
- Uses native lazy loading and async decoding for offscreen images.
- Uses eager loading and high priority fetching for important images.
- ...
<script setup lang="ts">
import { Image } from "@unpic/vue";
</script>
<template>
<Image
src="https://cdn.shopify.com/static/sample-images/bath_grande_crop_center.jpeg"
layout="constrained"
width="800"
height="600"
alt="A lovely bath"
/>
</template>Radix-ui ---> 交互体验极佳的react的UI框架
支持键盘导航、焦点管理、屏幕阅读器测试。支持鼠标右键下拉菜单,原生推荐单组件使用:
$ npm install @radix-ui/react-context-menu
$ npm install @radix-ui/react-hover-cardtilg ---> 一个调试React组件的钩子
会在控制太打印出相关的信息,包括props、children、lifecycle等。
import useTilg from 'tilg'
function MyButton() {
useTilg()
return <button>Click me</button>
}slate ---> 编辑器框架
A completely customizable framework for building rich text editors. (Currently in beta.)
// Import React dependencies.
import React, { useState } from 'react'
// Import the Slate editor factory.
import { createEditor } from 'slate'
// Import the Slate components and React plugin.
import { Slate, Editable, withReact } from 'slate-react'
const initialValue = [
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]
const App = () => {
const [editor] = useState(() => withReact(createEditor()))
// Render the Slate context.
return <Slate editor={editor} initialValue={initialValue} />
}