JS 篇
编码优化
使用 ES6 规范编码
善于利用解构
const { itemTitle, itemImg } = item;
不使用 commonjs 的规范引用和导出
const $ = require('@ali/mui-zepto/zepto');
module.exports = $;
import $ from '@ali/mui-zepto/zepto';
export default $;
建议使用 async await 处理异步
- ``` async function timeout(ms) { await new Promise((resolve) => { setTimeout(resolve, ms); }); }
async function asyncPrint(value, ms) { await timeout(ms); console.log(value); }
asyncPrint(‘hello world’, 50); ```
关于 zepto 部分
无线端不建议使用 zepto,建议使用原生 API 替代
原因:
目前无线端原生 API 的兼容性足够好
长期在 zepto 和 原生 API 之间来回切换会容易产生 bug
- case:
$(box)[0]
和this.box[0]
混淆导致 lazyload 绑定对象查询失败,绑定到 body 上
- case:
常用原生 API
zepto 写法 | 原生 | 备注 |
---|---|---|
$(‘selector’); | document.querySelectorAll(‘selector’); | |
$(‘selector’).first(); | document.querySelector(‘selector’); | |
$(‘selector’, box).first(); | box.querySelector(‘selector’); | 最常用的写法,携带查询 scope |
$el.attr(‘foo’); | el.getAttribute(‘foo’); | |
$el.attr(‘foo’, ‘bar’); | el.setAttribute(‘foo’, ‘bar’); | |
$el.css({ color: ‘#f01’ }); | el.style.color = ‘#f01’; | |
$el.addClass(className); | el.classList.add(className); | |
$el.removeClass(className); | el.classList.remove(className); | |
$el.hasClass(className); | el.classList.contains(className); | |
$el.toggleClass(className); | el.classList.toggle(className); | |
$(window).scrollTop(); | (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop; | 常见的兼容写法 |
$el.remove(); | el.parentNode.removeChild(el); | 常见的兼容写法 |
$el.html(htmlString); | el.innerHTML = htmlString; | |
$el.on(eventName, eventHandler); | el.addEventListener(eventName, eventHandler); | |
$.now(); | Date.now(); |
常见问题
获取浏览器高度
// 不含 scrollbar
window.innerHeight;
获取元素高度
- ``` // Native function getHeight(el) { const styles = this.getComputedStyle(el); const height = el.offsetHeight; const borderTopWidth = parseFloat(styles.borderTopWidth); const borderBottomWidth = parseFloat(styles.borderBottomWidth); const paddingTop = parseFloat(styles.paddingTop); const paddingBottom = parseFloat(styles.paddingBottom); return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom; }
// 精确到整数(border-box 时为 height - border 值,content-box 时为 height + padding 值) el.clientHeight;
// 精确到小数(border-box 时为 height 值,content-box 时为 height + padding + border 值) el.getBoundingClientRect().height; ```
常见错误代码
有 if 就要有对应的 else 逻辑
for 循环内针对数组长度进行缓存,避免重复计算
不要使用 | 请使用 |
---|---|
location.href | window.location.href |
setTimeout | 使用 async await Promise |
‘htmlString’ | 使用反引导` |
$el.css({ color: ‘#f01’ }); 或 el.style.color = ‘#f01’; | 定义类,添加或删除类 |
开头 import 结尾 module.exports | 纯粹的 ES 模块导入导出规范 |
localStorage.getItem | try … catch 避免隐身模式问题 |
命名规范
组件类采用首字母大写方式定义
- 原因:这样在调试阶段可以显式在控制台打印出对应大写类名,利于排查错误。
pmod-zebra-module
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── tap.conf.js
└── src
├── xtpls
│ ├── App.less
│ ├── App.js
│ ├── App.xtpl
├── index.less
└── index.js
事件绑定名称定义
- handleXXX,如:handleClick handleInputChange 等
能用
const
的地方就不用let
变量名不能出现拼音,为了准确表达,尽量使用长变量名。
生产工具推荐
代码格式化 prettier
相关配置:
"prettier.singleQuote": true, // 使用单引号
"prettier.trailingComma": "es5", // 末行数组带逗号
编辑器
建议使用 vscode
插件推荐
GitLens
Import Cost
性能优化
passive event
使用方法:
elem.addEventListener('touchstart', fn, detectIt.passiveEvents ? {passive:true} : false);
样式篇
常用配置
统一盒模型
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
}
最末元素样式
.nav li:not(:last-child) {
border-right: 1px solid #666;
}
移除滚动条
::-webkit-scrollbar {
display: hidden;
}
居中设置
.flexbox-centering {
display: flex;
justify-content: center;
align-items: center;
}
使用系统字体
.system-font-stack {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu,
Cantarell, 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
多行文本
.multi-line-text {
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
text-overflow: ellipsis;
}
便捷开发
使用 vw
普通方式
配置参数
{
viewportWidth: 750,
viewportHeight: 1334,
unitPrecision: 3,
viewportUnit: 'vw',
selectorBlackList: ['.ignore', '.hairlines'],
minPixelValue: 1,
mediaQuery: false
}
脚手架快捷方式
使用 @ali/tap-template-zebra-module-h5-vw
替换 @ali/tap-template-zebra-module-h5
。
module.exports = {
isAliIntranet: true,
template: {
module: '@ali/tap-template-zebra-module-h5-vw',
sv: '^5.0.0',
},
};
规范约定
z-index
最顶层:999999 (modal)
页头:1099
二级页头:1000 1010 1020 (参考 bootstrap 规范)
购物车:999
其他:1 2 3
常用工具
SVG 压缩
https://jakearchibald.github.io/svgomg/
模板篇
组件化
LESS 部分
定义组件 scope
样式层级不超过 3 层
使用响应单位
.zebra-jinkou-item {
width: 30.8vw;
display: block;
overflow: hidden;
position: relative;
background-color: #fff;
&-img {
width: 30.8vw;
height: 30.8vw;
}
&-title {
color: #333333;
font-size: 3.2vw;
height: 9.6vw;
line-height: 4.8vw;
display: -webkit-box;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
}
}
XTPL 部分
a 标签设置
target="_blank"
尽量不使用 id
为每个元素添加语义化的类,并处理好 scope
{{#each(itemList)}}
<a data-id="{{itemId}}" class="zebra-jinkou-item" href="{{itemUrl}}" target="_blank">
{{/each}}
JS 部分
引用样式
引用异步模板
导出函数
import './item.css';
import itemTpl from './item.xtpl';
export default itemTpl;
Git 篇
Commit 规范
工具参考:http://marionebl.github.io/commitlint/#/
Commit type
feat:新功能(feature)
fix:修补bug
docs:文档(documentation)
style: 格式(不影响代码运行的变动)
refactor:重构(即不是新增功能,也不是修改bug的代码变动)
test:增加测试
chore:构建过程或辅助工具的变动
Commit 范例
增加了点击方法:
feat: add click listener
修复了点击事件:
fix: click handler
预发测试:
test: slide swiper
改了下格式:
style: remove space
不知道选什么类型:
chore: balabala
推荐使用英文 Commit,方便检索,利于与外语开发者合作。
PR 规范
在原有仓库 master 上 checkout 分支,名称如:
feat/dynamic-render
fix/item-template
等修改代码,不破坏原有的格式,不进行构建
提交代码,向 master 分支发起 PR
填写详细的变更情况