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.
2.3 KiB
2.3 KiB
关于组件引用的奥秘,ref知多少
类似于React和Vue获取DOM元素引用的形式FineUI中也可以获取组件实例的引用,有两种方式
- BI.createWidget方法的返回值
- 组件props中的ref属性(推荐)
ref在什么时候调用
组件ref会在组件render之后回调this.options.ref.call(this, this)
,同时也会在组件destoryed之后再次回调this.options.ref.call(null, null)
这也是为什么在combo的一些特性详解一文中强调combo的popup是在弹出时候创建的,有时候虽然写了ref,但是暂时还拿不到.
ref不是只回调一次哦
使用ref时推荐如下写法,使用参数
{
type: "bi.button",
text: "左上角",
ref: function (_ref) {
xxx = _ref;
},
}
不推荐用this赋值的写法,因为在组件destoryed之后的回调,this可能是window对象.
{
type: "bi.button",
text: "左上角",
ref: function () {
xxx = this;
},
}
用BI.createWidget有什么不好吗,什么时候可以用BI.createWidget呢
- 相较于ref,BI.createWidget缺少相应的内存回收
- BI.createWidget会破坏render()=>json 的清晰代码结构
- 在封装高阶组件的时候,组件内部需要获取子组件引用,同时还有外部传入的props存在ref的场景.
例如如下示例,此时外部传入的ref失效了
class MyComponent extends BI.Widget {
static xtype = "my.component";
render() {
const el = this.options.el;
return {
type: "bi.combo",
el: {
...el,
ref: ref => {
this.trigger = ref;
},
},
popup: {},
};
}
}
let myRef;
const widget = {
type: MyComponent.xtype,
ref: ref => {
myRef = ref;
},
}; render:
}
如何避免这类错误呢,有两种可选方案,使用BI.createWidget方法,或者使用私有的__ref
class MyComponent extends BI.Widget {
static xtype = "my.component";
render() {
const el = this.options.el;
return {
type: "bi.combo",
el: {
...el,
__ref: ref => {
this.trigger = ref;
},
},
popup: {},
};
}
}