低代码的一些理解
他其实就是对于组件的高度封装,以至于方便我们开发。其实这种做法我们也可以做到。通过对组件的封装,我们只需要传入一个props就可以快速构建出一个模块或者一个页面出来。
低代码可以达到快速开发,通过可视化界面拖拽内置的组件,在通过api接口提供数据,就可以快速的构建出一个页面来。但是他的组件并不是很丰富,可能并不能满足我们的开发需求。并且如果出现错误,网上并不能准确地查找到解决办法,这就是他的生态。
对于后期维护,你想要去快速看懂代码,他是不现实的。需要借助可视化界面去维护该项目。
- 高度封装,快熟开发
- 可视化界面开发。(这个玩意是真的难用,还是自己去配置json吧)
- 组件并不丰富,可能还需要加入自己定制化的代码。
- 出现错误不易解决
- 后期维护也需要借助可视化界面开发
对于这几天看官网写代码,一些最基础的总结。
js sdk开发的好处
权限判断也省去了,因为返回的权限列表只注册了这么多的页面,无需你额外的去控制用户的访问权限。
以前都是在前端将所有的路由映射注册好,但是这样用户是可以再浏览器输入框中输入正确的地址,然后访问没有权限的页面的。这样你就必须去通过导航守卫去控制用户的这个行为。
但是这种方式开发就不需要了。因为你返回的就是每个用户的对应权限的路由映射,所以无需前端再控制了。
body的格式
- 模板
"body": "Hello ${text}!" // 输出 Hello World!
- Schema 配置
"body": { "type": "tpl", "tpl": "Hello ${text}!" // 输出 Hello World! }
- schemaArray
"body": [ { "type":"tpl", "tpl": "my name is ${name}" // 输出 my name is amis }, { "type":"tpl", "tpl": "I am ${age} years old" // 输出 I am 1 years old } ]
其中每个schema中的classname
可以设置该组件的class属性。
发送网络请求
api属性来控制。
{ "api": { "method": "get", "url": "xxxx", "data": { xxx }, ... // 其他配置 } }
每个schema中也可以配置source属性,他就是api类型。
{ "label": "选项2", "type": "select", "size": "sm", "name": "b", "source": { "method": "get", "url": "/amis/api/mock2/options/level2?a=${a}", // 只有满足这个条件才会触发 "sendOn": "this.a === 2" }, "description": "只有<code>选项1</code>选择<code>B</code>的时候,才触发<code>选项2</code>的<code>source</code>接口重新拉取" }
创建数据域的组件
需要注意,只有少数几个容器组件会创建新的数据域,除了最顶层的 Page,还有 CRUD、Dialog、IFrame、Form、Service 等。
并不是所有内置的组件都可以创建数据域。
表单提交数据
这里data中直接可以获取表单中写入的值,并且获取的时name字段。
{ "type": "page", "body": { "type": "form", "api": { "method": "post", "url": "/amis/api/mock2/form/saveForm", "data": { "userName": "${name}", "userEmail": "${email}" } }, "body": [ { "type": "input-text", "name": "name", "label": "姓名:" }, { "name": "email", "type": "input-text", "label": "邮箱:" } ] } }
展开该对象中所有变量
可以使用"&"
,作为数据映射 key,展开所配置的变量。
注意:他只能展开第一层的数据,舍弃其它层的数据。
"c": { "e": "3", "f": "4", "g": "5", "t": { "age": 20 } } }, "&": "${c}" ==> 等价于 { "e": "3", "f": "4", "g": "5", }
获取浏览器中的全局变量
window
即全局变量
ls
即 localStorage, 如果值是 json 对象,可以直接当对象用比如:${ls:xxxxxlocalStrorageKey.xxxx}
{ "type": "page", "body": "当前页面标题为:<span class='label label-info'>${ls:person[name]}</span>" }
ss
即 sessionStorage,同上。
在amis中使用表达式
一般来说,属性名类似于xxxOn
或者 className
的配置项,都可以使用表达式进行配置。
{ "type": "tpl", "tpl": "当前作用域中变量 show 是 1 的时候才可以看得到我哦~", "visibleOn": "this.show === 1" } // 或者 { "type": "static", "label": "IF(true, 2,", "tpl": "${val == 3.5}", // true "visibleOn": "${ SUM(3, 0.5) == val}" // true },
但是其他的一些属性中可以通过模板字符串,但是不能写js字符串来使用表达式。
{ "type": "static", "label": "IF(true, 2, 3)", "tpl": "${IF(true, 2, 3)}" }, { "type": "static", "label": "IF(true, 2, 3)", "tpl": "${CONTAINS('hello', 'he')}" }, { "data": { "val": 3.5 }, "body": [ { "type": "static", "label": "val==3.5", "tpl": "${val == 3.5}" // true }, ] }
上面的这些也是可以的。
所有的值都会作为该组件的数据域中的数据
- 表单中的值,作为最近组件可以创建数据域中的值,在该数据域中的组件都可以访问。这里注意一下,并不是只有和表单相关的组件才可以访问。他是以数据域为单位的。
- 请求返回的数据,他是放在全局数据域中的。例如下面例子中的button,发送ajax请求回来的id数据。
- 这里也需要注意一下,数据域中的数据的权重大于请求回来的数据。即如果数据域中已经存在该属性,那么返回来的属性将舍弃。
{ "type": "page", "body": [ { "type": "service", data: { id: 20, age: "llm" }, body: [ { "type": "input-text", // 并且表单的值也会自动作为数据域 "name": "name", "label": "姓名" }, { // 任何请求返回的接口都可以放置在自己的数据域中。 "type": "button", "label": "查询", actionType: "ajax", api: "https://aisuda.bce.baidu.com/amis/api/mock2/form/saveForm", "level": "primary" }, { type: "tpl", tpl: "service组件下的 :${id} ${name} ${age}" } ], }, { type: "tpl", tpl: "page组件下的: ${id} ${name} ${age}" } ] }
组件之间联动(跨数据域传递数据)
target 属性指定另一个组件的name属性值。
"target": "form2?name=${name}&email=${email}&company=${company}"
其中的查询参数会被传递到另一个组件数据源中。
target可以指定多个组件的name值,通过逗号分隔。
这种方式我测试了一下,他为啥只能在两个表单中传递值呢,一个表单向其他组件传递将不会成功。
💢💢💢 2022-9-5,今天测试发现,传递数据只有在两个都可以创建数据域的组件。如果就解决了上面的疑惑。因为今天是通过service组件测试的,内部在使用tpl组件获取值,这样是可以获取到的。
{ "type": "page", "body": [ { "title": "查询条件", "type": "form", "body": [ { "type": "input-text", "name": "a", "label": "关键字:" } ], "actions": [ { "type": "action", "actionType": "reload", "label": "发送到 form2", "target": "my_tpl?a=${a}" } ] }, { // type: "tpl", // name: "my_tpl", // tpl: "${a}" type: "form", name: "my_tpl", body: { type: "input-text", name: 'a' } } ] },
使用数据的方式
- 如果是使用在表达式中时,我们需要通过
this
去访问数据域中的数据。其中this就是当前数据域链对象。
这里需要注意一下,并不是所有的属性都支持书写表达式,支持表达式的属性,取值时都需要通过this来获取,不然不可以获取到。
- 如果写在其他地方,则只需要直接使用模板语法即可。
"source": { "method": "get", // 这里就可以直接通过模板取值 "url": "https://aisuda.bce.baidu.com/amis/api/mock2/options/level2?a=${a}", //这里的写法时不对的 "sendOn": "${a} === 2" // 应该这样写 "sendOn": "this.a === 2" },
但是最近有测试了一下,发现并不是表达式中只能通过this取值,他也可以通过模板语法取值。
{ type: "page", data: { xxx: "1" }, body: { "type": "tpl", // "tpl": "${xxx == 1 ? 'One' : 'Others'}" // 这里有不能使用this "tpl": "this.xxx == 1 ? 'one' : 'others'" } }
所以对应获取数据域中值的话,我们需要多去尝试。难,为啥他不统一一下呢 ????????
select中的source可以请求数据
他应该返回一个options对象。 刚好作为select中展示的值。
表单相关的属性测试总结
group
表单项,默认都是一行显示一个,Group 组件用于在一行展示多个表单项,会自动根据表单项数量均分宽度。
表格项可以设置label与input的占比
以前没看见这个值,自己设置的css样式结合labelWidth处理的。设置了这个属性,他会将表单项居中。
"horizontal": { "left": 5, "right": 5, },
"wrapWithPanel": false 去掉表单边框等
可以去掉默认表单边框(包括标题,按钮栏以及边距样式等)。切记,如果设置了他,我们就需要在body中自己定义提交按钮等交互行为。因为这时候定义actions时不会显示的。
表单默认发送的时post请求
表单重置
配置"type": "reset"
或者"actionType": "reset"
的按钮,可以实现点击重置表单项值。 这个是将表单项重置成为初始值,并不是清空。
"actions": [ { "type": "reset", "label": "重置" }, { "type": "submit", "label": "保存" } ]
"canAccessSuperData": false。取消新增时数据的回写。
新增时,我们定义的字段名和列表中的都是一样的,所以可能造成数据的回写(可以获取当前数据域中的属性),通过上述设置,可以将不关联当前数据域。这个对于编辑当前行列表的数据回写是非常有用的。不需要设置成false。
"resetAfterSubmit": true
在表单提交后,重置表单项。这个属性也非常有用。
reload ,当表单提交后,刷新目标组件,也可以传递参数给别的组件
配置reload
属性为其他组件name
值,可以在表单提交成功之后,刷新指定组件。
{ "type": "page", "body": [ { "type": "form", "api": "/amis/api/mock2/form/saveForm", "title": "用户信息", "reload": "otherForm?id=${id}", // 传递id参数 "body": [ { "type": "input-text", "name": "name", "label": "姓名" } ] }, { "type": "form", "name": "otherForm", "title": "返回结果", "actions": [], "body": [ { "type": "static", "name": "id", "label": "返回 ID" } ] } ] }
刚刚学习amis,前端搭建一个后台管理系统是非常简单的,所有的问题都聚焦到后端去了。