zsmj
2 years ago
8 changed files with 198 additions and 5 deletions
After Width: | Height: | Size: 92 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 43 KiB |
@ -0,0 +1,19 @@
|
||||
# 隐藏与显示组件的冷门知识点 |
||||
|
||||
FineUI中组件`setVisible`方法采用的是`display:none`的形式隐藏组件. |
||||
|
||||
优点大家都知道,不占据DOM流之类的. |
||||
|
||||
但是缺点也很明显,多tab之类的组件,隐藏的元素无法获取宽高,这也是一些"组件缩成一坨"问题的直接原因 |
||||
|
||||
那么为什么不用`visibility:hidden`呢? |
||||
|
||||
其实有个原因是input元素`focus`的特性导致 |
||||
|
||||
采用`visibility:hidden`形式隐藏组件,为了避免鼠标事件触发等,大多会附加一个超大的`top,left`样式,或者`translateX()`超大值,将其挪到屏幕外面 |
||||
|
||||
然而`focus`操作默认有个scrollToView特性,其会不受限制的自动跳到屏幕中间 |
||||
|
||||
![示例](../images/58.png) |
||||
|
||||
例如决策平台的modern主题,开发者无法控制每个打开的tab里面是否会有代码逻辑触发`focus`,因此只能采用`display:none`的形式隐藏tab,否则就容易出现这种位置异常 |
@ -0,0 +1,12 @@
|
||||
# defer和nextTick有什么区别 |
||||
|
||||
研读FineUI代码时,会发现有的地方用了`BI.defer`,有的地方用了`BI.nextTick`,有什么区别呢? |
||||
|
||||
`BI.defer`源自lodash,官方描述是Defers invoking the func until the current call stack has cleared.,翻译一下就是在当前调用栈执行完毕之后调用. |
||||
|
||||
看起来很高大上实际上底层实现就是`settimeout(fn,0)` |
||||
|
||||
`BI.nextTick`的实现相对复杂,采用的是"能力检测"策略,优先使用`Promise.resolve()`,不支持的话使用`MutationObserver`,不支持的话`setImmediate`,还是不支持的话 |
||||
那就只能`settimeout(fn,0)`了 |
||||
|
||||
由此可见,实际作用都是异步的延迟执行某段事务,使用`BI.nextTick`效率会更高一些 |
@ -0,0 +1,137 @@
|
||||
# 空状态提示的若干种实现方式 |
||||
|
||||
![示例](../images/59.png) |
||||
|
||||
## 布局实现 |
||||
|
||||
一般情况下,采用`bi.absolute`布局放置内容和空提示 |
||||
|
||||
```javascript |
||||
const widget = { |
||||
type: "bi.absolute", |
||||
items: [ |
||||
{ |
||||
el: { |
||||
type: "content", |
||||
}, |
||||
inset: 0 |
||||
}, { |
||||
el: { |
||||
type: "empty_tip", |
||||
invisible: () => !this.model.tipVisible |
||||
}, |
||||
inset: 0 |
||||
} |
||||
] |
||||
}; |
||||
``` |
||||
|
||||
## Layers实现 |
||||
|
||||
如果想脱离组件层面,以service的形式对组件施加空状态提示,也可以使用`BI.Layers`控制,实现对任意组件附加空提示 |
||||
|
||||
```javascript |
||||
function createEmptyTyp(widget) { |
||||
const name = BI.UUID(); |
||||
BI.Layers.create(name, null, { |
||||
container: widget, |
||||
render: { |
||||
type: "empty_tip", |
||||
}, |
||||
}); |
||||
|
||||
BI.Layers.show(name); |
||||
return () => { |
||||
BI.Layers.remove(name); |
||||
}; |
||||
} |
||||
``` |
||||
|
||||
## 状态控制 |
||||
|
||||
用独立清晰的状态控制空提示的显示隐藏,避免掺杂在其他状态控制中 |
||||
|
||||
如下示例,在items的watch中"顺带"处理tip组件显示隐藏,使得控制逻辑变的不够清晰 |
||||
|
||||
```javascript |
||||
class model extends Model { |
||||
state = { |
||||
items: [] |
||||
}; |
||||
}; |
||||
|
||||
class widget extends BI.Widget { |
||||
watch = { |
||||
items: (items) => { |
||||
this.list.populate(items); |
||||
this.tip.setVisible(BI.isEmpty(items)); |
||||
} |
||||
}; |
||||
|
||||
render() { |
||||
return { |
||||
type: "bi.absolute", |
||||
items: [ |
||||
{ |
||||
el: { |
||||
type: "content", |
||||
ref: ref => this.list = ref, |
||||
}, |
||||
inset: 0 |
||||
}, { |
||||
el: { |
||||
type: "empty_tip", |
||||
ref: ref => this.tip = ref, |
||||
invisible: !BI.isEmpty(this.model.items) |
||||
}, |
||||
inset: 0 |
||||
} |
||||
] |
||||
}; |
||||
} |
||||
}; |
||||
``` |
||||
将tip显示隐藏的状态独立出来,独立控制,这样状态到视图的映射清晰明了 |
||||
|
||||
```javascript |
||||
class model extends Model { |
||||
state = { |
||||
items: [] |
||||
}; |
||||
|
||||
computed = { |
||||
tipVisible: () => BI.isEmpty(this.model.items) |
||||
}; |
||||
}; |
||||
|
||||
class widget extends BI.Widget { |
||||
watch = { |
||||
items: (items) => { |
||||
this.list.populate(items); |
||||
}, |
||||
tipVisible: b => this.tip.setVisible(b) |
||||
}; |
||||
|
||||
render() { |
||||
return { |
||||
type: "bi.absolute", |
||||
items: [ |
||||
{ |
||||
el: { |
||||
type: "content", |
||||
ref: ref => this.list = ref, |
||||
}, |
||||
inset: 0 |
||||
}, { |
||||
el: { |
||||
type: "empty_tip", |
||||
ref: ref => this.tip = ref, |
||||
invisible: !this.model.tipVisible, |
||||
}, |
||||
inset: 0 |
||||
} |
||||
] |
||||
}; |
||||
} |
||||
}; |
||||
``` |
Loading…
Reference in new issue