其他
柠栀 2020/8/31 其他
# 其他
备注:这个栏目,存放一些过小的问题(不适合单独成一章的),如果后期拓展的很多,就可以考虑单独抽离出去一部分知识
# 🌟第一部分:Git && GitHub
# 1.Git常用命令
# 创建新仓库
git init
# 检出仓库
git clone username@host:/path/to/repository
# 来一次添加所有改变的文件
git add -A .
# 表示添加所有内容
git add -A
# 表示添加新文件和编辑过的文件不包括删除的文件
git add .
# 表示添加编辑或者删除的文件,不包括新添加的文件
git add -u
# 你的改动已经提交到了 HEAD,但是还没到你的远端仓库
git commit -m '代码提交信息'
# 推送改动
git push origin master
# 查看状态
git status
# 查看每个分支的最新提交记录
git branch -av
# 查看每个分支属于哪个远程仓库
git branch -vv
# 下载Git项目
git clone 地址
# 查看用户名
git config user.name
# 查看用户邮箱
git config user.email
# 修改用户名
git config --global user.name "Your_username"
# 修改用户邮箱
git config --global user.email "Your_email"
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
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
# 2.shields.io使用(给项目添加徽章)
- MIT使用举例:https://shields.io/category/license/ (要选GitHub哦)
- 使用说明:https://www.sohu.com/a/134390224_655394
# 💫第二部分:包管理工具(npm)
# 1.npm基本使用
# 初始化项目(也可以写 npm init -y)
npm init
# 安装(简写 npm i)
npm install
# 帮助(简写 npm -h)
npm --help
# 全局标志(简写 -g)
--global
# 保存为开发依赖(简写 -D)
--save-dev
# 保存为生产依赖(简写 -d)
--save
# 卸载npm安装的包
npm uninstall 包的名称 -g
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
设置 npm init属性,这样在初始化的时候,就不用每次都写了
npm config set init.author.name "Zhu Kunpeng" npm config set init.author.email "270750933@qq.com" npm config set init.author.url "itzkp.com" npm config set init.license "MIT"
让脚本跨平台兼容:cross-env
- 安装:npm i -D cross-env
// 然后在任何环境变量之前包括关键字cross-env,如下
{
"scripts": {
"dev": "cross-env node app.js"
}
}
1
2
3
4
5
6
2
3
4
5
6
参考掘金文章,作者小智,感谢 (opens new window)
# 2.发布包到NPM上
# 登录(会让你输入账号密码,邮箱)
npm adduser
# 上传(注意package.json里面的name不要和npm仓库重复)
npm publish
1
2
3
4
5
6
2
3
4
5
6
# ✨第三部分:前端工程化工具(Webpack)
- 首先肯定要 npm init
- 安装webpack:npm i webpack webpack-cli -D
- 新建 webpack.config.js 文件
- 常用loader
- npm i file-loader -D (用于移动字体文件等)
- npm i url-loader -D(用于打包图片等)
- npm i css-loader style-loader -D(打包基础CSS样式文件)
- npm i node-sass sass-loader -D(打包scss样式文件)
- npm i postcss-loader autoprefixer -D(自动添加厂商前缀,需要建立一个新的文件 postcss.config.js )
- 常用plugin
- npm i html-webpack-plugin -D (会在打包完成之后,自动生成一个HTML文件,并把打包之后的JS自动引入到这个HTML文件中)
- 其他
- SourceMap
- WebpackDevServer
- Hot Module Replacement
// webpack.config.js 配置示例
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
export default {
// 环境(默认是production,开启压缩等默认配置 || development是开发环境,不压缩...)
mode: 'production',
// 有了这个在就能在出错的时候,准确定位到是哪里的问题,这个devtool 还有很多配置,具体查阅文档
devtool: 'cheap-module-eval-source-map',
// 启动一个serve:npx webpack-dev-server
devServer: {
contentBase: './dist', // 启动的目录
open: true, // 自动打开浏览器
hot: true, // 启动热更新
hotOnly: true // 不刷新页面
},
// 入口:简写 entry: '入口文件地址'
entry: {
main: '入口文件地址',
// main2: '入口文件2地址' 多文件入口
},
// 模块规则
module: {
rules: [
// file-loader
{
test: /\.(字体文件后缀)$/,
use: {
loader: 'file-loader',
options: {
name: '[name].[ext]', //
outputPath: 'font/' // 打包输出文件夹
}
}
},
// url-loader
{
test: /\.(jpg|png|gif)$/,
use: {
loader: 'url-loader',
options: {
name: '[name].[ext]', //
outputPath: 'images/', // 打包输出文件夹
limit: 2048 // 如果小于 2kb,就会打包进JS,如果大于就打包到文件夹中
}
}
},
// 打包静态样式
{
test: '/\.css$/',
use: ['style-loader', 'css-loader', 'sass-loader', 'postcss-loader']
}
]
}
// 插件
plugins: [
new HtmlWebpackPlugin({
// 配置,index.html 模板,以此为模板进行注入
template: './test/index.html'
})
]
// 输入
output: {
filename: '输入文件名', // 输出文件夹名称, 可以使用占位符, 例如'[name]_[hash].[ext]'
publicPath: 'https://cdn.com.cn', // 配置引入前缀,如果静态资源在CDN上这个很有用
path: path.resolve(__dirname, '输入文件夹') // 输入目录
},
}
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
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
postcss.config.js 配置示例
// 默认是这样写的
module.exports = {
parser: 'sugarss',
plugins: {
'postcss-import': {},
'postcss-cssnext': {},
'cssnano': {}
}
}
// 我们也可以这么写
// 这么写的作用是,当我们使用 postcss-loader 的时候,会使用 autoprefixer 这个插件
module.exports = {
plugins: [
require('autoprefixer')
]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.babelrc 配置示例
1
# ☀️第四部分:测试(Jest)
# 1.Jest 常用匹配器速查
// ========== 和真假相关的匹配器 ===========
expect(1).toBe(1) // 通过:有点类似于 ===
expect({ name: '柠栀' }).toEqual({ name: '柠栀' }) // 通过:匹配内容相等
expect(null).toBeNull() // 通过:匹配是否是 null
expect(undefined).toBeUndefined() // 通过:匹配是否是 undefined
expect(true).toBetruthy() // 通过:匹配 是否为真,填 1 也行
expect(0).toBeFalsy() // 通过:匹配是否为假,填 false 也行
expect(0).not.toBeFalsy() // 不通过:可以通过 not 进行取反
// ...
// ========== 和数字相关的匹配器 ===========
expect(10).toBeGreaterThan(9) // 通过,匹配的是 10 是否 比 9 大
expect(10).toBeLessThan(11) // 通过,匹配的是 10 是否 比 11 小
expect(10).toBeGreaterThanOrEqual(10) // 通过,匹配的是 10 是否 大于等于 10
expect(11).toBeLessThanOrEqual(11) // 通过,匹配的是 11 是否小于等于 11
expect(0.1 + 0.2).toBeCloseTo(0.3) // 通过,判断小数是否相同,直接比较的话会有精度缺失的问题,比较不了
// ...
// ========= 和字符串相关的匹配器 ===========
expect('柠栀').toMatch('栀') // 通过,匹配的是 '柠栀' 中是否有 '栀' 字符 | 还可以写正则表达式
// ...
// ========= 和数组相关的匹配器 ===========
expect([1,2,3]).toContain(2) // 通过,匹配的是 数组中 是否包含 2 这一项,也可以判断 Set, Map 这种类型的
// ...
// ========= 和异常相关的匹配器 ===========
expect(throw new Error('出现错误')).toThrow() // 通过,匹配的是 是否出现异常
// ...
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
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
# ❄️第五部分:CSS预处理器
# 💥第六部分:跨平台开发(Electron)
# 🔥第七部分:日常开发中总结出来的组件(移动端)
# 1.弹框组件(DialogGray.vue)
使用方法
<dialog-gray v-model="dialogVisible" :opacity="opacity" :is-click="isClick">
//opacity 蒙层透明度 不传默认为.5
//isClick 蒙层是否可点击 默认可点击,传false即不可点击
//阻止点击冒泡在蒙层内部加@click.stop
//阻止滑动冒泡在蒙层内部加@touchmove.stop
//弹窗过大,内部div加class="part-scroll" 去掉滚动条:.part-scroll::-webkit-scrollbar {display: none;}
</dialog-gray>
1
2
3
4
5
6
7
2
3
4
5
6
7
<template>
<div
v-if="dialogVisible"
ref="dialogGray"
class="dialogSt"
:style="background"
@click="closeDia"
@touchmove.stop.prevent
>
<slot />
</div>
</template>
<script>
export default {
name: 'DialogGray',
model: {
prop: 'dialogVisible',
event: 'change'
},
props: {
dialogVisible: {
type: Boolean,
default: false
},
opacity: {
type: Number,
default: 0.5
},
isClick: {
type: Boolean,
default: true
}
},
data() {
return {
top: '',
background: {
'background': `rgba(0,0,0,${this.opacity})`
}
};
},
watch: {
dialogVisible: {
immediate: true,
handler(newval) {
const bodyEl = document.body;
if (newval) {
this.$nextTick(() => {
bodyEl.appendChild(this.$refs['dialogGray']);
});
this.top = window.scrollY;
bodyEl.style.position = 'fixed';
bodyEl.style.top = -this.top + 'px';
} else {
bodyEl.style.position = '';
bodyEl.style.top = '';
window.scrollTo(0, this.top); // 回到原先的top
}
}
}
},
methods: {
closeDia() {
if (!this.isClick) {
return;
}
this.$emit('change', false);
}
}
};
</script>
<style scoped>
.dialogSt {
position: fixed;
width: 100%;
height: 100%;
z-index: 99;
left: 0;
top: 0;
display: flex;
align-items: center;
justify-content: center;
}
</style>
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
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
# 2.奖励轮播组件(RewardWheel.vue)
使用方法
<reward-wheel
:wheel-row-height="23"
:wheel-rem-size="37.5"
:wheel-time="4000"
:wheel-number="playMsg.length - 2">
<!-- 书写业务代码区域 -->
<div></div>
</reward-wheel>
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- wheel-row-height:滚动的距离
- wheel-rem-size:rem相对单位(适配用)
- wheel-time:滚动一个的时间
- wheel-number:滚动的数量
<template>
<div :style="loopStyle">
<slot />
</div>
</template>
<script>
export default {
props: {
// 默认轮播数量
wheelNumber: {
type: Number,
default: 0
},
// 轮播一个需要的时间
wheelTime: {
type: Number,
default: 3000
},
// 每次滚动的距离
wheelRowHeight: {
type: Number,
default: 10
},
// 当前环境rem对px的值
wheelRemSize: {
type: Number,
default: 32
}
},
data() {
return {
// 中奖信息(轮播)
loopStyle: {
transform: '',
transition: 'none'
},
activeIndex: 0
};
},
watch: {
activeIndex(val) {
const transition = this.activeIndex === 0
? 'none'
: 'all .5s';
const top = ((-val * this.wheelRowHeight) / this.wheelRemSize) + 'rem';
this.loopStyle = {
transform: `translateY(${top})`,
transition: transition
};
}
},
mounted() {
this.loopListTool(); // 自动轮播函数
this.distanceAdaptationTool(); // 自动适配各个屏幕滚动距离
},
methods: {
// 自动轮播函数
loopListTool() {
this.$nextTick(() => {
window.clearInterval(this.interval);
this.interval = setInterval(() => {
if (this.activeIndex < this.wheelNumber - 1) {
this.activeIndex += 1;
} else {
this.activeIndex = 0;
}
}, this.wheelTime);
});
},
// 自动适配各个屏幕滚动距离
distanceAdaptationTool() {
const rem = this.wheelRowHeight / this.wheelRemSize;
this.wheelRemSize = document.documentElement.clientWidth / 10;
this.wheelRowHeight = rem * this.wheelRemSize;
}
}
};
</script>
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
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
- end-time-data: 结束时间 | String(xxxx-xx-xx xx:xx:xx)或者 Number(时间戳)
- @time-end: 倒计时结束的时候触发
# 3.倒计时组件(CountDown.vue)
使用方法
<!-- end-time-data:2020-01-30 00:00:00 -->
<div style="padding: 5px; border: 1px solid red;" >
<count-down
:end-time="1580313600000"
@time-end="timeEndEvent">
</count-down>
</div>
1
2
3
4
5
6
7
2
3
4
5
6
7
<template>
<div>
{{ time }}
</div>
</template>
<script>
export default {
props: {
// 结束时间
endTime: {
type: [Number, String],
default: null
}
},
data() {
return {
time: '', // 时间展示
flag: false // 是否启动时间
};
},
mounted() {
this.visibilitychangeEvent();
this.init();
},
methods: {
init() {
if (this.endTime === null) return;
const time = setInterval(() => {
if (this.flag == true) {
clearInterval(time);
return;
}
this.timeDown();
}, 500);
},
// 倒计时组件 核心逻辑
timeDown() {
// 结束时间
let endTimeData = null;
typeof this.endTime === 'number'
? endTimeData = new Date(this.endTime)
: endTimeData = this.timeStrToCorrectTool(this.endTime);
// 当前时间(默认是系统当前时间)
const nowTime = new Date();
// 相差时间
const leftTime = parseInt((endTimeData.getTime() - nowTime.getTime()) / 1000);
if (leftTime <= 0) {
this.time = `0小时 0分 0秒`;
this.flag = true;
this.$nextTick(() => {
this.$emit('time-end');
});
return;
}
const d = parseInt(leftTime / (24 * 60 * 60));
const h = this.formateTool(parseInt(leftTime / (60 * 60) % 24 + d * 24));
const m = this.formateTool(parseInt(leftTime / 60 % 60));
const s = this.formateTool(parseInt(leftTime % 60));
this.time = `${h}小时 ${m}分 ${s}秒`;
},
// 将小于10的数 转为 0开头的
formateTool(time) {
return time >= 10
? time
: `0${time}`;
},
// 兼容IOS 日期字符串 格式NaN的问题
timeStrToCorrectTool(endTime) {
const arr = endTime.split(/[- :]/);
const endTimeData = new Date(arr[0], arr[1] - 1, arr[2], arr[3], arr[4], arr[5]);
return endTimeData;
},
// 息屏检测事件,防止定时器关闭
visibilitychangeEvent() {
document.addEventListener('visibilitychange', () => {
this.init();
}, false);
}
}
};
</script>
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
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