app开发踩坑记录及其经验总结-2022暑假

小学期做项目js+python,收获很多,总结一下,以后可能就忘了,做个记忆保存和学习记录,记录点经验和体会。

最重要的一个:没有使用框架,纯原生js实现,做着做着发现自己其实已经不自觉的有开发框架的倾向了。说“开发框架”有点过了,其实只是把一些常用的过程简单的封装了一下。

其实学个框架挺重要的,至少代码不至于被拆的像屎山一样。不过自己手造轮子也有点小收获。发现了自己一些细小知识点的不足。同时也有点能够感觉到框架是怎么被开发出来的了。

前瞻性思考不足

最开始没打算做PC端,导致在pc端看起来太宽的双切换界面改起来已经不太好改了。

接口格式

因为”title”在前端传递的时候给写成name了,导致以为后端出了错误,低级错误

1
2
3
4
5
6
{
"title": "打比赛",
"week": [6],
"startTime": "13:15",
"alarm": true,
},

日期操作

获取今天是星期几,每次都忘,每次都查。

1
2
3
4
from datetime import datetime
d = datetime.now()
print(d.strftime("%A")) # 字符串的星期六中文
print(d.isoweekday()) # 1 2 3 4 5 6 7

系统路径

1
f"myDB/jsonDB/{fileName}.json"

要写/,不要写 //

颜色输入框设置默认颜色

必须是十六进制字符,rgb不行 ,red也不行

1
<input type="color" class="fillColor" value="#fff">

canvas模糊问题

canvas其实是模糊的,需要先放大,再css强制缩小。

封装canvas画图操作

因为每次画个小东西还要改ctx太麻烦了,索性直接写成function,同时还解决模糊问题。

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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/**
* canvas绘制标准化
* @param n
* @return {number}
*/
function standardize(n) {
return Math.floor(n * PR);
}

/**
* 在canvas上下文对象中画一条线,
* 这条线是对齐了像素点的,之所以要对齐像素点就是要解决模糊的效果
* 也就是传入的参数会默认取整
* @param ctx
* @param x1
* @param y1
* @param x2
* @param y2
* @param lineWidth
* @param color
* @param isDash
*/
function drawLine(ctx, x1, y1, x2, y2,
lineWidth = 1, color = "black", isDash = false) {
ctx.lineWidth = lineWidth;
ctx.strokeStyle = color;
ctx.beginPath();
if (isDash) {
ctx.setLineDash([5, 5]);
} else {
ctx.setLineDash([]);
}
ctx.moveTo(standardize(x1), standardize(y1));
ctx.lineTo(standardize(x2), standardize(y2));
ctx.stroke();
}

/**
* 画矩形边框
* @param ctx 上下文对象
* @param x 左上角顶点
* @param y 左上角顶点
* @param width 宽度
* @param height 高度
* @param color
* @param lineWidth
*/
function drawRectStroke(ctx, x, y, width, height, color, lineWidth) {
ctx.strokeStyle = color;
ctx.lineWidth = standardize(lineWidth);
ctx.lineJoin = "round";
ctx.strokeRect(standardize(x), standardize(y), standardize(width), standardize(height));
}

/**
* 画矩形填充
* @param ctx
* @param x 左上角顶点
* @param y 左上角顶点
* @param width
* @param height
* @param color
*/
function drawRectFill(ctx, x, y, width, height, color) {
ctx.fillStyle = color;
ctx.fillRect(standardize(x), standardize(y), standardize(width), standardize(height));
}

/**
* 写文字
* @param ctx
* @param content {String}
* @param x {Number} px
* @param y {Number} px
* @param color 颜色字符串
* @param fontSize {Number} px
*/
function writeFont(ctx, content, x, y, color = "black", fontSize = 20) {
ctx.fillStyle = color;
ctx.font = `${standardize(fontSize)}px "微软雅黑"`; //设置字体
// 默认中心对齐

/**
* |
* --+-----
* |
* 也就是填入的坐标点是整个文字的中心坐标点
*/

ctx.textBaseline = "middle";
ctx.textAlign = "center";
ctx.fillText(content, standardize(x), standardize(y));

}

两个IDE混着提交差点导致git乱了

pycharm和webstome。webstome打开的项目文件是pycharm打开项目文件的子文件夹。在pycharm里囤积的提交,websotme里再提交会忽略。要么只用一个编辑器搞git的事情,要么提交一次推送一次。

界面弹窗切换

注意是flex盒子,不要display:block了。早知道用框架了!Vue、react啥的,自己手写逻辑真麻烦。

css3动画停止状态

在动作结束时保持该状态不变

https://blog.csdn.net/yiyueqinghui/article/details/120292718

1
animation-fill-mode:forwards;

目的是为了去掉alert,改成不需要点击的一种气泡上升,于是创造了一个组件

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
/**
* 一种气泡组件
*
*/
class Bubble {
// 这种气泡组件会在最上方,css 的 z层是100
static z = 100;
// 气泡上升动画持续多少秒
static raiseDur = 1;
// 气泡多少秒后消失
static dur = 2;

/**
* 窗口上弹出一个框
* @param string {String}
*/
static pop(string) {
let bubble = div(string, "bubble");
bubble.style.zIndex = `${this.z}`;
// 设置上升动画秒数
bubble.style.animationDuration = `${this.raiseDur}s`;

let body = $("body");
body.appendChild(bubble);
setTimeout(() => {
bubble.style.animationDuration = `${this.dur - this.raiseDur}s`;
bubble.style.animationName = `bubbleExpand`;
}, this.raiseDur * 1000);
setTimeout(() => {
body.removeChild(bubble);
}, this.dur * 1000);
}
}

其实写的还不严谨,就为了图方便图快了。因为项目挺赶的。

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

@keyframes bubbleRaise {
from {
top: 20%;
}
to {
top: 10%;
}
}

@keyframes bubbleExpand {
from {
top: 10%;
transform: scale(1);
opacity: 100%;
}
to {
top: 10%;
transform: scale(2);
opacity: 0;
}
}

/**
气泡组件
*/
.bubble {
padding: 10px 50px 10px 50px;
border-radius: 1000px;
line-height: 2em;
font-size: 22px;
font-weight: bolder;
position: absolute;
left: 50%;
outline: solid 1px;
border: solid 2px;
background-color: rgba(255, 255, 255, 0.5);
top: 20%;

animation-name: bubbleRaise;
animation-iteration-count: 1;
animation-duration: 2s;
animation-fill-mode: forwards;
}

css做出鼠标按一下,就让某个div执行一下一次性动画

html

1
2
<button class="get">get</button>
<div class="box">123123</div>

css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@keyframes note {
0% {
background-color: transparent;
}
50% {
background-color: red;
}
100% {
background-color: transparent;
}
}

.box {

animation-fill-mode: forwards;
animation-duration: 1s;
}

js

1
2
3
4
5
6
7
8
9
10
let box = document.querySelector(".box");
document.querySelector(".get").onclick = function () {
if (box.style.animationName === "note") {
return;
}
box.style.animationName = "note";
setTimeout(() => {
box.style.animationName = "none";
}, 1000);
}

无意间发现了类属性和匿名内部类

原来自己一直都没有用过的类属性和匿名内部类,可能这严格来说不算匿名内部类了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class A {
static b = 15;
static C = class {
constructor(x, y) {
this.x = x;
this.y = y;
}
}

constructor() {
class B {

}
}
}

console.log(A.b);
A.b += 15
console.log(A.b);
let c = new A.C(1, 1);
console.log(c);

ajax封装

最开始以为一个ajax对象就可以用来处理所有的接口了,所以直接写了一个ajax全局对象。结果出了严重bug。

后来才意识到原来一个接口对应一个ajax对象才是对的。可以算是基础不牢固、不熟吧。但ajax写多了之后发现又有点麻烦,于是又又又封装成一个函数了。为了疯狂偷懒而疯狂封装。

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
/**
* 手动对ajax进行二次封装
* @param urlFix 请求路径后缀
* @param sendJson 发送的json,如果不写则自动变成get请求
* @return {XMLHttpRequest} 返回一个ajax对象,需要这样写
* POST("userGetAllDDL", {userName: "张全蛋"}).finish((res) => {
res 便是自动解析成结果的js对象,可以直接使用了
});
*/
function AJAX(urlFix, sendJson = null) {
let ajaxObj = new XMLHttpRequest();
ajaxObj.open(sendJson === null ? "GET" : "POST", `http://${ADDRESS}:${PORT}/${urlFix}`);
ajaxObj.setRequestHeader("Content-Type", "application/json");
if (sendJson === null) {
ajaxObj.send();
} else {
ajaxObj.send(JSON.stringify(sendJson));
}
// finish 是我自己新创的一个
ajaxObj.finish = (yourFunc) => {
ajaxObj.onload = () => {
let obj = JSON.parse(ajaxObj.responseText);
yourFunc(obj);
}
};
return ajaxObj;
}

依旧待解决的问题

webstome的html为什么ctrl+/ 之后,左侧注释开始从行首开始。