You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
5.2 KiB
174 lines
5.2 KiB
2 years ago
|
# 组件的代码设计基本思路
|
||
|
|
||
|
我们以一个分页组件为例,阐述一下FineUI中组件代码的基本思路
|
||
|
|
||
|
## 控件功能
|
||
|
|
||
|
上一页,下一页,带个输入框,有总页数.四个按钮带disabled逻辑,无上一页或者下一页时候灰化
|
||
|
|
||
|
![示例](../images/9.png)
|
||
|
|
||
|
## 第一步: 明确对外提供的props
|
||
|
|
||
|
总页数,当前页数 就这两个属性够了
|
||
|
|
||
|
```javascript
|
||
|
const props = {
|
||
|
total: 200,
|
||
|
page: 10,
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## 第二步: 明确要对外提供哪些方法
|
||
|
|
||
|
一个getValue方法加一个populate就行了
|
||
|
|
||
|
```javascript
|
||
|
// 获取当前页码
|
||
|
const page = this.page.getValue()
|
||
|
|
||
|
// 设置总页数和页码
|
||
|
this.pager.attr("total", 100)
|
||
|
this.pager.attr("page", 1)
|
||
|
this.pager.populate()
|
||
|
```
|
||
|
|
||
|
## 第三步: 明确对外提供哪些事件
|
||
|
|
||
|
事件只需要一个就够了,通知外部使用者当前page,养成良好习惯,事件尽量带上参数
|
||
|
|
||
|
```javascript
|
||
|
this.fireEvent("EVENT_CHANGE", page)
|
||
|
```
|
||
|
|
||
|
## 生命周期
|
||
|
|
||
|
万物皆render,能render一遍就执行好的,尽量别用其他生命周期,mounted之类的,避免没必要的回流重绘 如果组件是异步的, beforeInit/beforeRender.那么你在render中一定可以拿到所有的状态了,就没必要再通过一次watch来实现效果.当然,有些事情必须在mounted中做(例如获取组件宽高)那就另说了.
|
||
|
|
||
|
## 抛砖引玉
|
||
|
|
||
|
比如这个pager组件按钮的灰化,我就借用最新的响应式写个例子 [自动相应变更](http://fanruan.design/doc.html?post=afe4c84120)
|
||
|
|
||
|
```demo
|
||
|
|
||
|
const Pager = BI.inherit(BI.Widget, {
|
||
|
props: {
|
||
|
total: 1,
|
||
|
page: 1,
|
||
|
},
|
||
|
|
||
|
init: function () {
|
||
|
this.state = Fix.define({
|
||
|
currentPage: this.options.page,
|
||
|
total: this.options.total,
|
||
|
});
|
||
|
},
|
||
|
|
||
|
render: function () {
|
||
|
|
||
|
return {
|
||
|
type: "bi.vertical_adapt",
|
||
|
columnSize: [24, 24, "fill", "", 24, 24],
|
||
|
hgap: 5,
|
||
|
items: [
|
||
|
{
|
||
|
type: "bi.icon_button",
|
||
|
cls: "pre-page-h-font",
|
||
|
disabled: () => {
|
||
|
return this.state.currentPage === 1;
|
||
|
},
|
||
|
handler: () => {
|
||
|
this.state.currentPage = 1;
|
||
|
this.fireEvent("EVENT_CHANGE", this.getValue());
|
||
|
},
|
||
|
}, {
|
||
|
type: "bi.icon_button",
|
||
|
cls: "pre-page-h-font",
|
||
|
disabled: () => {
|
||
|
return this.state.currentPage === 1;
|
||
|
},
|
||
|
handler: () => {
|
||
|
this.state.currentPage--;
|
||
|
this.fireEvent("EVENT_CHANGE", this.getValue());
|
||
|
},
|
||
|
}, {
|
||
|
type: "bi.text_editor",
|
||
|
ref: ref => this.editor = ref,
|
||
|
value: () => this.state.currentPage,
|
||
|
validationChecker: (v) => (BI.parseInt(v) >= 1) && (BI.parseInt(v) <= this.state.total),
|
||
|
errorText: "error",
|
||
|
listeners: [
|
||
|
{
|
||
|
eventName: "EVENT_CHANGE",
|
||
|
action: () => {
|
||
|
this.state.currentPage = BI.parseInt(this.editor.getValue());
|
||
|
this.fireEvent("EVENT_CHANGE", this.getValue());
|
||
|
},
|
||
|
},
|
||
|
],
|
||
|
}, {
|
||
|
type: "bi.label",
|
||
|
text: () => "/" + this.state.total,
|
||
|
}, {
|
||
|
type: "bi.icon_button",
|
||
|
cls: "next-page-h-font",
|
||
|
disabled: () => {
|
||
|
return this.state.currentPage === this.state.total;
|
||
|
},
|
||
|
handler: () => {
|
||
|
this.state.currentPage++;
|
||
|
this.fireEvent("EVENT_CHANGE", this.getValue());
|
||
|
},
|
||
|
}, {
|
||
|
type: "bi.icon_button",
|
||
|
cls: "next-page-h-font",
|
||
|
disabled: () => {
|
||
|
return this.state.currentPage === this.state.total;
|
||
|
},
|
||
|
handler: () => {
|
||
|
this.state.currentPage = this.state.total;
|
||
|
this.fireEvent("EVENT_CHANGE", this.getValue());
|
||
|
},
|
||
|
},
|
||
|
],
|
||
|
};
|
||
|
},
|
||
|
|
||
|
getValue: function () {
|
||
|
return this.state.currentPage;
|
||
|
},
|
||
|
|
||
|
populate: function () {
|
||
|
this.state.currentPage = this.options.page;
|
||
|
this.state.total = this.options.total;
|
||
|
},
|
||
|
});
|
||
|
|
||
|
BI.shortcut("pager", Pager);
|
||
|
|
||
|
let pager;
|
||
|
|
||
|
BI.createWidget({
|
||
|
type: "bi.vertical",
|
||
|
vgap: 20,
|
||
|
items: [
|
||
|
{
|
||
|
type: "pager",
|
||
|
ref: ref => pager = ref,
|
||
|
height: 24,
|
||
|
width: 250,
|
||
|
total: 100,
|
||
|
page: 2,
|
||
|
}, {
|
||
|
type: "bi.button",
|
||
|
text: "populate",
|
||
|
handler: () => {
|
||
|
pager.attr("total", 500);
|
||
|
pager.attr("page", 400);
|
||
|
pager.populate();
|
||
|
},
|
||
|
},
|
||
|
],
|
||
|
});
|
||
|
|
||
|
```
|