zsmj
2 years ago
4 changed files with 160 additions and 2 deletions
@ -0,0 +1,97 @@
|
||||
# 关于组件引用的奥秘,ref知多少 |
||||
|
||||
类似于React和Vue获取DOM元素引用的形式FineUI中也可以获取组件实例的引用,有两种方式 |
||||
|
||||
1. BI.createWidget方法的返回值 |
||||
2. 组件props中的ref属性(推荐) |
||||
|
||||
## ref在什么时候调用 |
||||
|
||||
组件ref会在组件render之后回调`this.options.ref.call(this, this)`,同时也会在组件destoryed之后再次回调`this.options.ref.call(null, null)` |
||||
|
||||
这也是为什么在[combo的一些特性详解](./80.combo的一些特性详解.md)一文中强调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呢 |
||||
|
||||
1. 相较于ref,BI.createWidget缺少相应的内存回收 |
||||
2. BI.createWidget会破坏render()=>json 的清晰代码结构 |
||||
3. 在封装高阶组件的时候,组件内部需要获取子组件引用,同时还有外部传入的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: {}, |
||||
}; |
||||
} |
||||
} |
||||
``` |
@ -0,0 +1,58 @@
|
||||
## 高阶组件的render props.md |
||||
|
||||
在FineUI中,我们经常见到一些继承抽象组件的写法,为了实现某种功能,继承抽象组件重新定义一个组件 |
||||
|
||||
依据我们的编码规范,一个组件一个文件,被迫新建众多文件 |
||||
``` |
||||
// 用于loading效果的组件 |
||||
const Widget1 = BI.inherit(BI.Pane, { |
||||
|
||||
beforeRender: function () { |
||||
this.loading(); |
||||
}, |
||||
|
||||
}); |
||||
|
||||
// 用于封装可以点击的组件 |
||||
const Widget2 = BI.inherit(BI.BasicButton, { |
||||
|
||||
render: function () { |
||||
|
||||
}, |
||||
|
||||
}); |
||||
|
||||
// 用于封装带有tooltip功能的组件 |
||||
const Widget3 = BI.inherit(BI.Single, { |
||||
|
||||
render: function () { |
||||
|
||||
}, |
||||
|
||||
}); |
||||
``` |
||||
|
||||
以BI.BasicButton举例,很多时候我们只是想快速创建一个可以点击的组件,此时可以借助render-props来实现 |
||||
``` |
||||
const MyButton = { |
||||
type: "bi.basic_button", |
||||
render: () => { |
||||
return { |
||||
type: "bi.vertical_adapt", |
||||
items: [ |
||||
{ |
||||
type: "bi.label", |
||||
text: "文字", |
||||
}, { |
||||
type: "bi.icon_button", |
||||
cls: "delete-font", |
||||
title: "删除按钮", |
||||
}, |
||||
], |
||||
}; |
||||
}, |
||||
handler: () => { |
||||
console.log("点击了"); |
||||
}, |
||||
}; |
||||
``` |
Loading…
Reference in new issue