装饰器的定义

装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,属性或参数上,可以修改类的行为。

通俗的讲装饰器就是一个方法,可以注入到类、方法、属性参数上来扩展类、属性、方法、参数的功能。

常见的装饰器有:类装饰器、属性装饰器、方法装饰器、参数装饰器

装饰器的写法:普通装饰器(无法传参) 、 装饰器工厂(可传参)

阅读全文 »

Typescript 介绍

  • typescript 是由微软开发的一款开源的编程语言。
  • typescript 是 Javascript 的超集,遵循最新的 ES6、Es5 规范。TypeScript 扩展了 JavaScript 的语法。
  • typescript 更像后端 java、C#这样的面向对象语言,可以让 js 开发大型企业项目。
  • 谷歌也在大力支持 Typescript 的推广,谷歌的 angular2.x+就是基于 Typescript 语法。
  • 最新的 Vue 、React 也可以集成 TypeScript。
  • Nodejs 框架 Nestjs、midway 中用的就是 TypeScript 语法。

为什么要使用 TypeScript

  • 类型推演与类型匹配
  • 开发编译时报错
  • 极大程度的避免了低级错误
  • 支持 JavaScript 最新特性(包含 ES6\7\8)

Typescript 安装 编译

阅读全文 »

接口的作用:在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计里面,接口起到一种限制和规范的作用。接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供某些方法,提供这些方法的类就可以满足实际需要。 typescrip 中的接口类似于 java,同时还增加了更灵活的接口类型,包括属性、函数、可索引和类等。
定义标准。

属性接口

对 json 的约束

ts 中定义方法

1
2
3
4
function printLabel(): void {
console.log("printLabel");
}
printLabel();
阅读全文 »

命名空间

在代码量较大的情况下,为了避免各种变量命名相冲突,可将相似功能的函数、类、接口等放置到命名空间内。
同 Java 的包、.Net 的命名空间一样,TypeScript 的命名空间可以将代码包裹起来,只对外暴露需要在外部访问的对象。命名空间内的对象通过 export 关键字对外暴露。

命名空间和模块的区别

名称特征
命名空间内部模块,主要用于组织代码,避免命名冲突。
模块ts 的外部模块的简称,侧重代码的复用,一个模块里可能会有多个命名空间。

示例代码如下:

阅读全文 »

websocket 实现实时通讯

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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
"use strict";

function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}

var socket = (function () {
function socket() {
// 调用socket方法时传入的第一个参数为url, 第二个参数为options配置
var url =
arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
var options = arguments[1];

_classCallCheck(this, socket);

this.heartBeatTimer = null;
this.options = options;
this.messageMap = {};
this.connState = 0;
this.socket = null;
this.url = url;
this.limitConnect = 3; // 断线重连次数
this.timeConnect = 0;
}

socket.prototype.doOpen = function doOpen() {
var _this = this;
if (this.connState) return;
this.connState = 1;
this.afterOpenEmit = [];
var BrowserWebSocket = window.WebSocket || window.MozWebSocket;
var socket = new BrowserWebSocket(this.url);
socket.binaryType = "arraybuffer";
socket.onopen = function (evt) {
return _this.onOpen(evt);
};
socket.onclose = function (evt) {
return _this.onClose(evt);
};
socket.onmessage = function (evt) {
return _this.onMessage(evt.data);
};
socket.onerror = function (err) {
return _this.onError(err);
};
this.socket = socket;
};

socket.prototype.onOpen = function onOpen(evt) {
this.connState = 2;
this.heartBeatTimer = setInterval(this.checkHeartbeat.bind(this), 5000);
this.onReceiver({
Event: "open"
});
};

socket.prototype.checkOpen = function checkOpen() {
return this.connState === 2;
};

socket.prototype.onClose = function onClose() {
this.connState = 0;
if (this.connState) {
this.onReceiver({
Event: "close"
});
}
console.log("服务器已经断开");
this.reconnect();
};

socket.prototype.send = function send(data) {
this.socket.send(JSON.stringify(data));
};

socket.prototype.emit = function emit(data) {
var _this2 = this;

return new Promise(function (resolve) {
_this2.socket.send(JSON.stringify(data));
_this2.on("message", function (data) {
resolve(data);
});
});
};

socket.prototype.onMessage = function onMessage(message) {
if ("pong" !== message) {
try {
var data = JSON.parse(message);
this.onReceiver({
Event: "message",
Data: data
});
} catch (err) {
// console.error(' >> Data parsing error:', err);
}
}
};

socket.prototype.checkHeartbeat = function checkHeartbeat() {
this.socket.send("ping");
};

socket.prototype.onError = function onError(err) {
console.log("服务器报错:");
this.reconnect();
};

// 重连
socket.prototype.reconnect = function reconnect() {
if (this.heartBeatTimer) {
clearInterval(this.heartBeatTimer);
this.heartBeatTimer = null;
}
if (this.limitConnect > 0) {
// lockReconnect加锁,防止onclose、onerror两次重连
if (localStorage.getItem("lockReconnect") != true) {
localStorage.setItem("lockReconnect", 1);
this.limitConnect--;
this.timeConnect++;
console.log("第" + this.timeConnect + "次重连");
// 进行重连
setTimeout(function () {
TVjsApi.initSocket();
localStorage.removeItem("lockReconnect");
}, 2000);
}
} else {
console.log("TCP连接已超时");
}
};

socket.prototype.onReceiver = function onReceiver(data) {
var callback = this.messageMap[data.Event];
if (callback) callback(data.Data);
};

socket.prototype.on = function on(name, handler) {
this.messageMap[name] = handler;
};

socket.prototype.doClose = function doClose() {
this.socket.close();
};

socket.prototype.destroy = function destroy() {
if (this.heartBeatTimer) {
clearInterval(this, this.heartBeatTimer);
this.heartBeatTimer = null;
}
this.doClose();
this.messageMap = {};
this.connState = 0;
this.socket = null;
};

return socket;
})();

diy-vant-list 此组件可使用 van-list 的任意 api,van-pull-refresh 中的部分 api 与 List 组件命名冲突,增加前缀 [pull-]。 如: [pull-loading-text][pull-loading]
学习本文档可参考 vant 官方文档

引入(全局注入组件)

1
2
3
import diyVantList from "@/components/diy-vant-list";

Vue.component("diyVantList", diyVantList);

组件使用

1
2
3
4
5
<diy-vant-list postUrl="">
<template slot="content" slot-scope="{listItem}">
<div>{{ listItem }}</div>
</template>
</diy-vant-list>
阅读全文 »

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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
abbr,
address,
article,
aside,
audio,
b,
blockquote,
body,
canvas,
caption,
cite,
code,
dd,
del,
details,
dfn,
div,
dl,
dt,
em,
fieldset,
figcaption,
figure,
footer,
form,
h1,
h2,
h3,
h4,
h5,
h6,
header,
hgroup,
html,
i,
iframe,
img,
ins,
kbd,
label,
legend,
li,
mark,
menu,
nav,
object,
ol,
p,
pre,
q,
samp,
section,
small,
span,
strong,
sub,
summary,
sup,
table,
tbody,
td,
tfoot,
th,
thead,
time,
tr,
ul,
var,
video {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: 0 0;
box-sizing: border-box;
}

/* 加*号会导致ios光标不显示 */
body.env1,
body.env2 {
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}

body,
html {
height: 100%;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, STHeitiSC-Light,
Microsoft YaHei, "\5FAE\8F6F\96C5\9ED1", SimSun, sans-serif;
}

html {
-webkit-overflow-scrolling: touch;
}

:focus {
outline: 1;
}

article,
aside,
canvas,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section,
summary {
display: block;
}

ul {
list-style: none;
}

blockquote,
q {
quotes: none;
}

blockquote:after,
blockquote:before,
q:after,
q:before {
content: "";
content: none;
}

a {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
vertical-align: baseline;
background: 0 0;
}

ins {
background-color: #ff9;
color: #000;
text-decoration: none;
}

mark {
background-color: #ff9;
color: #000;
font-style: italic;
font-weight: 700;
}

del {
text-decoration: line-through;
}

abbr[title],
dfn[title] {
border-bottom: 1px dotted #000;
cursor: help;
}

table {
border-collapse: collapse;
border-spacing: 0;
}

hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 1em 0;
padding: 0;
}

input,
select {
vertical-align: middle;
}

input::-webkit-input-placeholder {
color: #bfbfbf;
font-size: 14px;
}

input::-moz-placeholder {
color: #bfbfbf;
font-size: 14px;
}

input:-ms-input-placeholder {
color: #bfbfbf;
font-size: 14px;
}

::-webkit-scrollbar {
display: none;
}

1
<canvas id="c1" width="800" height="600"></canvas>

画布内的元素移动

1
2
3
4
5
6
7
8
9
10
11
12
window.onload = function () {
//图形动起来

let oC = document.getElementById("c1");
let gd = oC.getContext("2d");
let L = 50;
setInterval(() => {
gd.clearRect(0, 0, oC.width, oC.height); //清除整个画布
L++;
gd.strokeRect(L, 50, 100, 70);
}, 10);
};

画布内的矩形元素添加事件

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
window.onload = function () {
//点击事件
let oC = document.getElementById("c1");
let gd = oC.getContext("2d");
let l = 50,
t = 50,
w = 100,
h = 70;
gd.strokeRect(l, t, w, h);
oC.onclick = function (e) {
gd.clearRect(0, 0, oC.width, oC.height);
if (
e.offsetX >= l &&
e.offsetX <= l + w &&
e.offsetY >= t &&
e.offsetY <= t + h
) {
gd.strokeStyle = "red";
gd.strokeRect(l, t, w, h);
} else {
gd.strokeStyle = "blue";
gd.strokeRect(l, t, w, h);
}
};
};
阅读全文 »