背景
为什么:存在哪些问题
怎么做
项目的一些优化方向
1、配置dll 或者 使用 externals
2、然后 用 BundleAnalyzerPlugin 看看boundle 。看还有啥优化的。 做代码分割
骨架图 实践
1 | npm install --save-dev page-skeleton-webpack-plugin |
Do things better
1、配置dll 或者 使用 externals
2、然后 用 BundleAnalyzerPlugin 看看boundle 。看还有啥优化的。 做代码分割
1 | npm install --save-dev page-skeleton-webpack-plugin |
viewport-fit 控制文档如何填充满足整个屏幕
1 | <meta name="viewport" content="viewport-fit=cover" /> |
// 不影响初始布局,整个web页面可以查看
viewport-fit: auto;
// 按照比例缩放,以显示内嵌的最大矩形
viewport-fit: contain;
// 视图端口被缩放以填充设备显示
viewport-fit: cover;1
2
3
4
5
6
7
8
9
10
// 建议:如果使用 viewport-fit=cover 最好使用 safe-area 变量,确保重要内容不会显示在视口之外
body {
padding:
env(safe-area-inset-top, 20px)
env(safe-area-inset-right, 20px)
env(safe-area-inset-bottom, 20px)
env(safe-area-inset-left, 20px);
}
env 将用户代理的环境变量插入在css 中
1 | env( <custom-ident> , <declaration-value>? ) |
custom-ident:指用户自定义字符串标识符。一种CSS 数据类型;要区分大小写,值不能有任何歧义
1 | env(safe-area-inset-bottom); |
safe-area-inset-top, safe-area-inset-right, safe-area-inset-bottom, safe-area-inset-left
safe-area-inset-*由四个定义了视口边缘内矩形的 top, right, bottom 和 left 的环境变量组成,这样可以安全地放入内容,而不会有被非矩形的显示切断的风险。对于矩形视口,例如普通的笔记本电脑显示器,其值等于零。 对于非矩形显示器(如圆形表盘,iPhoneX屏幕),在用户代理设置的四个值形成的矩形内,所有内容均可见。
注意: 不同于其他的 CSS 属性,用户代理定义的属性名字对大小写敏感。
支持: chrome 69+
解决方案:
1、meta 的 viewport content 值增加 viewport-fit=cover
2、如果是固底的 tab-bar 使用 env(safe-area-inset-bottom),其他情况按照场景设置其他的值
1 | padding-top: constant(safe-area-inset-top); // ios < 11.2 |
winter 直播的思想摘要:
0、基础:
编程能力:
架构能力:
工程化能力:
1、前端知识
2、领域知识:和业务相关性强
电商 -> 新零售
解决通用型问题
刻意练习
看到了就学习。不要太功利了,过多思考到底要不要取学。
架构能力,多去学习其他的框架
如何学习原代码?不要通读,有目的性的,可以去学习其他的。
刻意练习:
建立知识体系
知识整理法:
顺序关系
组合关系
维度关系: 词法 语意 运行时
分类关系
追溯法 -> 标准文档 -> 大师
什么时候好的面试题?
区分度:
覆盖面:
打断和争论
loader:
webpack 只能理解 JavaScript 和 JSON 文件。
loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效模块,以供应用程序使用,以及被添加到依赖图中
对模版文件资源文件等需要预处理的文件进行转化和预处理,提供前端构建的方法
用于对模块的源码进行转换。 在import 或者加载的时候预处理文件
plugins:
解决 loader 无法解决的其他问题,执行范围更广的任务,包括:打包优化,资源管理,注入环境变量
entry:
构建依赖图的开始的模块
output:
在哪里输出创建的 bundle 。以及如何命名这些文件
mode: development, production, none
browswer compatibility
安装 node.js
安装 nvm 或 n ( 管理node 版本)
1 | mkdir webpack-project |
1 | npm install webpack webpack-cli --save-dev |
webpack.config.js 配置文件
1 | { |
node_modules/.bin/webpack
通常状态下我们会使用软连接,来简化我们使用命令
在 package.json scripts 中配置
1 | "scripts": { |
在终端中使用 npm run build
当我们在项目中使用 ES6 、ES7 要使用babel 进行转化
使用 babel
安装
1 | npm i @babel/core @babel/preset-env @babel-loader -D |
“@babel/preset-env” 是常用环境的预设
创建 .babelirc 文件
1 |
|
使用 react
1 | npm i react react-dom @babel/preset-react -d |
最终1
2
3
4
5
6
7
{
"presets": [
"@babel/preset-env"
"@babel/preset-react"
]
}
补充中:
// 解析es6 和 react jsx
// 解析 less css
/// 解析图片和字体
文件监听
–watch 需要手动刷新
webpack.confog.js
watch: true
热更新
webpack-dev-middleware
文件指纹 —> 版本发布
文件压缩
ugliyfy
optimize
html-webpack-plugin 设置 minify
postcss-loader auto-prefix
to rem
raw-loder
多页面打包
source-map
webpack 增强功能
clean-webpack-plugin
自动补全
splitChunksPlugin
scope hoiting
备忘:
npm install 安装依赖
npm run upload ——> git pull
npm run publish –> vue-cli-servce build && npm run cdn
遍历:
forEach 遍历
forEach() 遍历的范围在第一次调用 callback 前就会确定。调用 forEach 后添加到数组中的项不会被 callback 访问到。如果已经存在的值被改变,则传递给 callback 的值是 forEach() 遍历到他们那一刻的值。已删除的项不会被遍历到。如果已访问的元素在迭代时被删除了(例如使用 shift()),之后的元素将被跳过:forEach() 不会在迭代之前创建数组的副本1
2
3
4
5
6
7
8
9
10var words = ['one', 'two', 'three', 'four'];
words.forEach(function(word) {
console.log(word);
if (word === 'two') {
words.shift();
}
});
// one
// two
// four
every 所有满足XXX 返回 Boolean
some 一部分满足XXX 返回 Boolean
filter 过滤器 返回满足条件的新的数组
map 可以对原来的数组进行修改,返回新的数组
修改
push 尾部插入一个或者镀铬数据,并返回长度
pop 删除并返回数组最后一个元素
shift 删除并返回第一个元素
unshift 头部插入一个几个元素,并返回长度
splice(index, howmaany, item1, item2) 向数组中添加/删除项目,index 删除/添加的位置 howmany 删除的数量 item 可选项,向数组里增加的项目 删除:返回被删除的元素数组 添加: 返回空数组
reverse() 反转数组
sort() 在原数组上进行排序 不生成副本 没有排序函数按照字符编码的顺序进行排序
提供了比较函数:
比较函数应该具有两个参数 a 和 b,其返回值如下:
若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。
若 a 等于 b,则返回 0。
若 a 大于 b,则返回一个大于 0 的值。
1 | // 从大到小 |
其他:
map(callback(currentValue, index, array),thisArg)创建一个新的数组
slice(start, end) 不会修改原数组,返回数组中被选定的元素的子数组 但是数组内的数据仍指向同一个引用
concat(arry1,array2,…) 连接数组 array1 可以是具体的值,页可以是数组 不会改变现有数组,返回被连接的现有数组的副本
toString()
oLocalString()
join() 数组转换字符串
indexOf(item, start) item 类型string 只能检测简单的数据类型
lastIndexOf(item, start) item 类型string 只能检测简单的数据类型
find(callback (element, index,array) {}) 返回找到符合条件的第一个元素后停止。如果没有返回undefined
findIndex(function() {}
———- ES6 ———–
copyWithin(target, [start], [end]) 复制数组的一部分到同一个数组的另一个位置,并返回,不会改变原数组的长度
fill() 使用给定值填充数组
entries() 返回新的 Array iterator 对象,改对象包含数组中每个索引的键值对
keys() 键名
values() 键值
includes() 返回(Boolean)是否包含给定的值 和indexOf() 相比更加的语义化,并且 indexOf 会对 NAN 进行误判
flat() 拉平数组1
2
3
4
5// 拉平一层 [1,2,3,[4,5]]
[1,2,[3,[4,5]]].flat(1)
// 拉平2层 【1,2,3,4,5】
[1,2,[3,[4,5]]].flat(2)
flatMap()
valueOf()
Array.isArray()
Array.from(arraylike,mapfn) 从一个类数组或可迭代对象创建一个新的浅拷贝的数组实例。
arraylike
伪数组对象(拥有一个 length 属性和若干索引属性的任意对象)
可迭代对象(可以获取对象中的元素,如 Map和 Set 等)
1 | // 从 String 生成数组 |
Array.of() 用于创建数组,弥补Array 够袄函数因为参数个数不同引起的重载
1 | var a = [1,22,3,7] |
因为 push 方法参数不能为数组
1 |
|
数组是复合数据类型,直接复制只是复制了底层数据结构的指针,不是克隆一个全新的数组
1 | const a = [1,23] |
1 | const a = [1,2,3] |
需要注意的是:上面两种方法都是数组的浅拷贝 (c 和 d 是两种不同方式合并生成的数组,但是成员都是对原数组成员的引用,这就是浅拷贝),如果修改了引用的值,会同步反应到新的数组
1 | [...'string'].length |
####
BOM 浏览器对象模型
允许js 和浏览器进行通信
获取浏览器的宽度和高度
历史记录
window
screen
histroy 对象 back forward back go
Location 对象 href hostname pathname assign
navigator 对象 jsEnabled / onLine /userAgent
navigator 中常用的一些属性
userAgent 返回又浏览器发送给服务器的用户代理报头
可以用来判断浏览器的系统版本
connection 我刚落连接信息 (不可靠)
geolocation 地理位置信息 。处于安全策略考虑 网站协议必须伟https
来自navigator 的对象信息有些是误导性的
time 定时器对象 setTimeout() setInterval()
弹出框: alert confirm prompt
cookies document.cookies
表示集合的数据结构:
Array Object Map Set
Iterator 遍历器 是为各种数据结构,提供一个统一的、简便的访问接口;
使数据结构的成员能够按照某种次序排列
ES6 的新的遍历命令 for…of
Iterator 本质是一个指针对象
调用 next 方法
原生具备:iterrator 的接口的数据结构如下:
Array
Map
Set
String
TypedArray
函数的 arguments 对象
NodeList 对象
Object 本质上是键值对的集合 但是只能使用字符串当键
Map 类似于对象,也是键值对的集合,但是‘键’的范围不局限于字符串,各种类型的值都可以当作键
map 构造函数接受具有iterator 接口,并且每个成员方法都是双元素的数组([key,value])的结构都可以当作Map的参数
1 | let map = new Map([ |
只有针对同一个值的引用,Map 结构才将其视为同一个键1
2
3let map = new Map()
map.set(['a'],1)
map.get(['a']) // undefined
看下面的例子就会理解
1 | const map = new Map(); |
变量k1和k2的值是一样的,但是它们在 Map 结构中被视为两个键,因为k1 和 k2 指向不同的引用
由上可知,Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。
这就解决了同名属性碰撞(clash)的问题,我们扩展别人的库的时候,如果使用对象作为键名,就不用担心自己的属性与原作者的属性同名。
如果 Map 的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map 将其视为一个键,比如0和-0就是一个键,布尔值true和字符串true则是两个不同的键。另外,undefined和null也是两个不同的键。虽然NaN不严格相等于自身,但 Map 将其视为同一个键。
clear方法清除所有成员,没有返回值。
遍历方法 keys values entries foreach
1 | const map = new Map([ |
// Map 转为数组 …
1 | const myMap = new Map() |
// 数组 转为 Map
1 | new Map([ |
// Map 转为对象 如果所有 Map 的键都是字符串,它可以无损地转为对象。 如果有非字符串的键名,那么这个键名会被转成字符串,再作为对象的键名
1 | function strMapToObj(strMap) { |
对象转为 Map1
2let obj = {"a":1, "b":2};
let map = new Map(Object.entries(obj));
json1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16json1 = '{"n1":123, "n2": {"a":1, "b": 2}}'
json2 = '"[{"a":1,"b":2},{"c":333,"d":{"d":1}}]"'
// json 转换为 map
let obj = JSON.parse(json1)
let map1 = new Map(Object.entries(obj))
obj = [
{a: 1,
b:2},
{c: 333,
d:{d:1
}}
]
m1 = new Map(Object.entries(JSON.parse(JSON.stringfy(obj))))
set 类似数组,值唯一(区分类型)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21let set = new Set([])
// 属性
set.constructor
set.size
// 添加某个值(不会添加重复的值) 返回set本身
set.add(value)
// 删除某个值 返回 Boolean 是否成功
set.delete(value)
// 返回 Boolean 是否存在
set.has(value)
// 清除所有 没有返回值
set.clear()
// 将set 转化为数组
let array = Array.from(set)
数组去重复
1 | function dedupe (array) { |
forEach, keys, values, entries 遍历 keys 和 values 一致
Set 结构的实例默认可遍历,它的默认遍历器生成函数就是它的values方法。
Set.prototype[Symbol.iterator] === Set.prototype.values
可以使用for…of 遍历
可以使用扩展运算符
let array = […set]
set 实现集合的交 并 差
1 | let a = new Set([1,2,3]) |
缺失模块。
1、请确保node版本大于6.2
2、在博客根目录(注意不是yilia根目录)执行以下命令:
npm i hexo-generator-json-content --save
3、在根目录_config.yml里添加配置:
jsonContent: meta: false pages: false posts: title: true date: true path: true text: false raw: false content: false slug: false updated: false comments: false link: false permalink: false excerpt: false categories: false tags: true