使用云开发低码(lowcode)开发一个项目
什么是低码
云开发低码 LowCode 是高效、高性能的拖拽式低代码开发平台,向上连接前端的行业业务,向下连接云计算的海量能力,助力企业垂直上云。云开发低码将繁琐的底层架构和基础设施抽象化为图形界面,通过行业化模板、拖放式组件和可视化配置快速构建多端应用(小程序、H5应用、Web 应用等),免去了代码编写工作,让您能够完全专注于业务场景。云开发低码以云开发作为底层支撑,云原生能力将应用搭建的全链路打通,提供高度开放的开发环境,且时刻为您的应用保驾护航。
了解云开发lowcode
准备步骤
- lowcode目前还在测试阶段,需申请白名单:https://cloud.tencent.com/apply/p/1ybq80uk3fx
- 开通云开发,申请一个按量付费环境:https://console.cloud.tencent.com/tcb/env/index
- 安装云开发CMS内容管理系统:https://console.cloud.tencent.com/tcb/extensions/index
- 建议安装云开发@cloudbase/cli工具:https://docs.cloudbase.net/cli-v1/install.html
前置知识
- 有基本的 html , css ,js 知识
- 有一定的vue或者小程序开发模式基础
开发流程
认识lowcode控制台
PS. 这篇文章大致是1月18号开始写的,发布时应该已经月底,版本有更新部分内容可能不一致
- 应用管理:是用户创建的所有应用的总览页
- 创建空白应用:创建一个不含任何预先样式的低代码模板
- 从模板应用创建:从模板中心中挑选一个应用进行创建,作为代码基础
- 模板中心
- 可查看目前云开发市场提供的模板
- 数据源管理
- 应用数据,需开通CMS内容管理系统,放在CMS内容中,采用JSON集合的方式存储
- 目前只支持CMS的数据源,外部的暂不支持。
这里我已经创建了一个空白todolist应用了,为给各位再展现一次操作,这里再创建一个新的todlist应用,成品大致如下:http://todolist.cn/
查看应用
点击创建好的新应用,进入应用信息页
可以看到应用详情、应用版本、应用数据(在CMS中)
点进「进入应用页面编辑」
编辑应用
PS. 强烈建议使用屏幕较大显示器!
菜单栏
- 撤销(ctrl z)、重做(ctrl shift z):不解释
- 预览发布:可以将应用发布到静态网站托管并提供链接,若本地安装了 @cloudbase/cli 工具
- 保存:Ctrl S
- 低代码编辑:可以用css编写样式,js编写函数,句柄事件
- 变量管理:一般是用于做mock数据或者引入外部数据源做数据
左侧:页面组件栏
- 页面:创建新页面,可以选择需要编辑的页面,创建新页面时的标题是页面的名字,页面ID即常说的文件名,例如页面title:首页,页面id:index。默认会创建一个首页(空白模板)
- 组件:目前只提供了官方组件库,可以使用常见的模块,(但没发现表格)
- JSON : 页面JSON表示
中部:IDE
- 组件树:展示目前编辑区所有的组件与层级关系,也可在这里选中编辑区无法点击的元素,组建的id可以简单理解为html中的id选择器属性。支持拖动曾经,但缺点是一旦移动到另一层级下,id也会随之发生变化。所以非常建议在开始编辑前,先想好页面结构。
- 编辑区:可以将右侧的组件拖动到编辑区内来 image.png
- 预览区:顾名思义,可以看编辑打包出来的效果,但是请注意,从实际来看打包出来的效果和编辑器并不完全相同,依然建议实际编辑采用平时开发的时候规范的布局方式(多块级,少内联,少用定位等)
右侧:属性编辑区
- 组件编辑
- 数据:部分组件可以绑定或填写数据用于展示,例如文本、导航。
- 样式:可以点击样式代码编辑用css自定义编辑,可以用下面提供的配置项直接编辑,相信熟悉前端的朋友一点也不会陌生
- 事件:可以选择常见的样式并添加事件回调,事件回调的函数可以在之前「低代码编辑」中进行编写,编写好后可以在这里进行绑定
- 页面编辑
- 数据:页面功能配置项
- 样式:全局页面样式
- 页面编辑
- 数据:应用功能配置项
- 样式:全局应用样式
构建页面
对这个页面分析后,静态部分基本可以分为以下这种结构
去掉默认的导航栏
为适配微信小程序,腾讯云的lowcode有自带的导航栏,一般是比较丑的,可以在页面编辑-导航栏设置-自定义样式给去掉
创建根元素
我们一般在body内套一个大容器container,一般开发中这个根元素都叫app
默认的container是没有高度的,如果拖过来就点掉的话,会因为没有高度而被隐藏点不到,不方便后续我们往里拖组件,这里建议有两种方案
- 给根container设置一个较高的高度,等里面的内容填充完成后,回头将这个根container的height设置为auto
- 用组件树来拖动与选择高度为0的组件(推荐)
添加静态元素
根据我们之前的结构图,我们基本上可以用组件拖拽出如下的组件树
- 根据页面添加静态样式
参考样式表如下:
代码语言:txt复制{
"id": "id3",
"component": "Container",
"attributes": {},
"items": [
{
"id": "id4",
"component": "Container",
"attributes": {},
"items": [
{
"id": "id5",
"component": "Container",
"attributes": {},
"items": [
{
"id": "id6",
"component": "Text",
"attributes": {
"text": "Todolist"
},
"extra": {
"commonStyle": {
"self": {
"fontSize": "36"
},
"text": {
"fontSize": "36"
}
},
"xIndex": 1
}
}
],
"extra": {
"xIndex": 0
}
},
{
"id": "id7",
"component": "Container",
"attributes": {},
"items": [
{
"id": "id71",
"component": "Form",
"attributes": {
"name": "formInput",
"type": "text",
"focus": false,
"label": "",
"rules": [],
"value": "",
"cursor": -1,
"layout": "",
"varPath": "",
"autoFill": "",
"descSlot": "",
"disabled": false,
"formType": "",
"password": false,
"required": false,
"clearable": true,
"labelSlot": "",
"maxLength": 140,
"underline": true,
"alwaysEmbed": false,
"confirmHold": false,
"confirmType": "done",
"placeholder": "请输入",
"holdKeyboard": false,
"labelVisible": true,
"selectionEnd": -1,
"cursorSpacing": 0,
"initialValues": {},
"adjustPosition": false,
"selectionStart": -1,
"validateStatus": "success",
"validateTrigger": "onChange"
},
"items": [
{
"id": "contentSlot",
"component": "",
"items": [
{
"id": "id72",
"component": "FormInput",
"attributes": {
"label": " ",
"rules": [],
"underline": false,
"placeholder": "请添加todo"
},
"extra": {
"commonStyle": {
"self": {
"height": "60",
"background": "#fff",
"lineHeight": "80",
"paddingTop": 5,
"borderRadius": "5"
},
"text": {
"lineHeight": "80"
},
"border": {
"radiusInfo": {
"topLeft": "5",
"topRight": "5",
"bottomLeft": "5",
"bottomRight": "5"
}
},
"padding": {
"top": 5
},
"background": {
"color": "#fff",
"bgType": "color"
}
},
"xIndex": 0
}
}
]
}
],
"extra": {
"commonStyle": {
"self": {
"height": "60"
},
"size": {
"height": "60"
}
}
}
}
],
"extra": {
"commonStyle": {
"self": {
"height": "50",
"display": "flex",
"alignItems": "center",
"lineHeight": "60",
"justifyContent": "center"
},
"size": {
"height": "50"
},
"display": "flex",
"flexConfig": {
"alignItems": "center",
"justifyContent": "center"
}
},
"xIndex": 1
}
}
],
"extra": {
"commonStyle": {
"self": {
"color": "#fff",
"height": "100",
"display": "flex",
"alignItems": "center",
"background": "#323232",
"paddingLeft": 30,
"paddingRight": 30,
"justifyContent": "space-between"
},
"size": {
"height": "100"
},
"text": {
"color": "#fff"
},
"display": "flex",
"padding": {
"left": 30,
"right": 30
},
"background": {
"color": "#323232",
"bgType": "color"
},
"flexConfig": {
"alignItems": "center",
"justifyContent": "space-between"
}
},
"xIndex": 0
}
},
{
"id": "id10",
"component": "Container",
"attributes": {},
"items": [
{
"id": "id11",
"component": "Container",
"attributes": {},
"items": [
{
"id": "id12",
"component": "Container",
"attributes": {},
"items": [
{
"id": "id13",
"component": "Text",
"attributes": {
"text": "正在进行"
},
"extra": {
"commonStyle": {
"self": {
"fontSize": "48",
"fontWeight": "bolder"
},
"text": {
"weight": "bolder",
"fontSize": "48"
}
},
"xIndex": 0
}
},
{
"id": "id14",
"component": "Container",
"attributes": {},
"items": [
{
"id": "id31",
"component": "Text",
"attributes": {
"text": "1"
},
"extra": {
"xIndex": 0
}
}
],
"extra": {
"commonStyle": {
"self": {
"width": "40",
"height": "40",
"display": "flex",
"textAlign": "left",
"alignItems": "center",
"background": "#E6E6FA",
"fontWeight": "bolder",
"borderRadius": "50",
"justifyContent": "center"
},
"size": {
"width": "40",
"height": "40"
},
"text": {
"weight": "bolder",
"textAlign": "left"
},
"border": {
"radiusInfo": {
"topLeft": "50",
"topRight": "50",
"bottomLeft": "50",
"bottomRight": "50"
}
},
"display": "flex",
"background": {
"color": "#E6E6FA",
"bgType": "color"
},
"flexConfig": {
"alignItems": "center",
"justifyContent": "center"
}
},
"xIndex": 1
}
}
],
"extra": {
"commonStyle": {
"self": {
"display": "flex",
"alignItems": "center",
"justifyContent": "space-between"
},
"display": "flex",
"flexConfig": {
"alignItems": "center",
"justifyContent": "space-between"
}
},
"xIndex": 0
}
},
{
"id": "id15",
"component": "Container",
"attributes": {},
"items": [
{
"id": "id41",
"component": "Container",
"attributes": {},
"items": [
{
"id": "id43",
"component": "Icon",
"attributes": {
"name": "delete"
},
"extra": {
"commonStyle": {
"self": {
"width": "75"
},
"size": {
"width": "75"
}
},
"xIndex": 2
}
},
{
"id": "id44",
"component": "Text",
"attributes": {},
"extra": {
"commonStyle": {
"self": {
"width": "500",
"display": "inline-block"
},
"size": {
"width": "500"
},
"display": "inline-block"
},
"xIndex": 1
}
},
{
"id": "id54",
"component": "Container",
"attributes": {},
"items": [
{
"id": "id55",
"component": "Text",
"attributes": {
"text": "√"
},
"extra": {
"commonStyle": {
"self": {
"color": "#fff",
"textAlign": "center",
"fontWeight": "bolder"
},
"text": {
"color": "#fff",
"weight": "bolder",
"textAlign": "center"
}
},
"xIndex": 0
}
}
],
"extra": {
"commonStyle": {
"self": {
"width": "50",
"border": "3 solid #666",
"height": "50",
"textAlign": "center",
"lineHeight": "50",
"marginLeft": 30,
"borderRadius": "5"
},
"size": {
"width": "50",
"height": "50"
},
"text": {
"textAlign": "center",
"lineHeight": "50"
},
"border": {
"type": "solid",
"color": "#666",
"width": "3",
"radiusInfo": {
"topLeft": "5",
"topRight": "5",
"bottomLeft": "5",
"bottomRight": "5"
}
},
"margin": {
"left": 30
}
},
"xIndex": 0
}
}
],
"extra": {
"commonStyle": {
"self": {
"display": "flex",
"marginTop": 15,
"alignItems": "center",
"background": "rgb(255, 255, 255)",
"borderLeft": "10px solid #629A9C",
"paddingTop": 15,
"borderRadius": "10",
"marginBottom": 15,
"paddingBottom": 15,
"justifyContent": "space-between"
},
"border": {
"radiusInfo": {
"topLeft": "10",
"topRight": "10",
"bottomLeft": "10",
"bottomRight": "10"
}
},
"custom": [],
"margin": {
"top": 15,
"bottom": 15
},
"display": "flex",
"padding": {
"top": 15,
"bottom": 15
},
"background": {
"color": "rgb(255, 255, 255)",
"bgType": "color"
},
"borderLeft": "10px solid #629A9C",
"flexConfig": {
"alignItems": "center",
"justifyContent": "space-between"
}
},
"xIndex": 0
}
}
],
"extra": {
"xIndex": 1
}
}
],
"extra": {
"xIndex": 0
}
},
{
"id": "id32",
"component": "Container",
"attributes": {},
"items": [
{
"id": "id33",
"component": "Container",
"attributes": {},
"items": [
{
"id": "id35",
"component": "Text",
"attributes": {
"text": "已经完成"
},
"extra": {
"commonStyle": {
"self": {
"fontSize": "48",
"fontWeight": "bolder"
},
"text": {
"weight": "bolder",
"fontSize": "48"
}
},
"xIndex": 0
}
},
{
"id": "id36",
"component": "Container",
"attributes": {},
"items": [
{
"id": "id37",
"component": "Text",
"attributes": {
"text": "1"
},
"extra": {
"xIndex": 0
}
}
],
"extra": {
"commonStyle": {
"self": {
"width": "40",
"height": "40",
"display": "flex",
"textAlign": "left",
"alignItems": "center",
"background": "#E6E6FA",
"fontWeight": "bolder",
"borderRadius": "50",
"justifyContent": "center"
},
"size": {
"width": "40",
"height": "40"
},
"text": {
"weight": "bolder",
"textAlign": "left"
},
"border": {
"radiusInfo": {
"topLeft": "50",
"topRight": "50",
"bottomLeft": "50",
"bottomRight": "50"
}
},
"display": "flex",
"background": {
"color": "#E6E6FA",
"bgType": "color"
},
"flexConfig": {
"alignItems": "center",
"justifyContent": "center"
}
},
"xIndex": 1
}
}
],
"extra": {
"commonStyle": {
"self": {
"display": "flex",
"alignItems": "center",
"justifyContent": "space-between"
},
"display": "flex",
"flexConfig": {
"alignItems": "center",
"justifyContent": "space-between"
}
},
"xIndex": 0
}
},
{
"id": "id34",
"component": "Container",
"attributes": {},
"items": [
{
"id": "id38",
"component": "Container",
"attributes": {},
"items": [
{
"id": "id45",
"component": "Container",
"attributes": {},
"items": [
{
"id": "id46",
"component": "Icon",
"attributes": {
"name": "delete"
},
"extra": {
"commonStyle": {
"self": {
"width": "75"
},
"size": {
"width": "75"
}
},
"xIndex": 2
}
},
{
"id": "id47",
"component": "Text",
"attributes": {},
"extra": {
"commonStyle": {
"self": {
"width": "500",
"display": "inline-block"
},
"size": {
"width": "500"
},
"display": "inline-block"
},
"xIndex": 1
}
},
{
"id": "id56",
"component": "Container",
"attributes": {},
"items": [
{
"id": "id57",
"component": "Text",
"attributes": {
"text": "√"
},
"extra": {
"commonStyle": {
"self": {
"color": "#fff",
"textAlign": "center",
"fontWeight": "bolder"
},
"text": {
"color": "#fff",
"weight": "bolder",
"textAlign": "center"
}
},
"xIndex": 0
}
}
],
"extra": {
"commonStyle": {
"self": {
"color": "#67A1E6",
"width": "50",
"border": "3 solid transparent",
"height": "50",
"textAlign": "center",
"background": "#67A1E6",
"lineHeight": "50",
"marginLeft": 30,
"borderRadius": "5"
},
"size": {
"width": "50",
"height": "50"
},
"text": {
"textAlign": "center",
"lineHeight": "50"
},
"border": {
"type": "solid",
"color": "transparent",
"width": "3",
"radiusInfo": {
"topLeft": "5",
"topRight": "5",
"bottomLeft": "5",
"bottomRight": "5"
}
},
"margin": {
"left": 30
},
"background": {
"color": "#67A1E6",
"bgType": "color"
}
}
}
}
],
"extra": {
"commonStyle": {
"self": {
"display": "flex",
"marginTop": 15,
"alignItems": "center",
"background": "#E6E6E6",
"borderLeft": "10px solid #629A9C",
"paddingTop": 15,
"borderRadius": "10",
"marginBottom": 15,
"paddingBottom": 15,
"justifyContent": "space-between"
},
"border": {
"radiusInfo": {
"topLeft": "10",
"topRight": "10",
"bottomLeft": "10",
"bottomRight": "10"
}
},
"custom": [],
"margin": {
"top": 15,
"bottom": 15
},
"display": "flex",
"padding": {
"top": 15,
"bottom": 15
},
"background": {
"color": "#E6E6E6",
"bgType": "color"
},
"borderLeft": "10px solid #629A9C",
"flexConfig": {
"alignItems": "center",
"justifyContent": "space-between"
}
}
}
}
],
"extra": {
"xIndex": 0
}
}
],
"extra": {
"xIndex": 1
}
}
],
"extra": {}
}
],
"extra": {
"commonStyle": {
"self": {
"paddingLeft": 20,
"paddingRight": 20
},
"padding": {
"left": 20,
"right": 20
}
},
"xIndex": 1
}
},
{
"id": "id29",
"component": "Container",
"attributes": {
"title": "footer"
},
"items": [
{
"id": "id39",
"component": "Text",
"attributes": {
"text": "Copyright 2014 todolist.cn clear"
},
"extra": {
"commonStyle": {
"self": {
"color": "#666677"
},
"text": {
"color": "#666677"
}
},
"xIndex": 0
}
}
],
"extra": {
"commonStyle": {
"self": {
"marginTop": 30,
"textAlign": "center"
},
"text": {
"textAlign": "center"
},
"margin": {
"top": 30
}
},
"xIndex": 2
}
}
],
"extra": {
"xIndex": 0
}
}
可以看到效果如下:
添加动态数据
- 做mock 打开变量编辑,定义两个变量,一个是todo,一个是complete
- 绑定数据 我们会发现页面上有这么几个视图内容是随着数据变化而变化的
那么对于这些部分我们需要在右边的属性编辑为为其绑定数据
循环数据绑定如下:
这里解释一下步骤:
- 首先给需要循环的容器添加状态变量(数组or对象),就会循环对应的次数,这个相信使用过vue框架的前端开发者们并不陌生
- 在被循环的元素内,在添加状态变量时可以绑定循环对象的子项
得到的效果图如下:
交互事件
事件总览
样式完成后,我们来完成事件,这里的事件有几个
- 输入成功后点击提交,将输入框内的内容添加到「正在进行」中
- 点击「正在进行」前面的框,会将这条信息从「正在进行」中挪至「已经完成」
- 点击「已经完成」前面的框,会将这条信息从「已经完成」中挪至「正在进行」
- 点击删除键删掉这一条信息
目前lowcode的表单元素只能放在表单Form内下使用,作为通用container容器的直接子元素会报错。目前想要获取表单内的数值,最好使用submit按钮,submit绑定的事件e中,可以获取到整个表单的内容,所以在这里添加了一个按钮
提交事件
- 点击低代码编辑,在对应页面下创建句柄
- 我们可以在函数入口内写入代码
- 顺便这里提及一下,上面的style可以写class,同样可以在前面的页面给予绑定,lifecycle是生命周期,在里面可以写对应的钩子函数
- 可以看一下input框里的内容,点击提交事件打印的信息(e.data.target)
- 将input的内容添加到$page.dataset.state.todolist中
即可发现我们的输入框内的内容增加到了「正在进行」中
完成事件
- 创建句柄并编写代码
目前还不支持传参传循环渲染的index,只能传value,那就只好用值来做判断点的谁了,可以在事件中传参
- 代码部分
- export default function(e) { let arr = new Array(); if(e.data.target){ let index = $page.dataset.state.todolist.indexOf(e.data.target); if(index == -1) return; for(let i = 0 ; i < $page.dataset.state.todolist.length ; i ){ if(i != index) arr.push($page.dataset.state.todolisti) else $page.dataset.state.completelist.push($page.dataset.state.todolisti) } $page.dataset.state.todolist = arr; }
}取消完成事件export default function(e) {
let arr = new Array();
if(e.data.target){
代码语言:txt复制 let index = $page.dataset.state.completelist.indexOf(e.data.target);
代码语言:txt复制 if(index == -1)
代码语言:txt复制 return;
代码语言:txt复制 for(let i = 0 ; i < $page.dataset.state.completelist.length ; i ){
代码语言:txt复制 if(i != index)
代码语言:txt复制 arr.push($page.dataset.state.completelist[i])
代码语言:txt复制 else
代码语言:txt复制 $page.dataset.state.todolist.push($page.dataset.state.completelist[i])
代码语言:txt复制 }
代码语言:txt复制 $page.dataset.state.completelist = arr;
}
}删除事件// 删除complete
export default function(e) {
let arr = new Array();
console.log(e.data.target)
if(e.data.target){
代码语言:txt复制 let index = $page.dataset.state.completelist.indexOf(e.data.target);
代码语言:txt复制 if(index == -1)
代码语言:txt复制 return;
代码语言:txt复制 for(let i = 0 ; i < $page.dataset.state.completelist.length ; i ){
代码语言:txt复制 if(i != index)
代码语言:txt复制 arr.push($page.dataset.state.completelist[i])
代码语言:txt复制 }
代码语言:txt复制 $page.dataset.state.completelist = arr;
}
}
// 删除todo
export default function(e) {
let arr = new Array();
if(e.data.target){
代码语言:txt复制 let index = $page.dataset.state.todolist.indexOf(e.data.target);
代码语言:txt复制 if(index == -1)
代码语言:txt复制 return;
代码语言:txt复制 for(let i = 0 ; i < $page.dataset.state.todolist.length ; i ){
代码语言:txt复制 if(i != index)
代码语言:txt复制 arr.push($page.dataset.state.todolist[i])
代码语言:txt复制 }
代码语言:txt复制 $page.dataset.state.todolist = arr;
}
}
发布
当我们编写完所有代码之后,就可以点击发布了
选择菜单栏中的预览发布
这里推荐使用本地发布,速度更快,且能帮助调试
用node安装好@cloudbase/cli工具后,按照命令开启登录后开启tcb lowcode watch
之后程序的编译过程就会在shell中展现出来,有任何报错都可以查看。
H5部署
如果H5部署成功,代码会存到对应的静态网站托管下面,可以通过静态网站托管提供的路径对H5页面进行访问
小程序部署
小程序的部署需要提供wxappid,同时需要关闭对应小程序公众平台-开发设置中的IP白名单,才可正常使用