amis/docs/zh-CN/extend/custom-sdk.md
2022-07-14 11:01:07 +08:00

143 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 自定义组件 - SDK
---
## 使用 custom 组件临时扩展
基于 custom 组件可以直接在 amis 配置实现自定义功能,它的支持面最广,是唯一支持在可视化编辑器中使用的方法。
使用 custom 组件类似如下写法:
```javascript
{
label: '使用 custom 组件',
name: 'username', // 如果要放在 form 中,需要设置 nameonChange 将会设置这个值
type: 'custom',
// onMount 将会在组件创建时执行,默认会创建一个空 div 标签,也可以设置 inline: true 来创建 span 标签
// dom 是 dom 节点value 是初始数据,比如表单 name 初始拿到的数据onChange 只有在表单下才会有
onMount: (dom, value, onChange) => {
const button = document.createElement('button');
button.innerText = '点击修改姓名';
button.onclick = event => {
// 第二个参数是要修改的表单项名称
onChange('new name', 'username');
event.preventDefault();
};
dom.appendChild(button);
},
// onUpdate 将会在数据更新时被调用
// dom 是 dom 节点、data 将包含表单所有数据prevData 是之前表单的所有数据
onUpdate: (dom, data, prevData) => {
console.log('数据有变化', data);
},
// onUnmount 将会在组件被销毁的时候调用,用于清理资源
onUnmount:() => {
console.log('组件被销毁');
}
}
```
注意上面的代码用到了 JavaScript 函数,无法转成 json 格式,但这三个函数还支持字符串形式,上面的代码可以改成如下形式,这样就能在可视化编辑器里支持自定义组件了:
```schema: scope="body"
{
"type": "form",
"title": "custom 组件",
"body": [
{
"type": "input-text",
"name": "username",
"label": "姓名"
},
{
"name": "username",
"type": "custom",
"label": "自定义组件",
"onMount": "const button = document.createElement('button'); button.innerText = '点击修改姓名'; button.onclick = event => { onChange('new name', 'username'); event.preventDefault(); }; dom.appendChild(button);"
}
]
}
```
注意上面的例子中两个组件的 name 是一样的,这是为了方便示例,因为 amis 中的数据是双向绑定的,因此 onChange 修改自身的时候,另一个「姓名」输入框由于 name 一样,也会同步更新。
关于 custom 组件的更多属性请参考「[Custom 组件](../../components/custom)」。
## JS SDK 注册组件
amis 组件都是基于 React 的,所以需要使用一个简单的 React 组件来注册,可以是函数组件也可以是类组件,下面以函数组件为例,将[快速开始](../start/getting-started)中的代码替换成如下示例:
```javascript
let amis = amisRequire('amis/embed');
let amisLib = amisRequire('amis');
let React = amisRequire('react');
// 自定义组件props 中可以拿到配置中的所有参数,比如 props.label 是 'Name'
function CustomComponent(props) {
let dom = React.useRef(null);
React.useEffect(function () {
// 从这里开始写自定义代码dom.current 就是新创建的 dom 节点
// 可以基于这个 dom 节点对接任意 JavaScript 框架,比如 jQuery/Vue 等
dom.current.innerHTML = 'custom';
// 而 props 中能拿到这个
});
return React.createElement('div', {
ref: dom
});
}
//注册自定义组件,请参考后续对工作原理的介绍
amisLib.Renderer({
test: /(^|\/)my-custom/
})(CustomComponent);
let amisScoped = amis.embed('#root', {
type: 'page',
title: '表单页面',
body: {
type: 'form',
mode: 'horizontal',
api: '/saveForm',
body: [
{
label: 'Name',
type: 'my-custom', // 注意这个的 type 对应之前注册的 test
name: 'custom'
}
]
}
});
```
### 示例:引入 Element UI
首先在页面中加入 Element UI 所需的依赖
```html
<link
rel="stylesheet"
href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"
/>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
```
然后将前面的 `React.useEffect` 改成如下即可:
```javascript
React.useEffect(function () {
dom.current.innerHTML = `
<el-button @click="visible = true">Button</el-button>
<el-dialog :visible.sync="visible" title="Hello world">
<p>Try Element</p>
</el-dialog>
`;
new Vue({
el: dom.current,
data: function () {
return {visible: false};
}
});
});
```