公告

网站迁移了,之前是托管在 gitee 上,好处是不用买服务器,坏处是不利于 seo 收录

前段时间把域名备案了,买了中国大陆的服务器,用 jenkins + nginx 搭了个自动化部署

新的服务器,新的开始,加油,奥利给 💪

小程序 跳转分包页面 点击多次的时候会跳转多次的问题

前言:

我们的小程序有做分包,tabbar 的四个页面以及 webview 页面放主包,其他的页面按照模块分了 user、order、mall的分包

问题:

产品在验收小程序的时候,发现在个人中心页面快速的点两次 我的订单 按钮,小程序就会跳转两次页面,一开始我们还不知道是什么原因,按照正常来说点一次就会马上跳转了。后来在微信开发者工具调为弱网模式试了下,发现点了按钮后,下方的状态栏显示在加载页面,这时候就懂了,因为那个页面是分包的页面,小程序只会主动加载主包的页面,分包的页面在访问时才会加载,所以点的快的话分包还在加载中,等加载完后因为快速点了几次就跳了几次页面

解决:

这个问题解决起来也很简单,小程序提供了一个分包预下载的功能,可以通过配置,在进入小程序某个页面的时候,就去预下载需要的分包,提升后续进入分包页面时的启动速度

配置方法:

app.json 增加 preloadRule 配置来控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"pages": ["pages/index"],
"subpackages": [
{
"root": "sub1",
"pages": ["index"],
},
{
"root": "sub2",
"pages": ["index"]
}
],
"preloadRule": {
"pages/index": {
"network": "all",
"packages": ["sub1", "sub2"]
},
}
}

带过期时间的 storage

由于小程序需要一个带有过期时间的缓存功能,原生缓存又不支持,于是就自己写了一个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import { isType } from './index';

const DEFAULT_TIME_KEY = 'always';

export default class Storage {
constructor() {
this.timeSign = '|-|';
}

isObj(value) {
return isType(value) === 'object';
}

/**
* 设置缓存
* @param {*} key
* @param {*} value
* @param {*} timestamp 到期时间 传时间戳/毫秒
* @returns
*/
set(key, value, timestamp = DEFAULT_TIME_KEY) {
let params;

if (this.isObj(value)) {
params = Object.assign(value, { startTime: timestamp });
} else {
params = value + this.timeSign + timestamp;
}

// 小程序单条数据转换成字符串后,字符串长度最大200*1024。同一个用户,同一个小程序缓存总上限为10MB。
uni.setStorageSync(key, params);
}

/**
* 读取缓存
* @param {*} key
* @returns
*/
get(key) {
const value = uni.getStorageSync(key);

if (value) {
const arr = value.split(this.timeSign);
if (arr.length > 1) {
if (new Date().getTime() > arr[1]) {
this.remove(key);
return null;
}
return arr[0];
}
return arr[0];
}

return null;
}

/**
* 移除缓存
* @param {*} key
*/
remove(key) {
if (!key) throw new Error('key为必填项');
uni.removeStorageSync(key);
}

/**
* 清空所有缓存
*/
clear() {
uni.clearStorageSync();
}
}

main.js 注册到全局

1
Vue.prototype.$storage = new Storage();

使用:

1
2
3
this.$storage.set('key', 123);
this.$storage.get('key'); // 123
this.$storage.remove('key'); // 清除 key

scss 使用 calc 遇到的问题

今天写代码时,需要对一个scss变量做calc处理,发现直接使用变量,浏览器是无法识别的,后面查了一下,要对变量处理才能正常使用

1
2
3
4
5
$a: 20px;
.xxx {
width: calc(100% - $a); // 这样写是不行的
height: calc(100% - #{a}); // 要这样写才生效
}

图片懒加载

图片懒加载是性能优化里很常见的一个操作,可以节省用户流量、减少http请求、提升首屏的打开速度

很多情况下,用户首屏看到的图片是只有小部分,剩下的图片可以滑动的那个距离的时候在加载

大概的实现原理是:先把 imgsrc 属性加在自定义属性 data-src 上,等当前元素出现在可视区域里的时候,在把 data-src 里的图片链接设到 src

demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Lazy-Load</title>
<style>
.img {
width: 200px;
height:200px;
background-color: #000;
}
</style>
</head>
<body>
<div class="container">
<div class="img">
<img class="pic" alt="加载中" data-src="./images/1.png">
</div>
<div class="img">
<img class="pic" alt="加载中" data-src="./images/2.png">
</div>
<div class="img">
<img class="pic" alt="加载中" data-src="./images/3.png">
</div>
<div class="img">
<img class="pic" alt="加载中" data-src="./images/4.png">
</div>
<div class="img">
<img class="pic" alt="加载中" data-src="./images/5.png">
</div>
<div class="img">
<img class="pic" alt="加载中" data-src="./images/6.png">
</div>
<div class="img">
<img class="pic" alt="加载中" data-src="./images/7.png">
</div>
<div class="img">
<img class="pic" alt="加载中" data-src="./images/8.png">
</div>
<div class="img">
<img class="pic" alt="加载中" data-src="./images/9.png">
</div>
<div class="img">
<img class="pic" alt="加载中" data-src="./images/10.png">
</div>
</div>
</body>
<script>
// 获取所有的图片标签
const imgs = document.getElementsByTagName('img')
// 获取可视区域的高度
const viewHeight = window.innerHeight || document.documentElement.clientHeight
// num用于统计当前显示到了哪一张图片,避免每次都从第一张图片开始检查是否露出
let num = 0
function lazyload(){
for(let i=num; i<imgs.length; i++) {
// 用可视区域高度减去元素顶部距离可视区域顶部的高度
let distance = viewHeight - imgs[i].getBoundingClientRect().top
// 如果可视区域高度大于等于元素顶部距离可视区域顶部的高度,说明元素露出
if(distance >= 0 ){
// 给元素写入真实的src,展示图片
imgs[i].src = imgs[i].getAttribute('data-src')
// 前i张图片已经加载完毕,下次从第i+1张开始检查是否露出
num = i + 1
}
}
}
// 监听Scroll事件
window.addEventListener('scroll', lazyload, false);
</script>
</html>

以上就是一个简单的 demo 了,在实际使用中,还需要注意加上函数防抖,不然 lazyload 函数会触发很多次,还有就是如果已经展示了的图片,就不在触发更改 src 属性的操作,减少不必要的开销

前端工程化之 commitlint + husky 实现 git 提交规范化

前言

对于编程语言进行「语法、书写」校验,能有效「归并」不同开发者的「不同风格」,还能检验出一些语法错误。

比如 eslint 就能校验 JS 代码的「鸡肋糟粕」,css 哪些东西需要校验?单纯从代码层面来说,CSS 校验的东西其实蛮少的。

比如:属性顺序、小于 1 的小数要不要去掉 0、选择器之间要不要加空格…
不过要细细的追究,校验的东西还是挺多的,比如 List of rules 列出了好多需要校验的规则。

规范的出现就是为了让这些每个人的编程风格变得统一

阅读全文...

修复 antd select placeholder 不显示的问题

今天弄后台的时候需要用到 Select 下拉选择器的组件,但是发现传了 placeholder 还是无法显示提示,以前也一直是这些写的啊,看了下官网 demo,也是这样的,这让我很疑惑这次咋不行了

后来找了下原因,发现把默认值设为 undefined 就可以显示了,设置为 “” 或者 null 的时候是不会显示的

js 监听数据的变化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 监听数据的变化
* @param obj 需要监听的对象
* @param name 需要监听的属性
* @param func 数据变化后的回调函数
*/
export const watch = (obj: Obj, name: string, func: (value: any) => void) => {
Object.defineProperty(obj, name, {
get: function() {
return obj;
},
set: newValue => {
func && func(newValue);
},
});
};

使用例子:

1
2
3
4
5
6
const obj = {
name: 123
};
watch(obj, 'name', newValue => {
console.log('name 被改变了')
});

css 自定义 ol/li 序号样式

默认样式:

css 自定义 ol/li 序号样式 - 小鑫の随笔

自定义样式:

css 自定义 ol/li 序号样式 - 小鑫の随笔

CSS 代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ol {
counter-reset: li; // 创建计数器
}
ol li {
position: relative;
padding-left: 30px;
}
ol li::before {
content: counter(li) ".";
counter-increment: li; // 递增计数器
position: absolute;
left: 0;
font-size: 28px;
color: rgba(0, 0, 0, .8);
}