Commit f5339844 authored by bqy_fe's avatar bqy_fe
Browse files

feat: :sparkles:添加组件事件

parent 249179ce
No related merge requests found
Showing with 270 additions and 147 deletions
+270 -147
# 只在开发模式中被载入 # 只在开发模式中被载入
# 网站标题
VITE_APP_TITLE = H5低代码
# 网站前缀 # 网站前缀
VITE_BASE_URL = / VITE_BASE_URL = /
......
# 只在生产模式中被载入 # 只在生产模式中被载入
# 网站标题
VITE_APP_TITLE = H5低代码
# 网站前缀 # 网站前缀
VITE_BASE_URL = /vite-vue3-lowcode/ VITE_BASE_URL = /vite-vue3-lowcode/
......
...@@ -49,20 +49,22 @@ let propObj = { ...@@ -49,20 +49,22 @@ let propObj = {
boolean: (config) => `createEditorSwitchProp(${JSON.stringify(config)})` boolean: (config) => `createEditorSwitchProp(${JSON.stringify(config)})`
} }
$$('#props + table tr').reduce((prev, curr) => { JSON.stringify(
const children = curr.children $$('#props + table tbody tr').reduce((prev, curr) => {
const key = children[0].textContent.replace(/-([a-z])/g, (all, i) => i.toUpperCase()) const children = curr.children
const child3Text = children[3].textContent const key = children[0].textContent.replace(/-([a-z])/g, (all, i) => i.toUpperCase())
const defaultValue = ['true', 'false'].includes(child3Text) const child3Text = children[3].textContent
? child3Text const defaultValue = ['true', 'false'].includes(child3Text)
: `'${child3Text == '-' ? '' : child3Text}'` ? child3Text
const value = (propObj[children[2].textContent] ?? propObj['string'])({ : `'${child3Text == '-' ? '' : child3Text}'`
label: `'${children[1].textContent}'`, const value = (propObj[children[2].textContent] ?? propObj['string'])({
defaultValue label: `'${children[1].textContent}'`,
}).replaceAll('"', '') defaultValue
prev[key] = value }).replaceAll('"', '')
return prev prev[key] = value
}, {}) return prev
}, {})
).replaceAll('"', '')
``` ```
## Browser support ## Browser support
......
...@@ -56,20 +56,38 @@ let propObj = { ...@@ -56,20 +56,38 @@ let propObj = {
boolean: (config) => `createEditorSwitchProp(${JSON.stringify(config)})` boolean: (config) => `createEditorSwitchProp(${JSON.stringify(config)})`
} }
$$('#props + table tr').reduce((prev, curr) => { JSON.stringify(
const children = curr.children $$('#props + table tbody tr').reduce((prev, curr) => {
const key = children[0].textContent.replace(/-([a-z])/g, (all, i) => i.toUpperCase()) const children = curr.children
const child3Text = children[3].textContent const key = children[0].textContent.replace(/-([a-z])/g, (all, i) => i.toUpperCase())
const defaultValue = ['true', 'false'].includes(child3Text) const child3Text = children[3].textContent
? child3Text const defaultValue = ['true', 'false'].includes(child3Text)
: `'${child3Text == '-' ? '' : child3Text}'` ? child3Text
const value = (propObj[children[2].textContent] ?? propObj['string'])({ : `'${child3Text == '-' ? '' : child3Text}'`
label: `'${children[1].textContent}'`, const value = (propObj[children[2].textContent] ?? propObj['string'])({
defaultValue label: `'${children[1].textContent}'`,
}).replaceAll('"', '') defaultValue
prev[key] = value }).replaceAll('"', '')
return prev prev[key] = value
}, {}) return prev
}, {})
).replaceAll('"', '')
```
```javascript
// 在vant文档中 chrome控制台输入以下代码,快速生成组件事件
JSON.stringify(
$$('#events + table tbody tr').reduce((prev, curr) => {
const children = curr.children
const event = {
label: children[1].textContent,
value: children[0].textContent
}
return prev.concat([event])
}, [])
)
.replaceAll(/(?<!:)\"(?!,|})/g, '')
.replace(/\"/g, "'")
``` ```
## 浏览器支持 ## 浏览器支持
......
...@@ -3,30 +3,29 @@ ...@@ -3,30 +3,29 @@
declare module 'vue' { declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {
ElHeader: typeof import('element-plus/es/el-header')['default']
ElAside: typeof import('element-plus/es/el-aside')['default'] ElAside: typeof import('element-plus/es/el-aside')['default']
ElMain: typeof import('element-plus/es/el-main')['default']
ElContainer: typeof import('element-plus/es/el-container')['default']
ElCol: typeof import('element-plus/es/el-col')['default']
ElButton: typeof import('element-plus/es/el-button')['default'] ElButton: typeof import('element-plus/es/el-button')['default']
ElTooltip: typeof import('element-plus/es/el-tooltip')['default'] ElCol: typeof import('element-plus/es/el-col')['default']
ElRow: typeof import('element-plus/es/el-row')['default'] ElCollapse: typeof import('element-plus/es/el-collapse')['default']
ElPopover: typeof import('element-plus/es/el-popover')['default'] ElCollapseItem: typeof import('element-plus/es/el-collapse-item')['default']
ElTabPane: typeof import('element-plus/es/el-tab-pane')['default'] ElContainer: typeof import('element-plus/es/el-container')['default']
ElTabs: typeof import('element-plus/es/el-tabs')['default']
ElDialog: typeof import('element-plus/es/el-dialog')['default'] ElDialog: typeof import('element-plus/es/el-dialog')['default']
ElTag: typeof import('element-plus/es/el-tag')['default'] ElDropdown: typeof import('element-plus/es/el-dropdown')['default']
ElDropdownItem: typeof import('element-plus/es/el-dropdown-item')['default'] ElDropdownItem: typeof import('element-plus/es/el-dropdown-item')['default']
ElDropdownMenu: typeof import('element-plus/es/el-dropdown-menu')['default'] ElDropdownMenu: typeof import('element-plus/es/el-dropdown-menu')['default']
ElDropdown: typeof import('element-plus/es/el-dropdown')['default']
ElTree: typeof import('element-plus/es/el-tree')['default']
ElInput: typeof import('element-plus/es/el-input')['default']
ElFormItem: typeof import('element-plus/es/el-form-item')['default']
ElForm: typeof import('element-plus/es/el-form')['default'] ElForm: typeof import('element-plus/es/el-form')['default']
ElFormItem: typeof import('element-plus/es/el-form-item')['default']
ElHeader: typeof import('element-plus/es/el-header')['default']
ElInput: typeof import('element-plus/es/el-input')['default']
ElMain: typeof import('element-plus/es/el-main')['default']
ElPopconfirm: typeof import('element-plus/es/el-popconfirm')['default'] ElPopconfirm: typeof import('element-plus/es/el-popconfirm')['default']
ElCollapseItem: typeof import('element-plus/es/el-collapse-item')['default'] ElPopover: typeof import('element-plus/es/el-popover')['default']
ElCollapse: typeof import('element-plus/es/el-collapse')['default'] ElRow: typeof import('element-plus/es/el-row')['default']
ElInfiniteScroll: typeof import('element-plus/es/el-infinite-scroll')['default'] ElTabPane: typeof import('element-plus/es/el-tab-pane')['default']
ElTabs: typeof import('element-plus/es/el-tabs')['default']
ElTag: typeof import('element-plus/es/el-tag')['default']
ElTooltip: typeof import('element-plus/es/el-tooltip')['default']
ElTree: typeof import('element-plus/es/el-tree')['default']
} }
} }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title> <title>H5低代码</title>
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
......
...@@ -27,15 +27,15 @@ ...@@ -27,15 +27,15 @@
"axios": "^0.21.1", "axios": "^0.21.1",
"dayjs": "^1.10.5", "dayjs": "^1.10.5",
"dexie": "^3.0.3", "dexie": "^3.0.3",
"element-plus": "1.0.2-beta.52", "element-plus": "1.0.2-beta.54",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"monaco-editor": "^0.25.2", "monaco-editor": "^0.25.2",
"normalize.css": "^8.0.1", "normalize.css": "^8.0.1",
"nprogress": "^1.0.0-1", "nprogress": "^1.0.0-1",
"qrcode": "^1.4.4", "qrcode": "^1.4.4",
"qs": "^6.10.1", "qs": "^6.10.1",
"vant": "^3.1.0", "vant": "^3.1.2",
"vue": "3.1.2", "vue": "3.1.4",
"vue-router": "^4.0.10", "vue-router": "^4.0.10",
"vuedraggable": "^4.0.3", "vuedraggable": "^4.0.3",
"vuex": "^4.0.2" "vuex": "^4.0.2"
...@@ -43,24 +43,24 @@ ...@@ -43,24 +43,24 @@
"devDependencies": { "devDependencies": {
"@commitlint/cli": "^12.1.4", "@commitlint/cli": "^12.1.4",
"@commitlint/config-conventional": "^12.1.4", "@commitlint/config-conventional": "^12.1.4",
"@types/node": "^15.12.4", "@types/node": "^16.0.0",
"@typescript-eslint/eslint-plugin": "^4.28.0", "@typescript-eslint/eslint-plugin": "^4.28.1",
"@typescript-eslint/parser": "^4.28.0", "@typescript-eslint/parser": "^4.28.1",
"@vitejs/plugin-legacy": "^1.4.2", "@vitejs/plugin-legacy": "^1.4.3",
"@vitejs/plugin-vue": "^1.2.3", "@vitejs/plugin-vue": "^1.2.4",
"@vitejs/plugin-vue-jsx": "^1.1.5", "@vitejs/plugin-vue-jsx": "^1.1.6",
"@vue/compiler-sfc": "3.1.2", "@vue/compiler-sfc": "3.1.4",
"commitizen": "^4.2.4", "commitizen": "^4.2.4",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"cz-conventional-changelog": "^3.3.0", "cz-conventional-changelog": "^3.3.0",
"cz-customizable": "^6.3.0", "cz-customizable": "^6.3.0",
"eslint": "^7.29.0", "eslint": "^7.30.0",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.23.4", "eslint-plugin-import": "^2.23.4",
"eslint-plugin-prettier": "^3.4.0", "eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-vue": "^7.12.1", "eslint-plugin-vue": "^7.12.1",
"gh-pages": "^3.2.3", "gh-pages": "^3.2.3",
"husky": "^6.0.0", "husky": "^7.0.0",
"lint-staged": "^11.0.0", "lint-staged": "^11.0.0",
"prettier": "^2.3.2", "prettier": "^2.3.2",
"pretty-quick": "^3.1.1", "pretty-quick": "^3.1.1",
...@@ -69,14 +69,14 @@ ...@@ -69,14 +69,14 @@
"stylelint-config-prettier": "^8.0.2", "stylelint-config-prettier": "^8.0.2",
"stylelint-config-standard": "^22.0.0", "stylelint-config-standard": "^22.0.0",
"stylelint-order": "^4.1.0", "stylelint-order": "^4.1.0",
"typescript": "^4.3.4", "typescript": "^4.3.5",
"vite": "2.3.8", "vite": "2.3.8",
"vite-plugin-components": "^0.11.2", "vite-plugin-components": "^0.12.0",
"vite-plugin-style-import": "^1.0.1", "vite-plugin-style-import": "^1.0.1",
"vite-plugin-windicss": "^1.1.1", "vite-plugin-windicss": "^1.2.0",
"vue-eslint-parser": "^7.6.0", "vue-eslint-parser": "^7.7.2",
"vue-tsc": "^0.2.0", "vue-tsc": "^0.2.0",
"windicss": "^3.1.3" "windicss": "^3.1.4"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
......
<!-- <!--
* @Author: 卜启缘 * @Author: 卜启缘
* @Date: 2021-06-01 09:45:21 * @Date: 2021-06-01 09:45:21
* @LastEditTime: 2021-06-25 08:47:36 * @LastEditTime: 2021-07-04 08:59:57
* @LastEditors: 卜启缘 * @LastEditors: 卜启缘
* @Description: * @Description:
* @FilePath: \vite-vue3-lowcode\preview\views\preview.vue * @FilePath: \vite-vue3-lowcode\preview\views\preview.vue
--> -->
<template> <template>
<template v-for="outItem in blocks" :key="outItem._vid"> <template v-for="outItem in blocks" :key="outItem._vid">
<slot-item :element="outItem" :config="visualConfig" /> <slot-item :element="outItem" :models="models" :actions="actions" :config="visualConfig" />
</template> </template>
</template> </template>
...@@ -69,6 +69,8 @@ export default defineComponent({ ...@@ -69,6 +69,8 @@ export default defineComponent({
return { return {
...toRefs(state), ...toRefs(state),
actions: jsonData.actions,
models: jsonData.models,
visualConfig visualConfig
} }
} }
......
<!-- <!--
* @Author: 卜启缘 * @Author: 卜启缘
* @Date: 2021-06-12 22:18:48 * @Date: 2021-06-12 22:18:48
* @LastEditTime: 2021-06-25 08:48:07 * @LastEditTime: 2021-07-04 12:59:13
* @LastEditors: 卜启缘 * @LastEditors: 卜启缘
* @Description: * @Description:
* @FilePath: \vite-vue3-lowcode\preview\views\slot-item.vue * @FilePath: \vite-vue3-lowcode\preview\views\slot-item.vue
--> -->
<template> <template>
<div class="__slot-item"> <div class="__slot-item">
<comp-render :element="element" :config="config"> <comp-render :element="element" :config="config" v-on="events">
<template v-for="(value, key) in element.props?.slots" :key="key" #[key]> <template v-for="(value, key) in element.props?.slots" :key="key" #[key]>
<template v-for="item in value?.children" :key="item._vid"> <template v-for="item in value?.children" :key="item._vid">
<slot-item :element="item" :config="config" /> <slot-item :element="item" :config="config" :models="models" :actions="actions" />
</template> </template>
</template> </template>
</comp-render> </comp-render>
...@@ -22,7 +22,14 @@ ...@@ -22,7 +22,14 @@
import { defineComponent, onMounted, PropType } from 'vue' import { defineComponent, onMounted, PropType } from 'vue'
import CompRender from './comp-render' import CompRender from './comp-render'
import { useAnimate } from '@/hooks/useAnimate' import { useAnimate } from '@/hooks/useAnimate'
import type { VisualEditorBlockData } from '@/visual-editor/visual-editor.utils' import type {
VisualEditorBlockData,
VisualEditorActions,
VisualEditorModel,
FetchApiItem
} from '@/visual-editor/visual-editor.utils'
import request from '../utils/http/request'
import { ContentTypeEnum } from '../utils/http/httpEnum'
export default defineComponent({ export default defineComponent({
name: 'SlotItem', name: 'SlotItem',
...@@ -32,12 +39,45 @@ export default defineComponent({ ...@@ -32,12 +39,45 @@ export default defineComponent({
type: [Object] as PropType<VisualEditorBlockData>, type: [Object] as PropType<VisualEditorBlockData>,
default: () => ({}) default: () => ({})
}, },
actions: {
type: Object as PropType<VisualEditorActions>,
default: () => ({})
},
models: {
type: Object as PropType<VisualEditorModel[]>,
default: () => ({})
},
config: { config: {
type: Object, type: Object,
default: () => ({}) default: () => ({})
} }
}, },
setup(props) { setup(props) {
// 生成组件事件
const events = props.element.actions.reduce((prev, curr) => {
prev[curr.event] = async () => {
for (const handle of curr.handle) {
const [scopeType, actionType, handleKey] = handle.link
if (scopeType == 'global') {
const apis: FetchApiItem[] = props.actions[actionType].apis
const { data, options } = apis.find((item) => item.key == handleKey)!
await request({
...options,
headers: {
'Content-Type': ContentTypeEnum[options.contentType]
},
data: {
username: 'admin',
password: '123456'
}
})
} else if (scopeType == 'component') {
}
}
}
return prev
}, {})
onMounted(() => { onMounted(() => {
const animations = props.element.animations const animations = props.element.animations
if (animations?.length) { if (animations?.length) {
...@@ -53,7 +93,9 @@ export default defineComponent({ ...@@ -53,7 +93,9 @@ export default defineComponent({
} }
}) })
return {} return {
events
}
} }
}) })
</script> </script>
......
...@@ -30,6 +30,10 @@ export default { ...@@ -30,6 +30,10 @@ export default {
height: true, height: true,
width: true width: true
}, },
events: [
{ label: '点击按钮,且按钮状态不为加载或禁用时触发', value: 'click' },
{ label: '开始触摸按钮时触发', value: 'touchstart' }
],
props: { props: {
text: createEditorInputProp({ label: '按钮文字', defaultValue: '按钮' }), text: createEditorInputProp({ label: '按钮文字', defaultValue: '按钮' }),
type: createEditorSelectProp({ type: createEditorSelectProp({
......
/*
* @Author: 卜启缘
* @Date: 2021-06-01 09:45:21
* @LastEditTime: 2021-07-04 16:50:19
* @LastEditors: 卜启缘
* @Description: 表单项类型 - 复选框
* @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\checkbox\index.tsx
*/
import { reactive } from 'vue'
import { Field, Checkbox, CheckboxGroup } from 'vant' import { Field, Checkbox, CheckboxGroup } from 'vant'
import type { VisualEditorComponent } from '@/visual-editor/visual-editor.utils' import type { VisualEditorComponent } from '@/visual-editor/visual-editor.utils'
import { createFieldProps } from './createFieldProps' import { createFieldProps } from './createFieldProps'
...@@ -5,7 +14,8 @@ import { useGlobalProperties } from '@/hooks/useGlobalProperties' ...@@ -5,7 +14,8 @@ import { useGlobalProperties } from '@/hooks/useGlobalProperties'
import { import {
createEditorInputProp, createEditorInputProp,
createEditorSelectProp, createEditorSelectProp,
createEditorTableProp createEditorCrossSortableProp,
createEditorModelBindProp
} from '@/visual-editor/visual-editor.props' } from '@/visual-editor/visual-editor.props'
export default { export default {
...@@ -25,6 +35,11 @@ export default { ...@@ -25,6 +35,11 @@ export default {
render: ({ size, block, props }) => { render: ({ size, block, props }) => {
const { registerRef } = useGlobalProperties() const { registerRef } = useGlobalProperties()
const state = reactive({
checkList:
typeof props.modelValue === 'string' ? props.modelValue.split(',') : props.modelValue
})
return ( return (
<Field <Field
{...props} {...props}
...@@ -32,12 +47,13 @@ export default { ...@@ -32,12 +47,13 @@ export default {
style={{ style={{
width: size.width ? `${size.width}px` : null width: size.width ? `${size.width}px` : null
}} }}
name={Array.isArray(props.name) ? [...props.name].pop() : props.name}
v-slots={{ v-slots={{
input: () => ( input: () => (
<CheckboxGroup <CheckboxGroup
ref={(el) => registerRef(el, block._vid)} ref={(el) => registerRef(el, block._vid)}
{...props} {...props}
v-model={props.modelValue} v-model={state.checkList}
> >
{props.options?.map((item) => ( {props.options?.map((item) => (
<Checkbox name={item.value} style={{ marginBottom: '5px' }} shape="square"> <Checkbox name={item.value} style={{ marginBottom: '5px' }} shape="square">
...@@ -51,30 +67,20 @@ export default { ...@@ -51,30 +67,20 @@ export default {
) )
}, },
props: { props: {
modelValue: createEditorSelectProp({ modelValue: createEditorInputProp({
label: '默认值', label: '默认值',
options: [
{ label: '萝卜', value: 'radish' },
{ label: '青菜', value: 'greens' }
],
multiple: true,
defaultValue: [] defaultValue: []
}), }),
name: createEditorInputProp({ label: '字段', defaultValue: 'checkbox' }), name: createEditorModelBindProp({ label: '字段绑定', defaultValue: '' }),
label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '复选框' }), label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '复选框' }),
options: createEditorTableProp({ options: createEditorCrossSortableProp({
label: '默认选项', label: '默认选项',
option: { labelPosition: 'top',
options: [ multiple: true,
{ label: '显示值', field: 'label' },
{ label: '绑定值', field: 'value' },
{ label: '备注', field: 'comments' }
],
showKey: 'label'
},
defaultValue: [ defaultValue: [
{ label: '萝卜', value: 'radish' }, { label: '胡萝卜', value: 'carrot' },
{ label: '青菜', value: 'greens' } { label: '白菜', value: 'cabbage' },
{ label: '', value: 'pig' }
] ]
}), }),
direction: createEditorSelectProp({ direction: createEditorSelectProp({
...@@ -93,6 +99,10 @@ export default { ...@@ -93,6 +99,10 @@ export default {
}), }),
...createFieldProps() ...createFieldProps()
}, },
events: [
{ label: '当绑定值变化时触发的事件', value: 'change' },
{ label: '点击复选框时触发', value: 'click' }
],
resize: { resize: {
width: true width: true
}, },
......
...@@ -5,6 +5,7 @@ import { useGlobalProperties } from '@/hooks/useGlobalProperties' ...@@ -5,6 +5,7 @@ import { useGlobalProperties } from '@/hooks/useGlobalProperties'
import { import {
createEditorInputNumberProp, createEditorInputNumberProp,
createEditorInputProp, createEditorInputProp,
createEditorModelBindProp,
createEditorSelectProp, createEditorSelectProp,
createEditorSwitchProp createEditorSwitchProp
} from '@/visual-editor/visual-editor.props' } from '@/visual-editor/visual-editor.props'
...@@ -52,6 +53,7 @@ export default { ...@@ -52,6 +53,7 @@ export default {
style={{ style={{
width: size.width ? `${size.width}px` : null width: size.width ? `${size.width}px` : null
}} }}
name={Array.isArray(props.name) ? [...props.name].pop() : props.name}
v-slots={{ v-slots={{
input: () => input: () =>
state.text?.trim() == '' ? ( state.text?.trim() == '' ? (
...@@ -77,10 +79,7 @@ export default { ...@@ -77,10 +79,7 @@ export default {
}, },
props: { props: {
modelValue: createEditorInputProp({ label: '默认值' }), modelValue: createEditorInputProp({ label: '默认值' }),
name: createEditorInputProp({ name: createEditorModelBindProp({ label: '字段绑定', defaultValue: '' }),
label: '字段名',
defaultValue: 'datetimePicker'
}),
label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '时间选择器' }), label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '时间选择器' }),
title: createEditorInputProp({ label: '顶部栏标题', defaultValue: '选择时间' }), title: createEditorInputProp({ label: '顶部栏标题', defaultValue: '选择时间' }),
type: createEditorSelectProp({ type: createEditorSelectProp({
...@@ -133,6 +132,11 @@ export default { ...@@ -133,6 +132,11 @@ export default {
placeholder: createEditorInputProp({ label: '占位符', defaultValue: '请选择' }), placeholder: createEditorInputProp({ label: '占位符', defaultValue: '请选择' }),
...createFieldProps() ...createFieldProps()
}, },
events: [
{ label: '当值变化时触发的事件', value: 'change' },
{ label: '点击完成按钮时触发的事件', value: 'confirm' },
{ label: '点击取消按钮时触发的事件', value: 'cancel' }
],
resize: { resize: {
width: true width: true
}, },
......
/* /*
* @Author: 卜启缘 * @Author: 卜启缘
* @Date: 2021-06-01 09:45:21 * @Date: 2021-06-01 09:45:21
* @LastEditTime: 2021-06-25 08:53:12 * @LastEditTime: 2021-07-04 16:53:22
* @LastEditors: 卜启缘 * @LastEditors: 卜启缘
* @Description: 图片组件 * @Description: 图片组件
* @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\image\index.tsx * @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\image\index.tsx
...@@ -84,5 +84,10 @@ export default { ...@@ -84,5 +84,10 @@ export default {
'show-error': createEditorSwitchProp({ label: '是否展示图片加载失败提示' }), 'show-error': createEditorSwitchProp({ label: '是否展示图片加载失败提示' }),
'show-loading': createEditorSwitchProp({ label: '是否展示图片加载中提示' }), 'show-loading': createEditorSwitchProp({ label: '是否展示图片加载中提示' }),
alt: createEditorInputProp({ label: '替代文本' }) alt: createEditorInputProp({ label: '替代文本' })
} },
events: [
{ label: '点击图片时触发', value: 'click' },
{ label: '图片加载完毕时触发', value: 'load' },
{ label: '图片加载失败时触发', value: 'error' }
]
} as VisualEditorComponent } as VisualEditorComponent
import { import {
createEditorInputProp, createEditorInputProp,
createEditorSelectProp, createEditorSelectProp,
createEditorSwitchProp createEditorSwitchProp,
createEditorModelBindProp
} from '@/visual-editor/visual-editor.props' } from '@/visual-editor/visual-editor.props'
/** /**
...@@ -16,7 +17,7 @@ export const createFieldProps = () => ({ ...@@ -16,7 +17,7 @@ export const createFieldProps = () => ({
label: '默认值', label: '默认值',
defaultValue: '' defaultValue: ''
}), }),
name: createEditorInputProp({ label: '字段', defaultValue: 'input' }), name: createEditorModelBindProp({ label: '字段绑定', defaultValue: '' }),
label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '输入框' }), label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '输入框' }),
type: createEditorSelectProp({ type: createEditorSelectProp({
label: '输入框类型', label: '输入框类型',
...@@ -132,7 +133,7 @@ export const createFieldProps = () => ({ ...@@ -132,7 +133,7 @@ export const createFieldProps = () => ({
defaultValue: 'left' defaultValue: 'left'
}), }),
'label-width': createEditorInputProp({ label: '左侧文本宽度' }), 'label-width': createEditorInputProp({ label: '左侧文本宽度' }),
maxlength: createEditorInputProp({ label: '输入的最大字符数' }), maxlength: createEditorInputProp({ label: '输入的最大字符数', defaultValue: 500 }),
'show-word-limit': createEditorSwitchProp({ 'show-word-limit': createEditorSwitchProp({
label: '是否显示字数统计', label: '是否显示字数统计',
tips: '需要设置 maxlength 属性' tips: '需要设置 maxlength 属性'
......
/* /*
* @Author: 卜启缘 * @Author: 卜启缘
* @Date: 2021-05-04 05:36:58 * @Date: 2021-05-04 05:36:58
* @LastEditTime: 2021-06-25 08:49:50 * @LastEditTime: 2021-07-03 09:45:56
* @LastEditors: 卜启缘 * @LastEditors: 卜启缘
* @Description: 表单项类型 - 输入框 * @Description: 表单项类型 - 输入框
* @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\input\index.tsx * @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\input\index.tsx
...@@ -33,6 +33,7 @@ export default { ...@@ -33,6 +33,7 @@ export default {
{...props} {...props}
{...model.default} {...model.default}
v-model={props.modelValue} v-model={props.modelValue}
name={Array.isArray(props.name) ? [...props.name].pop() : props.name}
rules={rules} rules={rules}
style={{ style={{
width: size.width ? `${size.width}px` : null width: size.width ? `${size.width}px` : null
...@@ -40,6 +41,16 @@ export default { ...@@ -40,6 +41,16 @@ export default {
/> />
) )
}, },
events: [
{ label: '输入框内容变化时触发', value: 'update:model-value' },
{ label: '输入框获得焦点时触发', value: 'focus' },
{ label: '输入框失去焦点时触发', value: 'blur' },
{ label: '点击清除按钮时触发', value: 'clear' },
{ label: '点击组件时触发', value: 'click' },
{ label: '点击输入区域时触发', value: 'click-input' },
{ label: '点击左侧图标时触发', value: 'click-left-icon' },
{ label: '点击右侧图标时触发', value: 'click-right-icon' }
],
props: createFieldProps(), props: createFieldProps(),
resize: { resize: {
width: true width: true
......
/* /*
* @Author: 卜启缘 * @Author: 卜启缘
* @Date: 2021-05-04 05:36:58 * @Date: 2021-05-04 05:36:58
* @LastEditTime: 2021-06-25 08:49:41 * @LastEditTime: 2021-07-04 16:54:00
* @LastEditors: 卜启缘 * @LastEditors: 卜启缘
* @Description: 导航栏 * @Description: 导航栏
* @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\nav-bar\index.tsx * @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\nav-bar\index.tsx
...@@ -48,6 +48,10 @@ export default { ...@@ -48,6 +48,10 @@ export default {
rightText: createEditorInputProp({ label: '右侧文案', defaultValue: '按钮' }), rightText: createEditorInputProp({ label: '右侧文案', defaultValue: '按钮' }),
leftArrow: createEditorSwitchProp({ label: '是否显示左侧箭头', defaultValue: true }) leftArrow: createEditorSwitchProp({ label: '是否显示左侧箭头', defaultValue: true })
}, },
events: [
{ label: '点击左侧按钮时触发', value: 'click-left' },
{ label: '点击右侧按钮时触发', value: 'click-right' }
],
resize: { resize: {
width: true width: true
} }
......
/* /*
* @Author: 卜启缘 * @Author: 卜启缘
* @Date: 2021-06-14 12:24:12 * @Date: 2021-06-14 12:24:12
* @LastEditTime: 2021-06-25 08:53:22 * @LastEditTime: 2021-07-04 16:54:32
* @LastEditors: 卜启缘 * @LastEditors: 卜启缘
* @Description: * @Description:
* @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\notice-bar\index.tsx * @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\notice-bar\index.tsx
...@@ -27,6 +27,11 @@ export default { ...@@ -27,6 +27,11 @@ export default {
return <NoticeBar ref={(el) => registerRef(el, block._vid)} {...props} /> return <NoticeBar ref={(el) => registerRef(el, block._vid)} {...props} />
}, },
events: [
{ label: '点击通知栏时触发', value: 'click' },
{ label: '关闭通知栏时触发', value: 'close' },
{ label: '每当滚动栏重新开始滚动时触发', value: 'replay' }
],
props: createFieldProps(), props: createFieldProps(),
resize: { resize: {
width: true width: true
......
/*
* @Author: 卜启缘
* @Date: 2021-06-01 09:45:21
* @LastEditTime: 2021-07-04 16:58:50
* @LastEditors: 卜启缘
* @Description: 表单项类型 - 选择器
* @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\picker\index.tsx
*/
import { Field, Popup, Picker } from 'vant' import { Field, Popup, Picker } from 'vant'
import type { VisualEditorComponent } from '@/visual-editor/visual-editor.utils' import type { VisualEditorComponent } from '@/visual-editor/visual-editor.utils'
import { createFieldProps } from './createFieldProps' import { createFieldProps } from './createFieldProps'
import { useGlobalProperties } from '@/hooks/useGlobalProperties' import { useGlobalProperties } from '@/hooks/useGlobalProperties'
import { createEditorInputProp, createEditorTableProp } from '@/visual-editor/visual-editor.props' import {
createEditorCrossSortableProp,
createEditorInputProp,
createEditorModelBindProp
} from '@/visual-editor/visual-editor.props'
import { reactive } from 'vue' import { reactive } from 'vue'
export default { export default {
...@@ -14,13 +26,19 @@ export default { ...@@ -14,13 +26,19 @@ export default {
const { registerRef } = useGlobalProperties() const { registerRef } = useGlobalProperties()
const state = reactive({ const state = reactive({
showPicker: false, showPicker: false,
text: '' text: '',
defaultIndex: 0
}) })
const customFieldName = { const customFieldName = {
text: 'label', text: 'label',
value: 'value' value: 'value'
} }
if (props.modelValue) {
state.defaultIndex = props.columns?.findIndex((item) => item.value == props.modelValue)
state.text = props.columns[state.defaultIndex]?.label
}
const onConfirm = (value) => { const onConfirm = (value) => {
props.modelValue = value.value props.modelValue = value.value
state.text = value[props.valueKey || 'text'] state.text = value[props.valueKey || 'text']
...@@ -39,6 +57,7 @@ export default { ...@@ -39,6 +57,7 @@ export default {
style={{ style={{
width: size.width ? `${size.width}px` : null width: size.width ? `${size.width}px` : null
}} }}
name={Array.isArray(props.name) ? [...props.name].pop() : props.name}
> >
{{ {{
input: () => input: () =>
...@@ -53,6 +72,7 @@ export default { ...@@ -53,6 +72,7 @@ export default {
<Picker <Picker
ref={(el) => registerRef(el, block._vid)} ref={(el) => registerRef(el, block._vid)}
{...props} {...props}
defaultIndex={state.defaultIndex}
columnsFieldNames={customFieldName} columnsFieldNames={customFieldName}
onConfirm={onConfirm} onConfirm={onConfirm}
onCancel={() => (state.showPicker = false)} onCancel={() => (state.showPicker = false)}
...@@ -65,42 +85,26 @@ export default { ...@@ -65,42 +85,26 @@ export default {
}, },
props: { props: {
modelValue: createEditorInputProp({ label: '默认值' }), modelValue: createEditorInputProp({ label: '默认值' }),
name: createEditorInputProp({ label: '字段', defaultValue: 'picker' }), name: createEditorModelBindProp({ label: '字段绑定', defaultValue: '' }),
label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '选择器' }), label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '选择器' }),
columns: createEditorTableProp({ columns: createEditorCrossSortableProp({
label: '数据项', label: '默认选项',
option: { labelPosition: 'top',
options: [ multiple: false,
{
label: '显示值',
field: 'label'
},
{
label: '绑定值',
field: 'value'
},
{
label: '备注',
field: 'comments'
}
],
showKey: 'label'
},
defaultValue: [ defaultValue: [
{ { label: '杭州', value: 'hangzhou' },
label: '杭州', { label: '上海', value: 'shanghai' }
value: 'hangzhou'
},
{
label: '上海',
value: 'shanghai'
}
] ]
}), }),
valueKey: createEditorInputProp({ label: '选项对象的键名', defaultValue: 'label' }), valueKey: createEditorInputProp({ label: '选项对象的键名', defaultValue: 'label' }),
placeholder: createEditorInputProp({ label: '占位符', defaultValue: '请选择' }), placeholder: createEditorInputProp({ label: '占位符', defaultValue: '请选择' }),
...createFieldProps() ...createFieldProps()
}, },
events: [
{ label: '点击完成按钮时触发', value: 'confirm' },
{ label: '点击取消按钮时触发', value: 'cancel' },
{ label: '选项改变时触发', value: 'change' }
],
resize: { resize: {
width: true width: true
}, },
......
/* /*
* @Author: 卜启缘 * @Author: 卜启缘
* @Date: 2021-06-12 22:18:48 * @Date: 2021-06-12 22:18:48
* @LastEditTime: 2021-06-25 08:50:11 * @LastEditTime: 2021-07-04 17:00:12
* @LastEditors: 卜启缘 * @LastEditors: 卜启缘
* @Description: 进度条 * @Description: 进度条
* @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\process\index.tsx * @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\process\index.tsx
......
/*
* @Author: 卜启缘
* @Date: 2021-06-01 09:45:21
* @LastEditTime: 2021-07-04 17:00:24
* @LastEditors: 卜启缘
* @Description: 表单项类型 - 单选框
* @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\radio\index.tsx
*/
import { Field, Radio, RadioGroup } from 'vant' import { Field, Radio, RadioGroup } from 'vant'
import type { VisualEditorComponent } from '@/visual-editor/visual-editor.utils' import type { VisualEditorComponent } from '@/visual-editor/visual-editor.utils'
import { createFieldProps } from './createFieldProps' import { createFieldProps } from './createFieldProps'
import { useGlobalProperties } from '@/hooks/useGlobalProperties' import { useGlobalProperties } from '@/hooks/useGlobalProperties'
import { import {
createEditorCrossSortableProp,
createEditorInputProp, createEditorInputProp,
createEditorSelectProp, createEditorModelBindProp,
createEditorTableProp createEditorSelectProp
} from '@/visual-editor/visual-editor.props' } from '@/visual-editor/visual-editor.props'
export default { export default {
...@@ -28,6 +37,7 @@ export default { ...@@ -28,6 +37,7 @@ export default {
style={{ style={{
width: size.width ? `${size.width}px` : null width: size.width ? `${size.width}px` : null
}} }}
name={Array.isArray(props.name) ? [...props.name].pop() : props.name}
v-slots={{ v-slots={{
input: () => ( input: () => (
<RadioGroup <RadioGroup
...@@ -48,21 +58,16 @@ export default { ...@@ -48,21 +58,16 @@ export default {
}, },
props: { props: {
modelValue: createEditorInputProp({ label: '默认值', defaultValue: '' }), modelValue: createEditorInputProp({ label: '默认值', defaultValue: '' }),
name: createEditorInputProp({ label: '字段', defaultValue: 'radio' }), name: createEditorModelBindProp({ label: '字段绑定', defaultValue: '' }),
label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '单选框' }), label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '单选框' }),
options: createEditorTableProp({ options: createEditorCrossSortableProp({
label: '默认选项', label: '默认选项',
option: { labelPosition: 'top',
options: [ multiple: false,
{ label: '显示值', field: 'label' },
{ label: '绑定值', field: 'value' },
{ label: '备注', field: 'comments' }
],
showKey: 'label'
},
defaultValue: [ defaultValue: [
{ label: '萝卜', value: 'radish' }, { label: '胡萝卜', value: 'carrot' },
{ label: '青菜', value: 'greens' } { label: '白菜', value: 'cabbage' },
{ label: '', value: 'pig' }
] ]
}), }),
direction: createEditorSelectProp({ direction: createEditorSelectProp({
...@@ -81,6 +86,7 @@ export default { ...@@ -81,6 +86,7 @@ export default {
}), }),
...createFieldProps() ...createFieldProps()
}, },
events: [{ label: '点击单选框时触发', value: 'click' }],
resize: { resize: {
width: true width: true
}, },
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment