前言:为什么Uploader这么重要?
各位前端小伙伴,有没有想过为什么上传组件这么重要?因为它就像前端界的瑞士军刀------看似简单,实则集成了多种核心技术!今天我们就来解剖WEUI的Uploader组件
一、HTML结构:BEM命名法的艺术
先看下面的的骨架结构,这可不是普通的div套娃:
xml
<div class="page">
<header class="page__hd">
<h1 class="page__title">Uploader</h1>
<p class="page__desc">上传组件,支持图片上传、文件上传、视频上传等</p>
</header>
<main class="page__bd">
<div class="weui-cells weui-cells_form">
<div class="weui-cell weui-cell_uploader">
<div class="weui-cell__bd">
<div class="weui-uploader">
<!-- 上传区域 -->
</div>
</div>
</div>
</div>
</main>
</div>
BEM命名法解析(前端命名界的"摩斯密码")
- Block(块) :独立实体,如
.page
,.weui-cell
- Element(元素) :块的组成部分,用
__
连接,如.page__hd
- Modifier(修饰符) :表示状态,用
_
连接,如.weui-cell_uploader
这种命名法就像给每个元素发身份证,看到类名就知道家族关系:
.page__title
:我是page块的title元素.weui-cell_uploader
:我是weui-cell块的上传版本
大家想了解更多关于BEM命名规范可以看看我的这篇文章 从零开始学 WEUI:用 BEM 命名规范打造优雅的微信前端 UI 相信看完,你会对BEM命名规范有一个深刻的理解
二、CSS魔法:那些精妙的实现技巧
1. 全屏布局的奥义
css
.page {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
background-color:green;
box-sizing: border-box;
/* 相当于人体工学椅------全方位包裹 */
}
简单地就能实现我们真正的布局整个页面

这个经典的四方位归零布局,就像给页面穿上紧身衣------完美贴合屏幕!
box-sizing: border-box; 要想真正,box-sizing: border-box
也是缺一不可,我们需要把盒子设置喂怪异盒模型,这样border和padding就不会影响我们的盒子,只需要关注margin
2. 滚动优化:丝般顺滑的秘诀
css
overflow: scroll;
-webkit-overflow-scrolling: touch; /* 移动端的润滑剂 */
这个-webkit
前缀就像浏览器的"特别通行证"------告诉移动端浏览器:"请开启丝滑滚动模式!" 是chrome 浏览器内核的代号
其实还处于实验阶段,会出现不兼容的现象,但是也不用太担心,因为我们的ios和安卓都是支持的
3. 1px边框的障眼法
css
.weui-cells::before {
content: "";
position: absolute;
height: 1px;
background-color: rgba(0,0,0,0.1);
}
设计师要1px细线?伪元素来救场!用RGBA透明度模拟物理像素,比直接写border优雅多了。
伪元素就像CSS的"影分身之术",不需要修改HTML结构就能创建视觉元素。它们出现在DOM树中却不增加实际标签,完美符合"结构-样式-行为"分离的原则。
温馨小提示
伪元素里面的content属性是必填的,可以为空,但不能没有
大家可以看看我写的这篇文章,是关于伪元素的,看完相信你会有所收获的
4. 弹性布局:垂直居中的魔法
css
.weui-cell {
display: flex;
align-items: center; /* 垂直居中不求人 */
}
Flex布局就是前端界的"万金油"------妈妈再也不用担心我的垂直居中了!
我之前写的文章也提到过关于居中
两种经典居中方式:
方法一:负边距法(需知道尺寸)
css
.more {
position: absolute;
top: 50%;
left: 50%;
margin-left: -25px; /* 盒子宽度一半 */
margin-top: -25px; /* 盒子高度一半 */
}
<div class="more"></div>
方法二:变形平移法(更现代)
css
.more {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* 自动计算偏移 */
}
也是一样的效果
就像在房间里挂画:第一种需要精确测量画框尺寸;第二种只需说"挂到墙中心",智能又省心!
三、Stylus:CSS的超进化形态
看看common.styl
如何施展魔法:
1. 变量:主题色的"变脸术"
bash
$weui-bg-0 = #ededed
$weui-fg-1 = rgba(0,0,0,0.55)
.page
background-color $weui-bg-0
.page__desc
color $weui-fg-1
定义变量就像给颜色取外号------一次定义,到处使用,换肤只需改一处!
2. 嵌套:选择器的"俄罗斯套娃"
css
.weui-uploader
.weui-uploader__hd
display flex
.weui-uploader__title
flex 1
嵌套写法比传统CSS简洁50%!视觉上直接反映HTML结构层次,再也不用在茫茫CSS海中捞针了。
3. 省略的艺术
css
/* 传统CSS */
.weui-cell {
padding: 16px;
}
/* Stylus版 */
.weui-cell
padding 16px
Stylus允许省略冒号和分号,代码精简得像诗人写俳句!
stylus的css是不是就像JS里面封装的概念,还具有变量的概念,是不是从所未有二点体验
四、上传区域:Float布局的文艺复兴
HTML结构
xml
<div class="weui-uploader">
<div class="weui-uploader__hd">
<p class="weui-uploader__title">图片上传</p>
<div class="weui-uploader__info">
<span>0</span> / <span>2</span>
</div>
</div>
<div class="weui-uploader__bd">
<ul class="weui-uploader__files">
<li class="weui-uploader__file"></li>
<li class="weui-uploader__file"></li>
<li class="weui-uploader__file"></li>
</ul>
</div>
</div>
CSS魔法
css
.weui-uploader__bd {
margin-bottom: -8px;
margin-right: -8px;
overflow: hidden; /* 触发BFC结界 */
}
.weui-uploader__file {
float: left;
margin-right: 8px;
margin-bottom: 8px;
width: 96px;
height: 96px;
background: url("https://weui.io/images/pic_160.png") no-repeat 50%;
background-size: cover; /* 图片自适应填充 */
}
Float布局的妙处
- 负边距抵消:用负margin吃掉最后一个元素的间距
- BFC结界 :
overflow:hidden
防止父容器高度塌陷 - 等宽高正方形:固定宽高+background-size:cover保持比例
哈哈哈,感觉float就像前端界的老兵一样,大家都快遗忘了,现在大家用定位和flex弹性布局居多,但是我想说,我们float还能打
五、从源码中学到的设计哲学
1. 组件化思维
WEUI把上传器拆解为:
weui-cells → weui-cell → weui-cell__bd → weui-uploader
就像俄罗斯套娃,组件层层嵌套,保证每个部分都可复用。
2. 留白艺术
css
.weui-cell_uploader {
padding-bottom: 24px; /* 底部额外留白 */
}
上传区域底部增加留白,给操作留出呼吸空间,避免拥挤感。
3. 渐进增强
css
-webkit-overflow-scrolling: touch; /* 支持设备使用更好特性 */
不支持的设备仍有基础滚动功能,优雅降级不影响核心体验。
4. 关注细节
css
.weui-uploader__file {
background: url(...) no-repeat 50%; /* 居中默认图 */
}
连默认图的居中展示都考虑到了------魔鬼藏在细节中! 真是不要太细节
七、为什么这些知识点是大厂必考?
- BEM命名:考察代码组织能力和团队协作规范
- Flex布局:新时代布局方案的掌握程度
- 移动端适配:是否具备移动优先思维
- 预处理器的使用:工程化能力和开发效率意识
- 组件设计:模块化思维和接口设计能力
- 性能优化:如使用伪元素代替DOM节点
大厂不考死记硬背,考的是如何像工程师一样思考!
结语:源码学习的正确姿势
学习WEUI Uploader源码就像在吃一道精致料理:
- 先整体欣赏(HTML结构)
- 再细品调料(CSS技巧)
- 最后研究烹饪法(设计思想)
记住:读源码不是背代码,而是理解背后的设计决策。下次面试官让你实现上传组件时,你可以自信地说:
"我的实现参考了WEUI的设计哲学:BEM命名保证可维护性,Flex保证布局灵活性,负边距+Float处理网格布局,伪元素实现细线边框,还有精心计算的间距系统..."
这,就是源码学习的真正价值!
最后我给大家相关代码和结果,大家也去探索一下吧
css部分
css
* {
margin: 0;
padding: 0;
}
.page {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
background-color: #ededed;
overflow: scroll;
-webkit-overflow-scrolling: touch;
box-sizing: border-box;
z-index: 1;
}
.page .page__hd {
padding: 40px;
}
.page .page__title {
text-align: left;
font-size: 20px;
font-weight: 400;
}
.page .page__desc {
margin-top: 4px;
color: rgba(0, 0, 0, 0.55);
text-align: left;
font-size: 14px;
}
.weui-cells {
margin-top: 8px;
background-color: #fff;
position: relative;
overflow: hidden;
}
.weui-cells::before {
content: "";
position: absolute;
left: 0;
right: 0;
height: 1px;
background-color: rgba(0, 0, 0, 0.1);
z-index: 2;
}
.weui-cell {
padding: 16px;
position: relative;
display: flex;
align-items: center;
line-height: 1.41176471;
}
.weui-cell .weui-cell__bd {
flex: 1;
}
.weui-cell_uploader {
padding-bottom: 24px;
}
.weui-uploader .weui-uploader__hd {
display: flex;
padding-bottom: 12px;
align-items: center;
}
.weui-uploader .weui-uploader__hd .weui-uploader__title {
flex: 1;
}
.weui-uploader .weui-uploader__hd .weui-uploader__info {
color: rgba(0, 0, 0, 0.3);
}
.weui-uploader .weui-uploader__bd {
margin-bottom: -8px;
margin-right: -8px;
overflow: hidden;
}
.weui-uploader .weui-uploader__files {
list-style: none;
}
.weui-uploader .weui-uploader__files .weui-uploader__file {
float: left;
margin-right: 8px;
margin-bottom: 8px;
width: 96px;
height: 96px;
background: url("https://weui.io/images/pic_160.png") no-repeat 50%;
background-size: cover;
}
html部分
html
<div class="page">
<header class="page__hd">
<h1 class="page__title">Uploader</h1>
<p class="page__desc">
上传组件,支持图片上传、文件上传、视频上传等
</p>
</header>
<main class="page__bd">
<div class="weui-cells weui-cells_form">
<div class="weui-cell weui-cell_uploader">
<div class="weui-cell__bd">
<div class="weui-uploader">
<div class="weui-uploader__hd">
<p class="weui-uploader__title">图片上传</p>
<div class="weui-uploader__info">
<span>0</span> /
<span>2</span>
</div>
</div>
<div class="weui-uploader__bd">
<ul class="weui-uploader__files">
<li class="weui-uploader__file"></li>
<li class="weui-uploader__file"></li>
<li class="weui-uploader__file"></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
最后实现结果
