Giter VIP home page Giter VIP logo

lowcode-engine-vue's People

Contributors

keuby avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

lowcode-engine-vue's Issues

element-plus物料接入问题

有fork过去,尝试了一下接入一下element-plus的物料,发现由于element-plus物料是用<script setup>的语法糖写的,接入会有问题,这边的lowcode-vue-simulator-renderer可能需要适配一下

自定义物料拖入报错,节点无法拖拽到page下

拖拽简单列表组件到页面,未渲染出对应的list

list/meta.ts

export default {
group: 'Antd',
componentName:'AList',
title: '列表',
category: '数据展示',
npm: {
destructuring: true,
componentName: 'AList'
},
props:[
{
title: '数据源',
display: 'block',
type: 'group',
items: [
{
name: 'dataSource',
title: { label: '列表数据源', tip: '列表数据源' },
propType: { type: 'arrayOf', value: 'any' },
setter: ['JsonSetter', 'VariableSetter'],
},
{
name: 'loading',
title: {
label: '是否加载中',
tip: 'loading | 当卡片内容还在加载中时,可以用 loading 展示一个占位',
},
propType: 'bool',
defaultValue: false,
setter: ['BoolSetter', 'VariableSetter'],
},
{
name: 'rowKey',
title: {
label: '行Key',
tip: 'rowKey | 当 renderItem 自定义渲染列表项有效时,自定义每一行的 key 的获取方式',
},
propType: {
type: 'oneOfType',
value: ['string', 'function'],
},
defaultValue: 'id',
setter: [
'StringSetter',
{
componentName: 'FunctionSetter',
props: {
template:
'rowKey(item,${extParams}){\n// 自定义每一行的 key\nreturn key-${item.id};\n}',
},
},
'VariableSetter',
],
},
],
},
{
title: '外观',
display: 'block',
type: 'group',
items: [
{
name: 'itemLayout',
title: {
label: '尺寸',
tip: 'itemLayout | 设置 List.Item 布局, 设置成 vertical 则竖直样式显示, 默认横排',
},
propType: { type: 'oneOf', value: ['horizontal', 'vertical'] },
defaultValue: 'horizontal',
setter: [
{
componentName: 'RadioGroupSetter',
props: {
options: [
{
title: '水平',
value: 'horizontal',
},
{
title: '垂直',
value: 'vertical',
},
],
},
},
'VariableSetter',
],
},
{
name: 'size',
title: { label: '尺寸', tip: 'size | 列表的尺寸' },
propType: { type: 'oneOf', value: ['default', 'large', 'small'] },
defaultValue: 'default',
setter: [
{
componentName: 'RadioGroupSetter',
props: {
options: [
{
title: '默认',
value: 'default',
},
{
title: '大',
value: 'large',
},
{
title: '小',
value: 'small',
},
],
},
},
'VariableSetter',
],
},
{
name: 'bordered',
title: { label: '显示边框', tip: 'bordered | 是否展示边框' },
propType: 'bool',
defaultValue: true,
setter: 'BoolSetter',
},
{
name: 'split',
title: { label: '展示分割线', tip: 'split | 是否展示分割线' },
propType: 'bool',
defaultValue: true,
setter: 'BoolSetter',
},
],
},
{
title: '栅格',
display: 'block',
type: 'group',
items: [
{
name: 'gridEnable',
title: { label: '启用栅格', tip: 'grid | 是否启用栅格' },
propType: 'bool',
setter: 'BoolSetter',
extraProps: {
setValue(target: { node: any; }, value: boolean) {
if (!value) {
const { node } = target;
node.setPropValue('grid', false);
}
},
},
},
{
name: 'grid.column',
title: { label: '列数', tip: 'grid.column | 栅格的列数' },
propType: 'number',
setter: 'NumberSetter',
defaultValue: 4,
condition: {
type: 'JSFunction',
value: 'target => !!target.getProps().getPropValue("gridEnable")',
},
},
{
name: 'grid.gutter',
title: { label: '间隔', tip: 'grid.gutter | 栅格的间隔' },
propType: 'number',
setter: 'NumberSetter',
defaultValue: 0,
condition: {
type: 'JSFunction',
value: 'target => !!target.getProps().getPropValue("gridEnable")',
},
},
],
},
{
title: '分页',
display: 'block',
type: 'group',
items: [
{
name: 'pagination',
title: { label: '显示分页', tip: 'pagination | 显示分页' },
propType: 'object',
setter: 'BoolSetter',
extraProps: {
setValue: (target: { parent: { setPropValue: (arg0: string, arg1: { pageSize: number; }) => void; }; }, value: any) => {
if (value) {
target.parent.setPropValue('pagination', {
pageSize: 5,
});
}
},
},
},
{
name: 'pagination.pageSize',
title: { label: '每页条数', tip: 'pagination.pageSize | 每页条数' },
setter: 'NumberSetter',
condition: {
type: 'JSFunction',
value: 'target => !!target.getProps().getPropValue("pagination")',
},
},
{
name: 'pagination.total',
title: { label: '数据总数', tip: 'pagination.total | 数据总数' },
setter: 'NumberSetter',
condition: {
type: 'JSFunction',
value: 'target => !!target.getProps().getPropValue("pagination")',
},
},
{
name: 'pagination.current',
title: { label: '当前页数', tip: 'pagination.current | 当前页数' },
setter: 'NumberSetter',
condition: {
type: 'JSFunction',
value: 'target => !!target.getProps().getPropValue("pagination")',
},
},
{
name: 'pagination.showTotal',
title: {
label: '显示总数',
tip: 'pagination.showTotal | 用于显示数据总量和当前数据顺序',
},
propType: 'func',
setter: [
{
componentName: 'FunctionSetter',
props: {
template:
'showTotal(total,range,${extParams}){\n// 用于格式化显示表格数据总量\nreturn 共 ${total} 条;\n}',
},
},
'VariableSetter',
],
condition: {
type: 'JSFunction',
value: 'target => !!target.getProps().getPropValue("pagination")',
},
},
{
name: 'pagination.showSizeChanger',
title: {
label: '页数切换',
tip: 'pagination.showSizeChanger | 是否展示 pageSize 切换器',
},
propType: 'bool',
setter: 'BoolSetter',
defaultValue: false,
condition: {
type: 'JSFunction',
value: 'target => !!target.getProps().getPropValue("pagination")',
},
},
{
name: 'pagination.showQuickJumper',
title: {
label: '快速跳转',
tip: 'pagination.showQuickJumper | 是否可以快速跳转至某页',
},
propType: 'bool',
setter: 'BoolSetter',
defaultValue: false,
condition: {
type: 'JSFunction',
value: 'target => !!target.getProps().getPropValue("pagination")',
},
},
{
name: 'pagination.simple',
title: { label: '简单分页', tip: 'pagination.simple | 简单分页' },
propType: 'bool',
setter: 'BoolSetter',
defaultValue: false,
condition: {
type: 'JSFunction',
value: 'target => !!target.getProps().getPropValue("pagination")',
},
},
{
name: 'pagination.size',
title: { label: '分页尺寸', tip: 'pagination.size | 分页尺寸' },
propType: {
type: 'oneOf',
value: ['default', 'small'],
},
setter: [
{
componentName: 'RadioGroupSetter',
props: {
options: [
{
title: '默认',
value: 'default',
},
{
title: '小',
value: 'small',
},
],
},
},
'VariableSetter',
],
defaultValue: 'default',
condition: {
type: 'JSFunction',
value: 'target => !!target.getProps().getPropValue("pagination")',
},
},
{
name: 'pagination.position',
title: { label: '分页位置', tip: 'pagination.position | 分页位置' },
setter: {
componentName: 'SelectSetter',
props: {
options: [
{
title: '上',
value: 'top',
},
{
title: '下',
value: 'bottom',
},
{
title: '上下',
value: 'both',
},
],
},
initialValue: 'bottomRight',
},
condition: {
type: 'JSFunction',
value: 'target => !!target.getProps().getPropValue("pagination")',
},
},
],
},
{
title: '扩展',
display: 'block',
type: 'group',
items: [
{
name: 'renderItem',
title: {
label: '渲染函数',
tip: 'renderItem | 当使用 dataSource 时,可以用 renderItem 自定义渲染列表项',
},
propType: 'func',
setter: [
{
componentName: 'SlotSetter',
title: '渲染函数插槽',
initialValue: {
type: 'JSSlot',
params: ['item'],
value: [
{
componentName: 'AListItem',
props: {},
children: {
componentName: 'ATypographyText',
props: {
children: {
type: 'JSExpression',
value: 'this.item.text',
},
},
},
},
],
},
},
{
componentName: 'FunctionSetter',
props: {
template: 'renderItem(item,${extParams}){\n// 自定义渲染列表项\nreturn item;\n}',
},
},
'VariableSetter',
],
},
{
name: 'header',
title: {
label: '列表头部',
tip: 'header | 列表头部',
},
propType: 'node',
setter: {
componentName: 'SlotSetter',
initialValue: {
type: 'JSSlot',
value: [
{
componentName: 'ATypographyText',
props: {
children: '列表头部',
},
},
],
},
},
},
{
name: 'footer',
title: {
label: '列表底部',
tip: 'footer | 列表底部',
},
propType: 'node',
setter: {
componentName: 'SlotSetter',
initialValue: {
type: 'JSSlot',
value: [
{
componentName: 'ATypographyText',
props: {
children: '列表底部',
},
},
],
},
},
},
{
name: 'loadMore',
title: {
label: '加载更多',
tip: 'loadMore | 加载更多',
},
propType: 'node',
setter: {
componentName: 'SlotSetter',
initialValue: {
type: 'JSSlot',
value: [
{
componentName: 'AButton',
props: {
children: 'loading more',
},
},
],
},
},
},
],
},
],
configure: {
supports: {
style:true,
events:[
{
name: 'pagination.onChange',
template: 'onChange(page,pageSize,${extParams}){\n// 页码或 pageSize 改变的回调\n}',
}
]
}
},
snippets:[
{
title: '简单列表',
screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/list-1.png',
schema: {
componentName: 'AList',
props: {
dataSource: [
{
id: 1,
text: 'Racing car sprays burning fuel into crowd.',
},
{
id: 2,
text: 'Japanese princess to wed commoner.',
},
{
id: 3,
text: 'Australian walks 100km after outback crash.',
},
{
id: 4,
text: 'Man charged over missing wedding girl.',
},
{
id: 5,
text: 'Los Angeles battles huge wildfires.',
},
],
renderItem: {
type: 'JSSlot',
params: ['item'],
value: [
{
componentName: 'AListItem',
props: {},
children: {
componentName: 'ATypographyText',
props: {
children: {
type: 'JSExpression',
value: 'this.item.text',
},
},
},
},
],
},
header: {
type: 'JSSlot',
value: [
{
componentName: 'ATypographyText',
props: {
children: '列表头部',
},
},
],
},
footer: {
type: 'JSSlot',
value: [
{
componentName: 'ATypographyText',
props: {
children: '列表底部',
},
},
],
},
itemLayout: 'horizontal',
size: 'default',
bordered: true,
split: true,
pagination: {
pageSize: 5,
total: 10,
current: 1,
},
},
},
},
{
title: '基础列表',
screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/list-1.png',
schema: {
componentName: 'AList',
props: {
dataSource: [
{
id: 1,
title: 'Ant Design Title 1',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png',
description:
'Ant Design, a design language for background applications, is refined by Ant UED Team',
},
{
id: 2,
title: 'Ant Design Title 2',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png',
description:
'Ant Design, a design language for background applications, is refined by Ant UED Team',
},
{
id: 3,
title: 'Ant Design Title 3',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png',
description:
'Ant Design, a design language for background applications, is refined by Ant UED Team',
},
{
id: 4,
title: 'Ant Design Title 4',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png',
description:
'Ant Design, a design language for background applications, is refined by Ant UED Team',
},
{
id: 5,
title: 'Ant Design Title 5',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png',
description:
'Ant Design, a design language for background applications, is refined by Ant UED Team',
},
],
renderItem: {
type: 'JSSlot',
params: ['item'],
value: [
{
componentName: 'AListItem',
props: {},
children: {
componentName: 'AListItemMeta',
props: {
avatar: {
type: 'JSSlot',
value: [
{
componentName: 'AAvatar',
props: {
// icon: {
// componentName: 'AIcon',
// props: {
// type: 'UserOutlined',
// },
// },
src: {
type: 'JSExpression',
value: 'this.item.avatar',
},
},
},
],
},
title: {
type: 'JSSlot',
value: [
{
componentName: 'ATypographyLink',
props: {
children: {
type: 'JSExpression',
value: 'this.item.title',
},
},
},
],
},
description: {
type: 'JSSlot',
value: [
{
componentName: 'ATypographyText',
props: {
children: {
type: 'JSExpression',
value: 'this.item.description',
},
},
},
],
},
},
},
},
],
},
itemLayout: 'horizontal',
size: 'default',
bordered: true,
split: true,
pagination: {
pageSize: 10,
total: 15,
current: 1,
},
},
},
}
]
}

版本信息
AliLowCodeEngine: v1.1.7-beta ,
AliLowCodeExt :v1.0.6-beta.27 ,
vue: v3.2.47,
@knxcloud/lowcode-plugin-vue-code-editor: v0.0.1-beta.6,
@knxcloud/lowcode-utils: v1.6.0-beta.5,
@knxcloud/lowcode-vue-renderer: v1.6.0-beta.7,
@knxcloud/lowcode-vue-simulator-renderer: v1.6.0-beta.7

报错了

G:\Developer\IDEA\lowcode\lowcode-engine-vue>pnpm start

@ start G:\Developer\IDEA\lowcode\lowcode-engine-vue
pnpm -C packages/vue-simulator-renderer start

@knxcloud/[email protected] start G:\Developer\IDEA\lowcode\lowcode-engine-vue\packages\vue-simulator-renderer
build-scripts start --disable-open --port 5559 --config=build.umd.json

@alib/build-scripts 0.1.32

ERROR Failed to compile with 3 errors 14:47:31
These dependencies were not found:

  • @knxcloud/lowcode-utils in ./src/simulator.ts
  • @knxcloud/lowcode-vue-renderer in ./src/index.ts, ./src/simulator-view.ts

[Feature] 支持低代码组件的交互体验优化

场景

低代码组件可以通过获取到适配器的相关信息,从而实现一些优化低代码引擎使用体验的交互效果

方案

提供一个新的包用于自定义组件和画布通讯

<script setup lang="ts">
import { useCurrentNode } from '@knxcloud/lowcode-hooks'

const { node, isDesignerEnv } = useCurrentNode();

const formNode = node.document.createNode({
    componentName: 'LcForm'
})

node.parent.insertBefore(formNode);
</script>

未支持JSSlot的解析

naive-ui 的 NDataTable 的操作栏 使用JSSlot自定义渲染(形如Antd table),未解析JSSlot
image
image

[Feature] 适配模态框组件渲染

场景

模态框组件拖拽进入设计器之后,会在画布上渲染出一个注释节点,导致无法正确获取到模态框的正确 dom 元素

适配方案

当组件渲染的根节点为注释节点,或为文本节点且文本值为空时,自动查找其临近兄弟节点是否为当前组件的子元素,若为子元素则将其作为当前组件的 dom 节点返回给设计器

与 react 的差异

  • 弹窗打开方式
    this.$('pro-dialog-entryl32xgrus').open(); -> this.$refs['pro-dialog-entryl32xgrus'].open();

画布无法选择到组件

复现步骤:随便拖几个物料到画布,发现选中的画布都是最外层的
原因:v1.1.0后,instance实例没有SYMBOL_VNID, SYMBOL_VDID,SYMBOL_VInstance属性,导致无法获取到正确实例

simulator.getClosestNodeInstance = (el: Element, specId) => {
    while (el) {
      if (isComponentHTMLElement(el)) {
        const nodeId = el[SYMBOL_VNID]; // undefined
        const docId = el[SYMBOL_VDID]; / undefined
        const instance = el[SYMBOL_VInstance]; // undefined
        if (!specId || specId === nodeId) {
          return {
            docId,
            nodeId,
            instance: { nid: nodeId, did: docId, cid: instance.uid },
          };
        }
      }
      el = el.parentElement as Element;
    }
    return null;
  };
// 这个方法会进入死循环,因为没有cid,有did
simulator.findDOMNodes = (instance: any) => {
    if (!instance) return null;
    const { did, cid } = instance;
    console.log('find', instance);
    const documentInstance = documentInstanceMap.get(did);
    if (!documentInstance) return null;
    const compInst = documentInstance.getComponentInstance(cid);
    return compInst ? [compInst.$el] : null;
  };

画布初始化时没有组件,直接修改js面板报错,导致画布渲染失败

复现方式

  1. 使用lowcode-engine-demo项目,将schema.json文件中改为下面这个配置(默认不带组件)
{
  "componentName": "Page",
  "id": "node_dockcviv8fo1",
  "props": {},
  "fileName": "主页",
  "state": {
    "text": {
      "type": "JSExpression",
      "value": "\"outer\""
    },
    "isShowDialog": {
      "type": "JSExpression",
      "value": "false"
    },
    "info": {
      "type": "JSExpression",
      "value": "{\n  info: \"\",\n  user: {\n    username: \"\",\n    password: \"\"\n  }\n}"
    }
  },
  "meta": {
    "router": "main",
    "level": 1,
    "pageType": "1"
  },
  "dataSource": {
    "list": [
      {
        "type": "fetch",
        "isInit": true,
        "options": {
          "params": {},
          "method": "GET",
          "isCors": true,
          "timeout": 5000,
          "headers": {},
          "uri": "mock/info.json"
        },
        "id": "info"
      },
      {
        "type": "fetch",
        "isInit": false,
        "options": {
          "params": {
            "username": {
              "type": "JSExpression",
              "value": "this.info.user.username"
            },
            "password": {
              "type": "JSExpression",
              "value": "this.info.user.password"
            }
          },
          "method": "POST",
          "isCors": true,
          "timeout": 5000,
          "headers": {
            "Auth": {
              "type": "JSExpression",
              "value": "this.text"
            },
            "Content-Type": "application/json"
          },
          "uri": "/api/user/login"
        },
        "id": "submit"
      }
    ]
  },
  "css": "body {\n  font-size: 12px;\n}\n\n.button {\n  width: 100px;\n  color: #ff00ff\n}",
  "lifeCycles": {
    "mounted": {
      "type": "JSFunction",
      "value": "function mounted() {\n  console.log('did mount');\n}"
    },
    "beforeMount": {
      "type": "JSFunction",
      "value": "function beforeMount() {\n  console.log('will unmount');\n}"
    }
  },
  "methods": {
    "testFunc": {
      "type": "JSFunction",
      "value": "function testFunc() {\n  console.log('test func');\n}"
    }
  },
  "originCode": "class LowcodeComponent extends Component {\n  state = {\n    \"text\": \"outer\",\n    \"isShowDialog\": false,\n    \"info\": {\n      \"info\": \"\",\n      \"user\": {\n        \"username\": \"\",\n        \"password\": \"\"\n      }\n    }\n  }\n  componentDidMount() {\n    console.log('did mount');\n  }\n  componentWillUnmount() {\n    console.log('will unmount');\n  }\n  testFunc() {\n    console.log('test func');\n  }\n  onClick() {\n    this.setState({\n      isShowDialog: true\n    })\n  }\n  closeDialog() {\n    this.setState({\n      isShowDialog: false\n    })\n  }\n\n\tonClick_new(){\n    this.$message.success('hhhhhh')\n\t}\n\n\tonSubmit(ev){\n    ev.preventDefault();\n    this.dataSourceMap.submit.load()\n\t}\n}",
  "hidden": false,
  "title": "",
  "isLocked": false,
  "condition": true,
  "conditionGroup": ""
}
  1. 启动项目后在浏览器中打开·源码面板·,随便修改内容。报错。然后就会画布中的插槽就会消失,控制台报错。

图片

image
2. 打开源码面板随便修改,例如将函数名由testFunc() 修改为testFunc2()
image
3. 保存 ,页面插槽消失控制台报错
image
image

vue插槽渲染组件中使用this获取插槽传过来的值不生效

image
image
我使用的是antd-vue组件库生成的物料,在设置table的expandedRowRender属性时,使用slot,拖进去一个成功提示的组件,然后自定义成功提示组件的描述性息和警告提示内容变量,使用的是slot传值过来的record和index属性,通过this.record和this.index获取,但是不生效

作用域内置对象的支持

请问一下,下述注释的内置对象是否有支持计划?

this: '容器上下文对象',
  // context: '容器的context',
  // schema: '页面上下文对象',
  // component: '组件上下文对象',
  // constants: '应用常量对象',
  // utils: '应用工具对象',
  dataSourceMap: '容器数据源Map',
  // field: '表单Field对象',

编辑源码保存后,报错

image

  1. 新增了一个 count变量,点击按钮后,count+1
  2. 拖入一个文本组件,文本内容绑定this.state.count,控制台直接报错,文本组件也不显示了

需要适配代码编辑器吗?

代码里面的 isNil 会一直是 false

return val === null && val === undefined; 应该是 return val === null || val === undefined;

export function isNil<T>(val: T | null | undefined): val is null | undefined {
  return val === null && val === undefined;
}

警告提示疑问

判断条件是 __vue_app__ 为什么提示的是 __vnode ? 应该是 __vnode ?

  if (!isCommentNode(el) && !('__vue_app__' in el)) {
    warn('__vnode 没有找到,请使用 vue 非生产环境版本');
    warn('https://unpkg.com/vue/dist/vue.runtime.global.js');
  }

[Feature] 支持 requestHandlersMap 参数自定义请求

场景

通过传入 requestHandlersMap 参数,控制请求方式对应的发送请求的行为

实例

设计器

import { init, project } from '@alilc/lowcode-engine';
import { setupHostEnvironment } from '@knxcloud/lowcode-utils';
import { RuntimeOptionsConfig } from '@alilc/lowcode-datasource-types';

setupHostEnvironment(project);

init(document.getElementById('lce'), {
  // ...
  simulatorUrl: [
    'https://unpkg.com/@knxcloud/lowcode-vue-simulator-renderer/dist/vue-simulator-renderer.js',
    'https://unpkg.com/@knxcloud/lowcode-vue-simulator-renderer/dist/vue-simulator-renderer.css',
  ],
  requestHandlersMap: {
    fetch: (options: RuntimeOptionsConfig) => {
        // ... 发送请求逻辑
        return axios.request(/* ... */)
    }
  },
});

渲染器

import VueRenderer from '@knxcloud/lowcode-vue-renderer';
import { RuntimeOptionsConfig } from '@alilc/lowcode-datasource-types';

const createFetcher = () => {
  return (options: RuntimeOptionsConfig) => {
    // ... 发送请求逻辑
    return axios.request(/* ... */
  }
}
const App = () => {
  return (
    <VueRenderer
      requestHandlersMap={{ fetch: createFetcher() }}
    ></VueRenderer>
  )
}

请问 isContainer 默认不显示子元素怎么处理?手动加了个自定义内容插槽,才会显示

配置如下

{
      "componentName": "UniCol",
      "title": "布局-列",
      "category": "数据展示",
      "npm": {
        "package": "uni-lib",
        "version": "1.0.0",
        "exportName": "TnCol",
        "destructuring": true
      },
      "props": [
        {
          "name": "children",
          "title": { "label": "自定义内容" },
          "propType": "node"
        },
        {
          "name": "float",
          "title": { "label": "是否浮动", "tip": "float | 是否浮动" },
          "propType": "bool",
          "setter": ["BoolSetter", "VariableSetter"],
          "defaultValue": true
        },
        {
          "name": "span",
          "title": { "label": "列数", "tip": "span | 栅格占据的列数" },
          "propType": "number",
          "setter": {
            "componentName": "NumberSetter",
            "props": { "min": 1, "max": 24 }
          },
          "defaultValue": 24
        },
        {
          "name": "offset",
          "title": {
            "label": "间隔格数",
            "tip": "offset | 栅格左侧的间隔格数"
          },
          "propType": "number",
          "setter": {
            "componentName": "NumberSetter",
            "props": { "min": -1, "max": 24 }
          },
          "defaultValue": -1
        },
        {
          "name": "pull",
          "title": {
            "label": "向左移动格数",
            "tip": "pull | 栅格向左移动格数"
          },
          "propType": "number",
          "setter": {
            "componentName": "NumberSetter",
            "props": { "min": -1, "max": 24 }
          },
          "defaultValue": -1
        },
        {
          "name": "push",
          "title": {
            "label": "向右移动格数",
            "tip": "push | 栅格向右移动格数"
          },
          "propType": "number",
          "setter": {
            "componentName": "NumberSetter",
            "props": { "min": -1, "max": 24 }
          },
          "defaultValue": -1
        }
      ],
      "configure": {
        "components": {
          "isContainer": true,
          "nestingRule": { "parentWhitelist": ["UniRow"] }
        },
        "supports": {
          "style": true,
          "events": [
            {
              "name": "onClick",
              "template": "onClick(e){\n// 点击事件\nconsole.log('onClick', e);}"
            }
          ]
        }
      }
    }

操作视频:

1.mp4

迁移ant design vue时部分组件拖拽到设计器时不能正常显示

版本:
ant design vue 3.2.20
设计器:使用lowcode-engine-vue-demo库中的设计器
测试方法:替换lowcode-engine-vue-demo库的assets文件
问题描述:模态框组件(底部抽屉,侧边抽屉,普通模态框)拖拽后在设计器中没反应(空白),但是右侧属性面板能显示,左侧大纲中有组件信息。
注:更新了assets相关信息。同时assets中组件均迁移自
https://github.com/alibaba/lowcode-materials/tree/main/packages/antd-lowcode-materials/lowcode
模态框部分有问题的组件如下:
https://github.com/alibaba/lowcode-materials/tree/main/packages/antd-lowcode-materials/lowcode/drawer
https://github.com/alibaba/lowcode-materials/tree/main/packages/antd-lowcode-materials/lowcode/modal

请使用更新后的assets文件
assets-202308111405.zip

报错了

G:\Developer\IDEA\lowcode\lowcode-engine-vue>pnpm start

@ start G:\Developer\IDEA\lowcode\lowcode-engine-vue
pnpm -C packages/vue-simulator-renderer start

@knxcloud/[email protected] start G:\Developer\IDEA\lowcode\lowcode-engine-vue\packages\vue-simulator-renderer
build-scripts start --disable-open --port 5559 --config=build.umd.json

@alib/build-scripts 0.1.32

ERROR Failed to compile with 3 errors 14:47:31
These dependencies were not found:

  • @knxcloud/lowcode-utils in ./src/simulator.ts
  • @knxcloud/lowcode-vue-renderer in ./src/index.ts, ./src/simulator-view.ts

自定义物料无法拖拽到页面,报错

复现步骤:

  1. 运行demo项目
  2. 拖入简单列表组件
    image
    3.控制台报错
    image

版本信息
@knxcloud/lowcode-plugin-vue-code-editor:v 0.0.1-beta.6,
@knxcloud/lowcode-utils v1.6.0-beta.5,
@knxcloud/lowcode-vue-renderer: v1.6.0-beta.7,
@knxcloud/lowcode-vue-simulator-renderer: v1.6.0-beta.7,
AliLowCodeEngine:v1.1.7-beta ,
AliLowCodeExt:v1.0.6-beta.27

画布国际化有点问题

element-plus locale应该是一个对象
image
demo项目的国际化也有问题,vue-renderer组件的props.locale默认为undefined,会覆盖demo configProvide传过去的locale
image
image

使用ant-design-vue的表格列,最后一列使用自定义渲染,在预览模式展示有问题

复现步骤

  1. 拖入ant-design-vue的自定义表格组件,默认有数据展示,表格列增加一项,操作列,开启自定义渲染
  2. 出现如下插槽组件
    image

3.将文字按钮组件拖入插槽处
image
4. 按钮绑定事件,传入参数,其中事件的传入参数为{ "data": this.data.record },在methods中定义按钮绑定事件,将操作列的参数传入并赋值给当前项变量
image
5. 拖入对话框-普通型组件,绑定是否可见为showDetail,在对话框中拖入2个文本,分别绑定为
this.currentRow.name和this.currentRow.address
image
6. 点击预览按钮,在页面点击详情,不断出现如下告警,对话框没有正常展示

image

预期

预览模式中点击详情按钮可以正常展示对话框,并且文本数据正确渲染

源码面板js

import { defineComponent,toRaw } from 'vue';

export default defineComponent({
props: {
style: {
type: Object,
default: {}
},
},
data: () => ({
text: "outer",
showDetail: false,
searchVal:'',
currentRow:{},
allList: [{
"id": "1",
"name": "毛不易",
"age": 32,
"address": "西湖区湖底公园1号",
"tag":"幼鸟指南"
}, {
"id": "2",
"name": "邓紫棋",
"age": 28,
"address": "滨江区网商路699号",
"tag":"高音天后"
}],
userList: [],
}),
methods: {
onDetail(e,data){
this.currentRow = toRaw(data);
console.log('打开详情', this.currentRow,data);
this.showDetail = true;
},
onCloseDetail(){
this.showDetail = false;
},
testFunc() {
console.log('test func');
},
filterList(){
if(!this.searchVal) {
this.userList = [...this.allList];
return;
}
const origin = [...this.allList];
this.userList = origin.filter(item=>{
return item.name === this.searchVal;
})
},
onSelectChange(val,option){
this.searchVal = option.label?option.label:'';
this.filterList();
},
onDeselect(e){
console.log('取消选中',e);
},
expandedRowRender(record,index){
console.log('record',record);
return ${record.tag};
}
},
mounted() {
this.userList = [...this.allList];
console.log('did mount');
},
beforeMount() {
console.log('will unmount');
},
})

JS代码编辑器插件

问题:按钮onClick事件无法自动添加到代码编辑器中
截图:
image
版本信息:

    "@knxcloud/lowcode-plugin-vue-code-editor": "0.0.1-beta.6",
    "@knxcloud/lowcode-utils": "^1.6.0-beta.5",
    "@knxcloud/lowcode-vue-renderer": "1.6.0-beta.7",
    "@knxcloud/lowcode-vue-simulator-renderer": "1.6.0-beta.7"

Routing Hooks Support (TODO)

If possible, would like to extend the route hooks (beforeRouteEnter, beforeRouteLeave)

But this only works for edit-like, not for preview pages at the moment.
image

支持Template、Block、Component结构

说明

目前vue-renderer中只实现了Page结构的物料规范,其他类型的物料未实现,请求实现。

协议地址

https://lowcode-engine.cn/lowcode

相关说明位置

低代码引擎搭建协议规范

  • 1.6.1 物料系统名词
  • 2.3 组件树描述 关于容器结构的描述
  • 2.3.3 容器结构描述
  • 2.3.5.1 容器API
  • 3 应用描述

低代码引擎物料协议规范

  • 1.6 名词术语
  • 3 物料规范-区块规范
  • 4 物料规范-模板规范

容器当中占位元素的类名不对

复现工具

本项目的demo,和lowcode-engine.cn提供的demo。分别添加一个容器物料,查看容器物料中占位元素的情况。

本项目demo中的情形

5ae0612b2efcd3a817e5ef1929b2753

官方demo中的情形

27128c4f1663d82f730116330ff239d

问题

可以看到一个是渲染的lc-container,一个是渲染的lc-container-placeholder,在渲染lc-container的情况下,当容器宽度小于lc-container文字宽度的时候,文字不换行,会撑开容器导致宽度不对,而lc-container-placeholder则会在这时文字换行,不会有宽度问题。
如下:
lc-container
image
lc-container-placeholder
image

代码

对比:
本项目中vue-renderer/src/core/use.ts:82

if (isDesignMode && node?.isContainer()) return h('div', { class: 'lc-container' });

官方项目react-renderer/src/renderer-view.tsx:239

// 如果是容器 && 无children && 高宽为空 增加一个占位容器,方便拖动
if (
            !viewProps.dataSource &&
            leaf?.isContainer() &&
            (children == null || (Array.isArray(children) && !children.length)) &&
            (!viewProps.style || Object.keys(viewProps.style).length === 0)
          ) {
            children = (
              <div className="lc-container-placeholder" style={viewProps.placeholderStyle}>
                {viewProps.placeholder || '拖拽组件或模板到这里'}
              </div>
            );
          }

对于容器中占位元素的处理不同。

而引擎中关于lc-container-placeholder的处理只有此一处,lc-container的处理也只有slot一处,所以我认为lc-container是给slot用的,而lc-container-placeholder是给容器占位元素用的。

从官方的注释当中也可以看出端倪。

内部的HOC包装组件(wrapLeafComp)有问题

image

这里对第三方的组件进行改写包装(HOC), 但是组件的属性没有完全的继承过来, 比如name, components; 目前发现elementPlus中ElTabelColumn 嵌套ElTabelColumn 是无法渲染, 因为elementPlus内部使用了name 属性; 对于compoents, 若果使用的第三方组件, 内部的组件是私有,那将无法渲染, 若还有其他属性用于运行组件内部运行的判断可能也将无法预期渲染, 这里应该将改写的属性覆盖, 其他的属性继承过来

image 以下场景将无法渲染 image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.