1 微信小程序

1.1 rpx

rpx是处理不同设备,元素大小的一种方法。

微信小程序的宽度固定是750rpx ,高度的rpx由长宽比决定。

其他处理相对大小的方法:

  • 使用百分比(%),这种方式相对于父容器来定义高度,可以适用于一些需要相对高度的场景。
  • 使用视窗高度(vh)来设置元素的高度。vh是CSS中的单位,其中1vh等于1%的视窗(viewport)高度(即浏览器高度)。

1.2 wxml 与html 区别

  1. 标签和属性
    • WXML为微信小程序特有的标记语言,它提供了一些自定义组件(如 <view><text> 等)来替代HTML中的标签(如 <div><span>)。
    • WXML中,classstyle等属性可以动态绑定数据(使用{{}}语法,括号内加js语句),从而实现动态的样式和内容。
  2. 数据绑定
    • WXML提供类似Vue数据绑定,通过{{}}进行变量插值,很方便地将页面数据与逻辑层数据连接。
  3. 事件处理
    • WXML中的事件绑定使用bindcatch前缀(如bindtapcatchtap),而HTML中则使用on前缀(如onclick)。
    • 微信小程序中的事件绑定允许开发者直接在WXML标签中定义处理函数,而不需要在页面加载后单独进行事件监听的设置。
  4. 条件渲染和列表渲染
    • WXML提供了类似Vue的wx:ifwx:elifwx:else属性用于条件渲染,以及wx:for用于循环列表渲染。这些指令能够简化页面的动态内容生成。

2 CSS

2.1 display属性

  1. **none**:
    元素不会被显示,并从文档流中移除,就好像它从来没有存在过一样。元素不占空间,它后面的元素会填补它原来的位置。

  2. **block**:
    块级元素。这意味着元素会新起一行显示,并尽可能填满其父容器的宽度。块级元素可以设置宽度、高度、外边距(margin)和内边距(padding)。

  3. **inline**:
    行内元素。元素不会新起一行,而是会和其他行内元素一样,在文本中同一行排列,只能在元素的前后添加内容。行内元素不能设置宽度和高度。

  4. **inline-block**:
    结合了inlineblock的特性。元素同行内元素一样水平排列,但它可以像块级元素一样设置宽度、高度、外边距和内边距。

  5. **flex**:
    元素将变为弹性容器(flex container),其子元素(flex items)能使用弹性布局的属性。这是CSS3中引入的一种布局模式,能够简化复杂的布局设计。

  6. **grid**:
    类似于flexgrid也是CSS3引入的一种现代布局模式。元素将变为网格容器,其内部子元素可以放在网格布局中。它为复杂的二维布局提供了更为强大和灵活的解决方案。

  7. **table**、table-rowtable-cell等:
    这一系列属性值将元素表现得像HTML中的表格元素一样。例如,display: table;可以将一个元素变为类似<table>的块级表格容器,而display: table-cell;则模仿了<td>的单元格盒子效果。

    (注:需要使用表格,尽量用div元素再设置display为table)

2.2 position属性定位

  • **static**(默认):不进行特殊定位,元素出现在正常的流中。
  • **relative**:元素相对于其正常位置进行定位。
  • **absolute**:元素相对于最近的非static定位的祖先元素进行定位。
  • **fixed**:元素相对于浏览器窗口进行定位,即便窗口滚动,元素也会保持在指定的位置。
  • **sticky**:元素根据用户的滚动位置在relativefixed定位之间切换。

使用leftrighttopbottom属性取决于position属性的值

2.3 flex弹性布局

属性

  • flex-direction
  • flex-wrap
  • justify-content
  • align-items
2.3.1 flex-direction属性

flex-direction属性决定主轴的方向(即项目的排列方向)。

  • row(默认值):主轴为水平方向,起点在左端。
  • row-reverse:主轴为水平方向,起点在右端。
  • column:主轴为垂直方向,起点在上沿。
  • column-reverse:主轴为垂直方向,起点在下沿。
2.3.2 flex-wrap属性

flex-wrap属性决定换行

  • nowrap(默认):不换行。
  • wrap:换行,第一行在上方。
  • wrap-reverse:换行,第一行在下方。
2.3.3 justify-content属性

justify-content决定水平方向的对齐

  • flex-start(默认值):左对齐
  • flex-end:右对齐
  • center: 居中
  • space-between:两端对齐,项目之间的间隔都相等。
  • space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
2.3.4 align-items属性

align-items决定垂直方向的对齐

  • flex-start:交叉轴的起点对齐。
  • flex-end:交叉轴的终点对齐。
  • center:交叉轴的中点对齐。
  • baseline: 项目的第一行文字的基线对齐。
  • stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。

3 JS

3.1 DOM操作

3.1.1 选择元素

通过id选择 var element = document.getElementById('myElement');

通过类class选择

​ 选一个 var singleElement = document.querySelector('.myClass');

​ 选所有 var multipleElements = document.querySelectorAll('.myClass');

jQuery写法

1
2
3
var $element = $('#myElement'); // 使用ID选择器
var $singleElement = $('.myClass'); // 使用类选择器,返回的是jQuery 对象集合
var $multipleElements = $('.myClass'); // 使用类选择器,返回的是jQuery 对象集合
3.1.2 修改元素内容

修改文本内容

1
2
var element = document.getElementById('myElement');
element.textContent = '新的文本内容';

修改html内容

1
2
var element = document.getElementById('myElement');
element.innerHTML = '<strong>新的HTML内容</strong>';

jQuery写法

1
2
3
4
var $element = $('#myElement');
$element.text('新的文本内容');
var $element = $('#myElement');
$element.html('<strong>新的HTML内容</strong>');
3.1.3 修改属性与样式

修改属性

1
2
3
var element = document.getElementById('myElement');
element.setAttribute('src', 'newImage.jpg');
element.src = 'newImage.jpg'; // 等效操作

修改样式

1
2
3
var element = document.getElementById('myElement');
element.style.color = 'red';
element.style.backgroundColor = 'blue';

jQuery写法

1
2
3
4
5
6
var $element = $('#myElement');
$element.attr('src', 'newImage.jpg'); // 设置属性
var srcValue = $element.attr('src'); // 获取属性
var $element = $('#myElement');
$element.css('color', 'red');
$element.css('background-color', 'blue');
3.1.4 事件处理

添加事件监听器

1
2
3
4
var element = document.getElementById('myElement');
element.addEventListener('click', function() {
alert('元素被点击了!');
});
3.1.5 jQuery其他操作

追加内容

1
2
3
var $parentElement = $('#myElement');
$parentElement.append('<div>新内容</div>'); // 在元素内的末尾插入新内容
$parentElement.prepend('<div>新内容</div>'); // 在元素内的开头插入新内容

移除元素

1
2
var $element = $('#myElement');
$element.remove(); // 移除元素

3.2 es6+新特性

3.2.1 块级作用域 let const

变量声明可以用var const let 先来介绍下var为什么不行

特点

  • 函数作用域:使用var声明的变量是函数作用域的,这意味着它只能在声明它的函数内访问到。
  • 变量提升var声明的变量在作用域内会被提升到作用域的顶部(hoisted),但变量提升只会提升声明,不会提升赋值。会被初始化为undefined
  • 可重新赋值var声明的变量可以重新赋值

坏处

  • 变量提升导致不小心在变量声明之前就使用它
  • 缺乏块级作用域导致变量的修改意外地跨越代码块发生

let的特点

  • 块级作用域let声明的变量在它们所在的任何块级作用域内有效。
  • 不可重复声明:在同一作用域内使用let声明的变量不能重新声明。
  • 变量提升但不初始化到undefinedlet声明的变量会被提升到所在块的顶部,但不会初始化为undefined,在声明之前访问这些变量会导致ReferenceError

const 的特点

  • 块级作用域const声明的变量在它们所在的任何块级作用域内有效。

  • 不可重新赋值const声明的变量在初始化之后无法重新赋值。注意,const声明的对象可以修改其属性。

  • 不可重复声明:与let相似,在同一作用域内使用const声明的变量不能重新声明。

  • 变量提升但不初始化到undefined:与let相似,const声明的变量会被提升到所在块的顶部,但不会初始化为undefined,在声明之前访问这些变量会导致ReferenceError

总结和区别

  • 作用域
    • var:函数作用域
    • let:块级作用域
    • const:块级作用域
  • 变量提升
    • var:变量提升并初始化为undefined
    • let:变量提升但不初始化
    • const:变量提升但不初始化
  • 可重新赋值性
    • var:可以重新赋值
    • let:可以重新赋值
    • const:不可重新赋值,但对象的属性可以修改
  • 不可重复声明
    • var:在同一作用域内可重复声明(会覆盖之前的声明)
    • let:在同一作用域内不可重复声明
    • const:在同一作用域内不可重复声明
3.2.2 箭头函数

示例

1
const add = (a, b) => a + b;
1
2
3
4
5
6
7
8
9
res => {
if (res.success) {
console.log(res.message);
alert('短信发送成功');
} else {
console.error(res.message);
alert('短信发送失败');
}
}

箭头函数主要特点

  1. 简洁的语法
    • 比传统的匿名函数语法简短,特别适合用于简短的回调函数。
  2. **词法的this**:
    • 箭头函数不会创建它自己的this上下文,this将保持为定义该箭头函数的上下文中的值。这在处理回调函数时特别有用,避免this值在不同上下文中的意外变化问题。
3.2.3 模板字符串

使用反引号(```)定义多行字符串和内插变量。

1
2
const name = 'John';
const greeting = `Hello, ${name}!`;

4 NodeJS

4.1 linux NodeJs安装

4.1.1 下载nodejs

去官网 Node.js — Download Node.js® (nodejs.org)

右键复制链接

建议输入 wget https://nodejs.org/dist/v20.15.1/node-v20.15.1-linux-x64.tar.xz

建议解压 tar -xvf node-v20.15.1-linux-x64.tar.xz

4.1.2 设置软链接 供全局使用

ln -s /usr/local/node-v20.15.1-linux-x64/bin/node /usr/local/bin/node

ln -s /usr/local/node-v20.15.1-linux-x64/bin/npm /usr/local/bin/npm

设置好后 winscp可以看到

4.1.3 配置环境,以防万一
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//进入到profile文件
vim /etc/profile
//在文件的末尾添加一下三行语句 (vim 操作命令可见此博客)
export NODE_HOME=/usr/local/node-v20.15.1-linux-x64
export PATH=$PATH:$NODE_HOME/bin
export NODE_PATH=$NODE_HOME/lib/node_modules
//按ESC键,再输入:wq保存并退出
//配置完成后执行
source /etc/profile
//在命令行中输入 node -v
//为了保证每个账户下该配置均可用需要
vim /root/.bashrc
//在这个文件的末尾加上以下这句语句
source etc/profile
//按ESC键,再输入:wq保存并退出
//成啦

4.2 pm2操作

pm2安装 npm install pm2 -g

pm2: linux系统下用来保证nodejs文件一直运行的软件

pm2常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
启动:pm2 start demo.js  //demo.js是你要启动的app_name|app_id文件
停止:pm2 stop app_name|app_id
删除:pm2 delete app_name|app_id
重启:pm2 restart app_name|app_id
停止所有:pm2 stop all
查看所有的进程:pm2 list
查看所有的进程状态:pm2 status
查看某一个进程的信息:pm2 describe app_name|app_id
参数说明
--watch:监听应用目录源码的变化,一旦发生变化,自动重启。如果要精确监听、不见听的目录,最好通过配置文件
-i --instances:启用多少个实例,可用于负载均衡。如果-i 0或者-i max,则根据当前机器核数确定实例数目,可以弥补node.js缺陷
--ignore-watch:排除监听的目录/文件,可以是特定的文件名,也可以是正则。比如--ignore-watch="test node_modules "some scripts"
-n --name:应用的名称,查看应用信息的时候可以用到
-o --output <path>:标准输出日志文件的路径,有默认路径
-e --error <path>:错误输出日志文件的路径,有默认路径
--interpreter <interpreter>:the interpreter pm2 should use for executing app (bash, python...)
如完整参数命令:
pm2 start demo.js --watch -i 2 //开启2个进程
pm2 start app.js -i max //根据机器CPU核数,开启对应数目的进程

4.3 vim

linux文本编辑器

在 Vim 中,有三种主要的工作模式:

  1. 普通模式(Normal mode):执行浏览和编辑命令。
  2. 插入模式(Insert mode):编辑文本,输入字符。
  3. 命令模式(Command mode):保存或退出文档,设置配置,运行宏等。

一些Vim中常用的操作和命令:

1
2
3
4
5
6
7
进入和退出
vim 文件名:在终端中打开一个文件。
:q:退出Vim(如果有未保存的更改,此命令会失败)。
:q!:强制退出并丢弃所有更改。
:w:保存文件。
:wq或:x或ZZ:保存文件并退出。
:w 文件名:保存文件到指定的文件名。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
普通模式:
h、j、k、l:左、下、上、右移动光标。
w和W:移动到下一个单词的开头。
b和B:移动到上一个单词的开头。
e和E:移动到下一个单词的末尾。
0:移动到行首。
$:移动到行末。
gg:移动到文件的第一行。
G:移动到文件的最后一行。
Ctrl + f:向下滚动一页。
Ctrl + b:向上滚动一页。
dd:删除(剪切)当前行。
yy:复制当前行。
p:粘贴内容到光标后。
u:撤销上一步操作。
Ctrl + r:重做上一步被撤销的操作。
1
2
3
插入模式:
i:在光标位置进入插入模式。
Esc:从插入模式返回普通模式。

5 异步操作 Promise Async Await

在JavaScript中,异步操作通常用于执行耗时的任务,如数据请求、文件读写等,而不阻塞主线程的执行。回调函数是处理异步操作的一种方式,但如果使用不当,可能导致回调地狱(Callback Hell)的问题。而Promises提供了更好的异步操作管理方法。

5.1 什么是Promise?

Promise是一个表示异步操作最终完成或失败的对象。它允许你为异步操作的成功值或失败原因编写处理方法。Promise有三种状态:

  • Pending(等待态):异步操作尚未完成。
  • Fulfilled(成功态):异步操作成功完成。
  • Rejected(失败态):异步操作失败。

5.2 创建与使用Promise

1
2
3
4
5
6
7
8
9
const promise = new Promise((resolve, reject) => {
// 异步操作
const success = true;
if (success) {
resolve('Operation successful');
} else {
reject('Operation failed');
}
});
1
2
3
4
5
6
7
promise
.then((value) => {
console.log(value); // 'Operation successful'
})
.catch((error) => {
console.error(error); // 'Operation failed'
});

5.3 Promise链式调用

1
2
3
4
5
6
7
doSomething()
.then(result => doSomethingElse(result))
.then(newResult => doThirdThing(newResult))
.then(finalResult => {
console.log(`Got the final result: ${finalResult}`);
})
.catch(failureCallback);

Promise链式调用中,每个.then()方法接收前一个.then()返回的结果作为输入,在链的任意位置抛出的错误(或被reject的Promise)都会被最近的.catch()处理。

5.4 Promise.all

Promise.all()可以将多个Promise实例包装成一个新的Promise实例

1
2
3
4
5
6
7
8
9
10
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(resolve, 100, 'foo'));
const promises = [promise1, promise2];

Promise.all(promises)
.then(results => {
const [result1, result2] = results;
console.log(result1); // 3
console.log(result2); // 'foo'
});

只有当所有Promise都fulfill了,由Promise.all()返回的新Promise才会fulfill,它的结果是一个数组,包含了所有传入的Promise的结果。如果传入的任意一个Promise被reject,新的Promise也会立即reject,并且reject的是第一个Promise的错误信息。

5.5 async和await

5.5.1 什么是aysncawait
  • async 关键字用来定义一个异步函数,函数中的操作默认返回一个Promise。
  • await 关键字只能在async函数中使用,它使异步函数暂停执行,直到Promise解决,然后返回Promise的结果。
5.5.2 使用asyncawait基本示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 定义一个返回Promise的函数
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('数据获取成功'), 1000);
});
}

// 使用async和await获取数据
async function getData() {
console.log('Fetching data...');
const result = await fetchData(); // 等待Promise解决
console.log(result); // 输出:数据获取成功
}

getData();
5.5.3 错误处理

使用asyncawait处理异步操作时,同样需要考虑错误处理。可以通过try...catch块来处理可能的异步操作错误:

1
2
3
4
5
6
7
8
9
10
11
async function getDataWithErrorHandling() {
try {
console.log('Fetching data...');
const result = await fetchData(); // 等待Promise解决
console.log(result); // 输出:数据获取成功
} catch (error) {
console.error('Error fetching data:', error);
}
}

getDataWithErrorHandling();
5.5.4 多个异步操作进行交互
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function fetchData1() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('数据1获取成功'), 1000);
});
}

function fetchData2() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('数据2获取成功'), 500);
});
}

async function fetchDataSequentially() {
try {
const data1 = await fetchData1();
console.log(data1); // 数据1获取成功
const data2 = await fetchData2();
console.log(data2); // 数据2获取成功
} catch (error) {
console.error('Error fetching data:', error);
}
}

fetchDataSequentially();

使用await时,每个异步操作是顺序执行的。这意味着如果你想并行执行多个异步操作,可以使用Promise.all

1
2
3
4
5
6
7
8
9
10
11
async function fetchDataConcurrently() {
try {
const [data1, data2] = await Promise.all([fetchData1(), fetchData2()]);
console.log(data1); // 数据1获取成功
console.log(data2); // 数据2获取成功
} catch (error) {
console.error('Error fetching data:', error);
}
}

fetchDataConcurrently();
5.5.5 总结
  • async函数:定义异步函数,它返回一个Promise。
  • await关键字:暂停async函数的执行,等待Promise解决,并返回结果。它只能在async函数中使用。
  • 错误处理:使用try...catch块在异步函数中处理可能的错误。
  • 顺序操作:将多个异步操作顺序执行,通过多个await

通过使用asyncawait,可以使异步代码看起来更像是同步代码,增强代码的可读性和维护性。