Skip to content
forked from handyui/handy-ui

UI Components Library for React Applications

License

Notifications You must be signed in to change notification settings

Akscom/handy-ui

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

handy-ui

handy-ui是一个基于React hook开发的组件库,兼容移动端,用于个人对前端技术和交互设计的学习与探索、及工作上的需求
仅供参考,暂时不建议在正式项目中使用

  • 基础组件

    • button 按钮
    • cell 单元格
    • icon 图标
    • popup 弹出层
    • toast 轻提示
    • menu 目录
    • image 图片
    • style 内置样式
  • 表单组件

    • field 输入框
    • radio 单选框
    • checkbox 复选框
    • picker 选择器
    • calendar 日历
    • datePicker 日期选择器
    • uploader 文件上传
    • rate 评分
    • stepper 进步器
    • switch 开关
    • searchBar 搜索栏
  • 反馈组件

    • Loading 加载
    • actionSheet 动作面板
    • dialog 弹出框
    • dropdownMenu 下拉菜单
  • 展示组件

    • carousel 轮播
    • skeleton 骨架屏
    • backToTop 返回顶部
    • drag 拖拽
    • imagePreview 图片预览
  • 导航组件

    • tabs 标签页
    • sidebar 侧边导航

组件实现思路

无缝轮播图

  1. 无缝轮播:当切换到最后一个轮播图时,如何悄无声息回到第一张 核心思想:
    1)把第一张图复制并push到最后一个位置,复制之前的最后一张图并unshift到第一个位置
    2)在div上绑定transitionend事件,用来监听CSS完成过渡后触发,
    2.1)当切换到最后一张图时,马上在回调事件上设置第一张(transform),把currentIndex设置为0
    2.2)当切换上一张,到达第一张时,马上在回调事件上设置回到最后一张,把current设置为length-1
<!--vant的思路:不额外创建dom,而是判断将要切换到第一张或最后一张时加transform--> 
<div style="width: 1440px; transition-duration: 500ms; transform: translateX(-1440px);">
    <div style="width: 360px; transform: translateX(1440px);">1</div>
    <div style="width: 360px;">2</div>
    <div style="width: 360px;">3</div>
    <div style="width: 360px;">4</div>
   <!-- 切换到第一张时
   <div class="van-swipe-item" style="width: 360px; transform: translateX(1440px);">4</div>
   --> 
</div>
  1. 自动播放
  2. 加手势切换

优化点:

  • 使用useMemo(记忆计算结果)和useCallback(记忆函数体)都会在组件第一次渲染的时候执行,之后会在其依赖的变量发生改变时再次执行;
  • 定时器中,使用setState的函数模式解决setState时数据不实时更新问题

骨架屏

可以用ui组件当作骨架屏,可以用[loader]或者plugin来实现

ui组件思路:用div作为占位符,相当于用图片代替

loader思路:
1)babylon解释器把代码字符串转化为AST树
2)babel-traverse对AST树进行解析遍历出整个树的path(在这里可以对代码进行改造)
3)plugin转换出新的AST树
4)输出新的代码字符串

plugin思路:
起个服务器访问页面,把内容抓下来转成骨架屏的元素,然后把改造的dom元素变成html内容,替换到 <div id ='root'><!--shell--></div>

使用:将loading属性设置成false表示内容加载完成,此时会隐藏占位图,并显示Skeleton的组件

参考

大文件上传

1)监听input file的change事件,获取到file对象<input type="file" @change="handleFileChange" />
2)把这个对象通过file.slice切割成chunk[0: {file: Blob} 1: {file: Blob}...]
3)使用spark-md5.js,给每个切片文件按顺序生成md5名称 (另开一个worker线程生成)
3)把每个chunk通过FormData上传到后台
3.1)上传前先请求校验,后台校验切片是否已经存在某个文件中(把hash和文件名传过去,判断文件中是否已有hash名),已存在返回false,为为存在返回true
3.2)new FormData()实例,把chunk和hash都append进去,提交上传请求,通过Promise.all并发请求
3.3)拿到请求返回的结果,计算 本次上传成功数量+之前上传的切片(暂停的情况) 是否等于 所有切换数量。
等于的话就发送合并请求,把切片合并一起,删除hash内存

const formData = new FormData()
formData.append('chunk', chunk) // Blob {size: 577542, type: ""}
formData.append('hash', hash)  // 5530cc512e2a3ab0652b300f0cd2224c-0 分片的hash名称 -1/-2/-3/-4 
formData.append('filename', state.container.file.name) // Web全栈工程师的自我修养.mobi
formData.append('fileHash', state.container.hash) // 5530cc512e2a3ab0652b300f0cd2224c hash名称

参考例子

图片压缩上传(在上传之前转换文件)

1)使用FileReader对象异步读取blob文件,将他转成base64
2)通过canvas元素使用一个2D上下文,drawImage绘制图片(传入图片/宽/高),通过canvas.toDataURL转化为base64(传入压缩质量,重点)
3)atob解析base64转换为byte,再用ArrayBuffer转为二进制
4)通过new File实例一个blob对象,append到FormData上,用于上传到服务器

// 核心代码
ctx.drawImage(img, 0, 0, 200, 200);
const imageDataURL = canvas.toDataURL(fileObj.type ||'image/jpeg', pictureQuality); 

About

UI Components Library for React Applications

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 56.9%
  • SCSS 39.1%
  • JavaScript 2.5%
  • HTML 1.5%