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.
 

5.2 KiB

组件的代码设计基本思路

我们以一个分页组件为例,阐述一下FineUI中组件代码的基本思路

控件功能

上一页,下一页,带个输入框,有总页数.四个按钮带disabled逻辑,无上一页或者下一页时候灰化

示例

第一步: 明确对外提供的props

总页数,当前页数 就这两个属性够了

const props = {
  total: 200,
  page: 10,
}

第二步: 明确要对外提供哪些方法

一个getValue方法加一个populate就行了

//  获取当前页码
const page = this.page.getValue()

//  设置总页数和页码
this.pager.attr("total", 100)
this.pager.attr("page", 1)
this.pager.populate()

第三步: 明确对外提供哪些事件

事件只需要一个就够了,通知外部使用者当前page,养成良好习惯,事件尽量带上参数

this.fireEvent("EVENT_CHANGE", page)

生命周期

万物皆render,能render一遍就执行好的,尽量别用其他生命周期,mounted之类的,避免没必要的回流重绘 如果组件是异步的, beforeInit/beforeRender.那么你在render中一定可以拿到所有的状态了,就没必要再通过一次watch来实现效果.当然,有些事情必须在mounted中做(例如获取组件宽高)那就另说了.

抛砖引玉

比如这个pager组件按钮的灰化,我就借用最新的响应式写个例子 自动相应变更


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();
            },
        },
    ],
});