Browse Source

update

master
zsmj 2 years ago
parent
commit
4ebbbaa5bb
  1. 5
      README.md
  2. BIN
      images/45.png
  3. 48
      questions/2.如何格式化输出日期.md
  4. 12
      questions/20.如何监听元素大小变化.md
  5. 63
      questions/31.md
  6. 86
      questions/31.响应式中谨慎使用解构.md
  7. 91
      questions/55.watch使用的常见误区.md

5
README.md

@ -6,6 +6,8 @@ FineUI 100个问题题,带你走进FineUI的世界
每一篇md会结合实际场景或问题背景,来阐述原因和解决方案
期望达成的意义是再遇到任何开发中的困惑时,都可以在这里找到答案并产生积累
## 100-Questions列表
---
@ -25,6 +27,7 @@ FineUI 100个问题题,带你走进FineUI的世界
- [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、如何监听元素大小变化](./questions/20.如何监听元素大小变化.md)
### 进阶技巧
@ -58,7 +61,7 @@ FineUI 100个问题题,带你走进FineUI的世界
- [28、defer和nextTick有什么区别](./questions/35.文件上传控件多次选择文件和自定义校验.md)
- [29、为什么说随意修改原始数据时万恶之源?](./questions/35.文件上传控件多次选择文件和自定义校验.md)
- [30、空状态提示的若干种实现方式](./questions/35.文件上传控件多次选择文件和自定义校验.md)
- [31、在computed和响应式中谨慎使用中断](./questions/35.文件上传控件多次选择文件和自定义校验.md)
- [31、在响应式中谨慎使用解构](./questions/31.在响应式中谨慎使用解构.md)
- [32、有没有一种布局方式,在文本保持垂直居中的情况下,文本很多时,可以限制其不超出外层高度 并出现滚动条](./questions/32.有没有一种布局方式,在文本保持垂直居中的情况下,文本很多时,可以限制其不超出外层高度 并出现滚动条.md)
- [33、如何快速的封装自定义combo](./questions/35.文件上传控件多次选择文件和自定义校验.md)
- [33、horizontalAlign:stretch是怎么一回事儿](./questions/35.文件上传控件多次选择文件和自定义校验.md)

BIN
images/45.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

48
questions/2.如何格式化输出日期.md

@ -1 +1,47 @@
# FineUI中如何格式化输出日期
# FineUI中如何格式化输出日期
`BI.print(date,formatStr)`
如果你不知道用什么,那么直接`%Y-%X-%d %H:%M:%S`
约定当前日期为2022年十月八日
## 输出基本年月日格式
```javascript
BI.print(BI.getDate(), "%Y-%X-%d") // '2022-10-08'
BI.print(BI.getDate(), "%Y-%x-%e") // '2022-10-08'
BI.print(BI.getDate(), "%X/%d/%Y") // '10/08/2022'
```
## 输出时分秒格式
```javascript
BI.print(BI.getDate(), "%H:%M:%S") // '16:14:26'
BI.print(BI.getDate(), "%I:%M:%S") // '04:14:26'
BI.print(BI.getDate(), "%k:%M:%S") // '16:14:26'
BI.print(BI.getDate(), "%l:%M:%S") // '4:14:26'
```
## AM与PM区分
```javascript
BI.print(BI.getDate(), "%l:%M:%S %p") // '4:26:12 PM'
BI.print(BI.getDate(), "%l:%M:%S %P") // '4:26:12 pm'
```
## 星期
```javascript
BI.print(BI.getDate(), "%Y-%X-%d %u") // '2022-10-08 7' the day of the week (range 1 to 7, 1 = MON)
BI.print(BI.getDate(), "%Y-%X-%d %w") // '2022-10-08 6' the day of the week (range 0 to 6, 0 = SUN)
```
## 每年的第几周
```javascript
BI.print(BI.getDate(), "%Y-%W") // '2022-40'
```
## 季度
```javascript
BI.print(BI.getDate(), "%Y-%Q") // '2022-4'
BI.print(BI.getDate(), "%Y-%q") // '2022-04'
```

12
questions/20.如何监听元素大小变化.md

@ -1 +1,11 @@
# 如何监听元素大小变化
# 如何监听元素大小变化
广义上讲,FineUI中有两种监听大小变化的方法
`BI.Resizers.add`和`BI.ResizeDetector.addResizeListener`
严格意义上讲`BI.Resizers.add`并不算是监听元素大小变化,其底层实现是监听window的resize事件,只有窗口大小改变时候会触发,多用于combo,layer等自动调整位置的组件.
`BI.ResizeDetector.addResizeListener`则是真实的监听组件元素大小改变,常用于计算动态宽高等场景
注意事项:有添加监听必有取消监听,要注意再组建销毁时移除掉事件监听,有两种形式,一种是在添加监听的方法会返回一个移除当前监听的函数,调用即可.另一种是调用`BI.Resizers.remove`和`BI.ResizeDetector.removeResizeListener`方法

63
questions/31.md

@ -1,63 +0,0 @@
let selectedValues = ["1", "2"];
var Model = BI.inherit(Fix.Model, {
state: function () {
return {
selectedValues: ["1", "2"],
}
},
computed: {
selectedNodes: function () {
return this.model.selectedValues;
}
},
actions: {
setSelectedValue: function (v) {
this.model.selectedValues = v;
}
}
})
BI.model("demo_chooser_combo", Model);
var model = BI.Models.getModel("demo_chooser_combo");
BI.createWidget({
type: "bi.value_chooser_no_bar_combo",
ref: (_ref) => {
this.combo = _ref;
},
value: model.model.selectedValues,
items: [
{
text: "11",
value: "1",
disabled: () => {
var isSelected = !!model.model.selectedNodes.find(value => value === "1");
return !isSelected && model.model.selectedNodes.length >= 2;
}
}, {
text: "22",
value: "2",
disabled: () => {
var isSelected = !!model.model.selectedNodes.find(value => value === "2");
return !isSelected && model.model.selectedNodes.length >= 2;
}
}, {
text: "33",
value: "3",
disabled: () => {
var isSelected = !!model.model.selectedNodes.find(value => value === "3");
return !isSelected && model.model.selectedNodes.length >= 2;
}
}
],
listeners: [
{
eventName: BI.ValueChooserNoBarCombo.EVENT_CLICK_ITEM,
action: () => {
const selectedNodesID = this.combo.getValue();
model.setSelectedValue(selectedNodesID);
},
}
]
});

86
questions/31.响应式中谨慎使用解构.md

@ -0,0 +1,86 @@
# 在响应式中谨慎使用解构
在刚接触编程的时候,我们就学过条件语句中断的特性,在Fix编程中,我们的computed计算属性有很多使用逻辑判断语句的.
**如果某个响应式属性与依赖某个state,那么在书写响应式属性取值函数时需要确保对响应式数据的获取在取值函数内发生.**
即`value = > get observe data and return`
结合一个实际场景举例:
demo代码如下,label的text属性采用响应式形式,min和max提前做了解构,那么当label点击触发修改状态之后,label的文本会随之改变吗?答案显而易见是不会的,因为违背了上面的原则,在text属性的计算函数外获取的state属性
```javascript
const Model = BI.inherit(Fix.Model, {
state: function () {
return {
max: 38,
min: 22,
};
},
actions: {
upup: function () {
this.model.max++;
this.model.min++;
},
},
});
BI.model("demo", Model);
const DemoWidget = BI.inherit(BI.Widget, {
_store: function () {
return BI.Models.getModel("demo");
},
render: function () {
const { min, max } = this.model;
return {
type: "bi.label",
height: 32,
text: () => `最高气温: ${max} 最低气温: ${min}`,
handler: () => {
this.store.upup();
},
};
},
});
BI.shortcut("demo_widget", DemoWidget);
const Demo = BI.createWidget({
type: "demo_widget",
});
```
调整方式也很容易,将state获取写入函数体内
```javascript
render: function () {
return {
type: "bi.label",
height: 32,
text: () => `最高气温: ${this.model.max} 最低气温: ${this.model.min}`,
handler: () => {
this.store.upup();
},
};
},
```
或者在函数体内解构,同样是在函数内部获取state属性
```javascript
render: function () {
return {
type: "bi.label",
height: 32,
text: () => {
const { min, max } = this.model;
return `最高气温: ${max} 最低气温: ${min}`;
},
handler: () => {
this.store.upup();
},
};
},
```

91
questions/55.watch使用的常见误区.md

@ -1,7 +1,92 @@
# watch使用的常见误区
示例
https://code.fineres.com/projects/DEC/repos/decision-webui/pull-requests/7973/diff#src/modules/management/authority/carrierdimenision/entities/system/system.authority.js
## watch职责不单一,掺杂额外处理逻辑
![示例](../images/1.png)
最常见的场景为在watch中掺杂调用loading和loaded方法.这样做的弊端在于loading状态的控制没有形成明显闭环,有可能出现loading触发了,但是没有后续的loaded,导致用于在加载中
```javascript
watch: {
items: function (items) {
this.loading();
// do someting
},
},
```
比较合理的做法是在触发异步获取数据的action中进行loading状态的切换,即异步请求发起前状态切换到loading,请求结束后切换到loaded
```javascript
// model.js
actions: {
getItems: function (items) {
this.model.loading = true;
requestItems().then(() => {
// do something
this.model.loaded = false;
});
},
},
// widget.js
watch: {
loading: function (b) {
b : this.loading() : this.loaded();
},
},
```
## 在组件的watch中回过头来调用store中的action
类似于经济上的出口转内销,在watch中调用action修改状态,进而触发另外的watch.
这样是不优雅的,实际业务中确实存在watch某个状态改变触发action的场景,例如通过watch上层的keyword状态,触发搜索action.
很多同学忽视了其实store中也可以进行watch的,合理的实现是将状态改变全都放在store里,在store中进行watch
不佳的实现
```javascript
// model.js
context: ["keyword"],
state: function () {
return {
b: 22,
};
},
actions: {
changeB: function () {
this.model.b++;
},
},
// widget.js
watch: {
keyword: function () {
this.store.changeB();
},
},
```
更为合理的实现
```javascript
// model.js
context: ["keyword"],
state: function () {
return {
b: 22,
};
},
watch: {
keyword: function () {
this.store.changeB();
},
},
actions: {
changeB: function () {
this.model.b++;
},
},
```
业务代码示例
![示例](../images/45.png)

Loading…
Cancel
Save