Compare commits

...

2 Commits

Author SHA1 Message Date
zsmj 50f4783eff Merge remote-tracking branch 'origin/master' 2 years ago
zsmj 5493a0527b update 2 years ago
  1. 11
      README.md
  2. BIN
      images/37.png
  3. BIN
      images/38.png
  4. 74
      questions/4.结合语义化、可读性和程序性能选择遍历方法.md
  5. 81
      questions/z-index解析以及在FineUI中使用原则.md

11
README.md

@ -16,18 +16,15 @@ FineUI 100个问题题,带你走进FineUI的世界
- [1、前端如何正确书写资源路径](https://code.fanruan.com/dailer/FineUI-100-Questions/src/branch/master/questions/50.前端如何正确书写资源路径.md)
- [2、组件的代码设计基本思路](https://code.fanruan.com/dailer/FineUI-100-Questions/src/branch/master/questions/2.组件的代码设计基本思路.md)
- [3、如何获取当前时间](https://code.fanruan.com/dailer/FineUI-100-Questions/src/branch/master/questions/1.如何获取当前时间.md)
- [4、结合语义化、可读性和程序性能选择遍历方法](https://code.fanruan.com/dailer/FineUI-100-Questions/src/branch/master/questions/2.如何格式化输出日期.md)
- [4、结合语义化、可读性和程序性能选择遍历方法](./questions/4.结合语义化、可读性和程序性能选择遍历方法.md)
- [5、关于组件引用的奥秘,ref知多少](https://code.fanruan.com/dailer/FineUI-100-Questions/src/branch/master/questions/3.关于组件引用的奥秘,ref知多少.md)
- [6、使用ButtonGroup控制可点击组件的控制选中状态](https://code.fanruan.com/dailer/FineUI-100-Questions/src/branch/master/questions/4.使用ButtonGroup控制可点击组件的控制选中状态.md)
- [7、我们为什么要设计el这个属性](https://code.fanruan.com/dailer/FineUI-100-Questions/src/branch/master/questions/40.我们为什么要设计el这个属性.md)
- [8、常用遍历方法和FineUI中内置遍历方法](https://code.fanruan.com/dailer/FineUI-100-Questions/src/branch/master/questions/2.组件的代码设计基本思路.md)
- [9、z-index究竟是怎么回事](https://code.fanruan.com/dailer/FineUI-100-Questions/src/branch/master/questions/1.如何获取当前时间.md)
- [9、z-index究竟是怎么回事](./z-index解析以及在FineUI中使用原则.md)
- [10、computed通俗易懂的原理解析和日常排错](https://code.fanruan.com/dailer/FineUI-100-Questions/src/branch/master/questions/1.如何获取当前时间.md)
- [11、绝对布局的隐藏知识点](https://code.fanruan.com/dailer/FineUI-100-Questions/src/branch/master/questions/41.绝对布局的隐藏知识点.md)
- [12、如何灵活应用布局组件,尽可能的减少DOM数量?](https://code.fanruan.com/dailer/FineUI-100-Questions/src/branch/master/questions/41.绝对布局的隐藏知识点.md)
- [13、何时会滚动,滚动条位置如何贴边,究竟是怎么回事](https://code.fanruan.com/dailer/FineUI-100-Questions/src/branch/master/questions/42.何时会滚动,滚动条位置如何贴边,究竟是怎么回事.md)
- [14、结合语义化、可读性和程序性能选择遍历方法](https://code.fanruan.com/dailer/FineUI-100-Questions/src/branch/master/questions/42.何时会滚动,滚动条位置如何贴边,究竟是怎么回事.md)
### 进阶技巧
@ -60,7 +57,9 @@ FineUI 100个问题题,带你走进FineUI的世界
- [27、effect的妙用](./questions/35.文件上传控件多次选择文件和自定义校验.md)
- [28、defer和nextTick有什么区别](./questions/35.文件上传控件多次选择文件和自定义校验.md)
- [29、为什么说随意修改原始数据时万恶之源?](./questions/35.文件上传控件多次选择文件和自定义校验.md)
- [23、在computed和响应式中谨慎使用中断](./questions/35.文件上传控件多次选择文件和自定义校验.md)
- [30、空状态提示的若干种实现方式](./questions/35.文件上传控件多次选择文件和自定义校验.md)
- [31、在computed和响应式中谨慎使用中断](./questions/35.文件上传控件多次选择文件和自定义校验.md)
### 代码之外

BIN
images/37.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

BIN
images/38.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

74
questions/4.结合语义化、可读性和程序性能选择遍历方法.md

@ -0,0 +1,74 @@
# 结合语义化、可读性和程序性能选择遍历方法
在实际开发中,经常会用到遍历方法对集合进行判断,过滤,筛选等.
对于ES5年代,我们大多依托基于lodash封装的`BI.each,BI.map,BI.some,BI.filter`方法,ES6时代,原生的`forEach,map,filter`等方法经常被使用
我们这里分析一下如何结合语义化、可读性和性能选择合适的遍历方法
## BI.xxx和原生的遍历方法有什么区别?
1. BI.xxx方法保留了JQuery年代遍历方法的使用习惯,迭代调用的函数参数顺序为`(index,value)`,因此现在大多情况下,我们推荐使用原生遍历方法
2. BI.each方法可以遍历对象,原生javascript并未提供相应方法,`for...in`和`for..of`都无法同时获取key-value
## 语义化可读性的原则
1. 如果你需要将数组按照某种规则映射为另一个数组,就应该用map
2. 如果你需要进行简单的遍历,用forEach
3. 如果你需要提前中断迭代,那么使用some或every
4. 如果你需要过滤出符合条件的项,用filter
5. 如果你需要遍历数组累计计算出某个结果,那可以用reduce
6. 如果你需要先根据条件过滤,再按照规则映射为新数组,那就用filter加一个map
实际场景举例
```javascript
// 利用some提前中断的特性减少遍历
const arr = [1, 3, 4, 7];
const hasEven = arr.some(v => v % 2 === 0);
const allOdd = arr.every(v => v % 2 === 1);
```
```javascript
// 迭代累计结果,两种实现并无高低之分,但求简单易懂
const arr = [1, 3, 4, 7];
const allCount1 = arr.reduce((previousValue, currentValue) => previousValue + currentValue, 0);
let allCount2 = 0;
arr.forEach(v => allCount2 += v);
```
## 既要有性能意识,又无需过度追求性能
绝大多数情况,我们无需考虑究竟是`forEach`更快,还是`for...in`更快,我们的主要目标是写出清晰,稳定,可持续的代码.
与此同时,我们有尽量避免一些显而易见的代码缺陷,一个常见的误区是在遍历中重复进行额外的遍历.
对于在循环遍历中可以保持不变的信息,可以在遍历之外提前计算好再使用
```javascript
const arr1 = [
{
name: "xiaoming",
age: 17
}, {
name: "dashan",
age: 28
}
];
const arr2 = [14, 25, 36, 17];
// 每次都要进行map
arr2.forEach(v => {
if (arr1.map(j => j.age).includes(v)) {
console.log(true);
}
});
// 对不变数据进行预先提取
const ages = arr1.map(j => j.age);
arr2.forEach(v => {
if (ages.includes(v)) {
console.log(true);
}
});
```

81
questions/z-index解析以及在FineUI中使用原则.md

@ -0,0 +1,81 @@
# z-index解析以及在FineUI中使用原则
z-index问题一直是前端开发人员的噩梦
代码review过程中反复强调z-index解析以及在FineUI中使用原则:
<b>"不要滥用z-index,只有当你充分理解原理并确定要通过z-index解决的时候,方可使用"</b>
从直觉上,z-index越大的元素排在上面是理所当然的,但是实际上这是不全面的,z-index不是全局的,设置了z-index的元素只会和与他处在同一stacking contexts的元素进行比较
可以思考一下,为什么我们的气泡默认的container属性是body呢,不可以放到当前的容器里面吗?因为stacking contexts的关系,即使弹出气泡的z-index很大,也会出现被遮住的情况
```javascript
BI.createWidget({
type: "bi.horizontal_auto",
items: [
{
type: "bi.label",
text: "我的z-index是2",
height: 50,
width: 100,
cls: "bi-background bi-border",
css: {
zIndex: 2,
},
}, {
type: "bi.horizontal_auto",
css: {
zIndex: 1, // 因为这里产生了一个stacking context,因此无论popup的z-index多高,他都会在label的下面
},
items: [
{
type: "bi.bubble_combo",
width: 100,
height: 30,
el: {
type: "bi.button",
text: "点击弹出",
},
container: this, // 默认container为body,这里手动改为当前元素
direction: "top",
popup: {
el: {
type: "bi.label",
text: "我的z-index是10000000",
},
},
},
],
},
],
});
```
![示例1](../images/38.png)
## 创建stacking contexts的几种方式
详细场景可以参考MDN文档,这里只列举几个常见的
[the_stacking_context](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context#the_stacking_context)
- html根节点
- opacity的值小于1
- position:absolute 或 position:relative 且带有z-index属性
- position:fixed 或 position:sticky
- 父容器是 display:flex 或 display:grid 且子元素自己带有z-index属性
- transform属性
- isolation: isolation 直接创建上下文
如果觉得通过查看代码不能够直观的分辨stacking contexts,那么推荐一个插件[CSS Stacking Context inspector](https://chrome.google.com/webstore/detail/css-stacking-context-insp/apjeljpachdcjkgnamgppgfkmddadcki)
能够自动识别stacking context结构,并注明产生stacking context的原因
![示例2](../images/37.png)
## 在什么情况下需要使用z-index来解决问题呢
除FineUI内部使用z-index之外,常见业务开发中使用z-index的例子
1. 在某个元素上悬浮显示,且超出容器边界的,例如拖拽宽度的图标.
2. 仪表板组件自由排列叠放布局
3. 没了
Loading…
Cancel
Save