comfy-tool
v1.0.6
Published
A lightweight Vue 3 framework designed to streamline development and seamlessly integrate with other UI libraries, helping developers build applications faster and more efficiently.
Readme
comfy-tool
一个Vue项目的辅助工具库及常用工具函数
✨ 特性
- 🔹 轻量
- 🔹 简单使用
- 🔹 辅助工具
📦 安装
# 使用 npm
npm install comfy-tool
# 使用 yarn
yarn add comfy-tool
# 使用 pnpm
pnpm add comfy-tool<!-- 浏览器(CDN/直接引入) -->
<script src="https://unpkg.com/comfy-tool/style.css"></script>
<script src="https://unpkg.com/comfy-tool/dist/index.min.js"></script>
<script>
console.log(ComfyTool);
</script>🚀 快速开始
导入
- ESM
只导入工具函数(无需安装直接使用)import 'comfy-tool/style.css'; import { useComfyTool } from 'comfy-tool';import * as ComfyTool from 'comfy-tool/utils'; // 或 导入单个工具函数,如:对象合并merge import { merge } from 'comfy-tool/utils'; - CommonJS
require('comfy-tool/style.css'); const { useComfyTool } = require("comfy-tool");
- ESM
安装组件
- 方式一:
const app = createApp(App); useComfyTool(app) - 方式二:
import ComfyTool from 'comfy-tool'; createApp(App).use(ComfyTool);
- 方式一:
⚡ 功能预览
// 常规使用
import { ComfyTool, useComfyTool, configComfyTool, resourceLoader, version } from 'comfy-tool';
// 这种导入方式一般只由于安装(参考上述方式二)
import ComfyTool from 'comfy-tool';导出项介绍
| 项目名 | 描述 | |:-------:|:-------| | ComfyTool | 一个工具函数的合集 | | useComfyTool | 用于安装ComfyTool的vue组件及指令等 | | configComfyTool | 用于配置ComfyTool | | resourceLoader | 动态加载第三方资源css、js | | version | 版本号 |
import _Util from 'your-utils'; //这是你自己项目的工具库
import { ComfyTool } from 'comfy-tool';
// 合并工具库
export const Util = {
...ComfyTool, // ComfyTool放在前面,降低优先级
..._Util, // _Util放在后面,增加优先级,可以用相同的函数名重写ComfyTool中的函数
}扩展组件 (以Element-Plus为例)
1. <expanded>
自动填充剩余空间,与 flexbox 的 flex:1 一样
<el-row style="width:240px">
<el-col :span="6">60px</el-col>
<el-col :span="8">80px</el-col>
<expanded>100px</expanded>
</el-row>用 flex="-" 可以定义尺寸,不然设置了width、height都会无效。
<!-- 使用 flex="-" 可以定义尺寸 -->
<el-row style="width:240px">
<expanded flex="-" :width="60">60px</expanded>
<expanded>90px</expanded>
<expanded>90px</expanded>
</el-row>...待续
2. <row> 与 <colmun>
这两个组件差不多,只是一个是水平排布,一个是垂直排布。只说其中一个。
<row> 与 <el-row> 不一样,<row> 是用于创造一个滚动区域,并且方便在滚动区域前后添加无需滚动的内容,而不用调整父容器以及滚动区域。
<!-- 使用 flex="-" 可以定义尺寸 -->
<div style="width:240px">
<!-- 宽度默认100% -->
<row>
<temlate #before>
这是放在前面的内容
</template>
<div>大量内容......(假设出现横向滚动条)</div>
<temlate #after>
这是放在后面的内容
</template>
</row>
</div>
<!-- colmun也一样 -->
<div style="height:240px">
<!-- 高度默认100% -->
<colmun>
<temlate #before>
这是放在前面的内容
</template>
<div>大量内容......(假设出现纵向滚动条)</div>
<temlate #after>
这是放在后面的内容
</template>
</colmun>
</div>扩展功能
1. Layer
主要用于辅助二次封装弹层,并非直接使用的
使用方式
import { Layer } from 'comfy-tool'; import { Dialog } from 'vant' import HelloWorld from '@/components/HelloWorld.vue' function openElDialog(){ // 返回的实例全局默认只有一个,不想重新渲染可以创建实例Layer.create 然后手动$layer.open({...}) const $layer = Layer({ // 弹层容器组件用vant的Dialog为例,也可以用任何其他的组件,自定义的也行 baseContent:ElDialog, // 这是传给Dialog的属性 baseContentProps:{ title:'弹层标题', // Q:为什么要用vant的Dialog做示例,而不用ElDialog呢? // A:Layer工具是操作弹层组件的开/关,是由show属性来控制的 // 而element-plus的ElDialog控制开/关的属性却是modelValue,需要二次封装暴露出一个show属性才能正常使用 // 个人习惯将控制组件显示/隐藏都用show属性,对vant的API设计更加青睐 show:true // element-plus的ElDialog控制开/关的属性是modelValue // modelValue:true // 更多配置 ... }, // 传给Dialog的属性,其实也能写在baseContentProps中 style:{ zIndex: 99 }, // 这可以理解为你需要弹层弹出的内容,一般就是业务组件,传给Dialog的默认插槽 content:HelloWorld, // 传给HelloWorld的属性 contentProps:{ content:'Hello World' }, }) }// appLayer.ts import { Util } from "@/utils"; import { ElDialog } from "element-plus"; import AppDialog from "@/components/public/common/AppDialog.vue"; import { Layer } from "comfy-tool"; import type { LayerComponent, LayerComponentProps, LayerInstance as _LayerInstance, LayerOptions } from "comfy-tool"; import type { DialogProps } from "element-plus"; export type LayerInstance<T, C extends LayerComponent> = _LayerInstance<T, C, typeof ElDialog>; function _Layer<T, C extends LayerComponent=any>(options:{ content:C, contentProps:LayerComponentProps<C> }&RequiredOf<LayerOptions<T, C, typeof AppDialog>, 'content'>&Partial<DialogProps>){ return Layer<T, C, typeof AppDialog>({ ...options, baseContent: AppDialog, baseContentProps: { ...Util.pickEx(options, ['content', 'contentProps', 'baseContent', 'baseContentProps']), show: true, ...options.baseContentProps, } }) } _Layer.create = function <T, C extends LayerComponent=any>(options:Partial<{ content:C, contentProps:LayerComponentProps<C> }&LayerOptions<T, C, typeof AppDialog>&DialogProps>){ return Layer.create<T, C, typeof AppDialog>({ ...options, baseContent: AppDialog, baseContentProps: { ...Util.pickEx(options, ['content', 'contentProps', 'baseContent', 'baseContentProps']), show: true, ...options.baseContentProps, } } as any) } _Layer.close = Layer.close export const AppLayer = _Layer;在业务中你需要对函数进行封装,可以达到以下使用效果
// 假设已经封装好了 import AppLayer from '@/utils/appLayer'; import HelloWorld from '@/components/HelloWorld.vue' // 常用示例 // 示例一 AppLayer<string>({ content:HelloWorld, contentProps:{ taskId:'123' }, }).then((res)=>{ console.log(res); // 这是HelloWorld组件中回传的数据 }).catch((action)=>{ console.log(action); }) // 示例二 // 先创建实例 const $layer1 = AppLayer.create<string>({ content:HelloWorld, onConfirm(res, close){ console.log(res); // 这是HelloWorld组件中回传的数据 } }, true); //创建新示例 // 按需打开 $layer1.open({ contentProps:{ taskId:'123' } }) // 按需关闭 $layer1.close()回调的形式与promise的形式的区别。(只能使用一种回调,都写的话只在回调生效)
// 较完整示例 AppLayer<string>({ // 业务组件 content:HelloWorld, // 传给HelloWorld的属性 contentProps:{ content:'Hello World' }, // 回调的形式可以控制弹层关闭,默认也会自动关闭,return true 则不会自动关闭 onConfirm(res, close){ // res:string console.log(res); // 这是HelloWorld组件中回传的数据 setTimeout(()=>{ close();// 手动关闭弹层 }, 3000) return true; }, onClose(action: "complete" | "cancel" ){ console.log(action); } }).then((res)=>{ // promise的形式:返回结果后立即关闭 console.log(res); // 这是HelloWorld组件中回传的数据 }).catch((action)=>{ console.log(action); })- 继续封装成Hooks
// use-hello-world-Layer.ts let $layer:LayerInstance<string, typeof HelloWorld, typeof ElDialog>; // 单独实例 export function useHelloWorldLayer(){ function open(props: {title:string}={title:'测试'}){ if (!$layer) { $layer = AppLayer.create<string>({ content: HelloWorld }) } return new Promise<string>((resolve, reject) => { $layer.open({ contentProps: props, onConfirm(data){ // type:string console.log('confirm:',data) resolve() }, onClose(action){ console.log('close:',action) reject() } }) }).then(res => { console.log('res:',res) }) } function close(){ $layer?.close() } return { open, close } }使用
const HelloWorldLayer = useHelloWorldLayer(); HelloWorldLayer.open({title:'Hello World'});
...
扩展指令
...
扩展样式
扩展的样式类 Tailwind 的原子类工具库
先看看几个简单的示例
<!-- flex横向布局 -->
<div class="u-flex-row"></div>
<!-- flex纵向布局 -->
<div class="u-flex-col"></div>
<!-- 字体大小16px -->
<div class="u-text-s-16"></div>
<!-- 文字居中对齐 -->
<div class="u-text-a-c"></div>
<!-- 外边距 -->
<!-- margin: 10px -->
<div class="u-m-10"></div>
<!-- margin: 0 10px -->
<div class="u-m-x-10"></div>
<!-- margin: 10px 0 -->
<div class="u-m-y-10"></div>
<!-- margin-top: 10px -->
<div class="u-m-t-10"></div>
<!-- 内边距(与外边距用法一致) -->
<!-- padding: 10px -->
<div class="u-p-10"></div>
...1.flex布局
|类名|描述|代码解析| |:--:|:--:|:--:| |u-flex/u-flex-row|横向布局|| |u-flex-row-r|横向布局(反向)|| |u-flex-col|纵向布局|| |u-flex-col-r|纵向布局(反向)|| |u-flex-center|内容居中|| |u-flex u-flex-h-c|主轴居中|| |u-flex u-flex-v-c|交叉轴居中|| |...|||
2.内外边距
优先级遵循 u-m-l/r/t/b-* > u-m-x/y-* > u-m-*
只打算做部分常用的css扩展,所以不是一个全面的样式库
