feat: 添加组件事件

This commit is contained in:
bqy_fe 2021-07-04 17:04:10 +08:00
parent 249179ce44
commit f5339844c3
45 changed files with 1164 additions and 412 deletions

View File

@ -1,5 +1,8 @@
# 只在开发模式中被载入
# 网站标题
VITE_APP_TITLE = H5低代码
# 网站前缀
VITE_BASE_URL = /

View File

@ -1,5 +1,8 @@
# 只在生产模式中被载入
# 网站标题
VITE_APP_TITLE = H5低代码
# 网站前缀
VITE_BASE_URL = /vite-vue3-lowcode/

View File

@ -49,20 +49,22 @@ let propObj = {
boolean: (config) => `createEditorSwitchProp(${JSON.stringify(config)})`
}
$$('#props + table tr').reduce((prev, curr) => {
const children = curr.children
const key = children[0].textContent.replace(/-([a-z])/g, (all, i) => i.toUpperCase())
const child3Text = children[3].textContent
const defaultValue = ['true', 'false'].includes(child3Text)
? child3Text
: `'${child3Text == '-' ? '' : child3Text}'`
const value = (propObj[children[2].textContent] ?? propObj['string'])({
label: `'${children[1].textContent}'`,
defaultValue
}).replaceAll('"', '')
prev[key] = value
return prev
}, {})
JSON.stringify(
$$('#props + table tbody tr').reduce((prev, curr) => {
const children = curr.children
const key = children[0].textContent.replace(/-([a-z])/g, (all, i) => i.toUpperCase())
const child3Text = children[3].textContent
const defaultValue = ['true', 'false'].includes(child3Text)
? child3Text
: `'${child3Text == '-' ? '' : child3Text}'`
const value = (propObj[children[2].textContent] ?? propObj['string'])({
label: `'${children[1].textContent}'`,
defaultValue
}).replaceAll('"', '')
prev[key] = value
return prev
}, {})
).replaceAll('"', '')
```
## Browser support

View File

@ -56,20 +56,38 @@ let propObj = {
boolean: (config) => `createEditorSwitchProp(${JSON.stringify(config)})`
}
$$('#props + table tr').reduce((prev, curr) => {
const children = curr.children
const key = children[0].textContent.replace(/-([a-z])/g, (all, i) => i.toUpperCase())
const child3Text = children[3].textContent
const defaultValue = ['true', 'false'].includes(child3Text)
? child3Text
: `'${child3Text == '-' ? '' : child3Text}'`
const value = (propObj[children[2].textContent] ?? propObj['string'])({
label: `'${children[1].textContent}'`,
defaultValue
}).replaceAll('"', '')
prev[key] = value
return prev
}, {})
JSON.stringify(
$$('#props + table tbody tr').reduce((prev, curr) => {
const children = curr.children
const key = children[0].textContent.replace(/-([a-z])/g, (all, i) => i.toUpperCase())
const child3Text = children[3].textContent
const defaultValue = ['true', 'false'].includes(child3Text)
? child3Text
: `'${child3Text == '-' ? '' : child3Text}'`
const value = (propObj[children[2].textContent] ?? propObj['string'])({
label: `'${children[1].textContent}'`,
defaultValue
}).replaceAll('"', '')
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, "'")
```
## 浏览器支持

33
components.d.ts vendored
View File

@ -3,30 +3,29 @@
declare module 'vue' {
export interface GlobalComponents {
ElHeader: typeof import('element-plus/es/el-header')['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']
ElTooltip: typeof import('element-plus/es/el-tooltip')['default']
ElRow: typeof import('element-plus/es/el-row')['default']
ElPopover: typeof import('element-plus/es/el-popover')['default']
ElTabPane: typeof import('element-plus/es/el-tab-pane')['default']
ElTabs: typeof import('element-plus/es/el-tabs')['default']
ElCol: typeof import('element-plus/es/el-col')['default']
ElCollapse: typeof import('element-plus/es/el-collapse')['default']
ElCollapseItem: typeof import('element-plus/es/el-collapse-item')['default']
ElContainer: typeof import('element-plus/es/el-container')['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']
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']
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']
ElCollapseItem: typeof import('element-plus/es/el-collapse-item')['default']
ElCollapse: typeof import('element-plus/es/el-collapse')['default']
ElInfiniteScroll: typeof import('element-plus/es/el-infinite-scroll')['default']
ElPopover: typeof import('element-plus/es/el-popover')['default']
ElRow: typeof import('element-plus/es/el-row')['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']
}
}

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
<title>H5低代码</title>
</head>
<body>
<div id="app"></div>

View File

@ -27,15 +27,15 @@
"axios": "^0.21.1",
"dayjs": "^1.10.5",
"dexie": "^3.0.3",
"element-plus": "1.0.2-beta.52",
"element-plus": "1.0.2-beta.54",
"lodash": "^4.17.21",
"monaco-editor": "^0.25.2",
"normalize.css": "^8.0.1",
"nprogress": "^1.0.0-1",
"qrcode": "^1.4.4",
"qs": "^6.10.1",
"vant": "^3.1.0",
"vue": "3.1.2",
"vant": "^3.1.2",
"vue": "3.1.4",
"vue-router": "^4.0.10",
"vuedraggable": "^4.0.3",
"vuex": "^4.0.2"
@ -43,24 +43,24 @@
"devDependencies": {
"@commitlint/cli": "^12.1.4",
"@commitlint/config-conventional": "^12.1.4",
"@types/node": "^15.12.4",
"@typescript-eslint/eslint-plugin": "^4.28.0",
"@typescript-eslint/parser": "^4.28.0",
"@vitejs/plugin-legacy": "^1.4.2",
"@vitejs/plugin-vue": "^1.2.3",
"@vitejs/plugin-vue-jsx": "^1.1.5",
"@vue/compiler-sfc": "3.1.2",
"@types/node": "^16.0.0",
"@typescript-eslint/eslint-plugin": "^4.28.1",
"@typescript-eslint/parser": "^4.28.1",
"@vitejs/plugin-legacy": "^1.4.3",
"@vitejs/plugin-vue": "^1.2.4",
"@vitejs/plugin-vue-jsx": "^1.1.6",
"@vue/compiler-sfc": "3.1.4",
"commitizen": "^4.2.4",
"cross-env": "^7.0.3",
"cz-conventional-changelog": "^3.3.0",
"cz-customizable": "^6.3.0",
"eslint": "^7.29.0",
"eslint": "^7.30.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-vue": "^7.12.1",
"gh-pages": "^3.2.3",
"husky": "^6.0.0",
"husky": "^7.0.0",
"lint-staged": "^11.0.0",
"prettier": "^2.3.2",
"pretty-quick": "^3.1.1",
@ -69,14 +69,14 @@
"stylelint-config-prettier": "^8.0.2",
"stylelint-config-standard": "^22.0.0",
"stylelint-order": "^4.1.0",
"typescript": "^4.3.4",
"typescript": "^4.3.5",
"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-windicss": "^1.1.1",
"vue-eslint-parser": "^7.6.0",
"vite-plugin-windicss": "^1.2.0",
"vue-eslint-parser": "^7.7.2",
"vue-tsc": "^0.2.0",
"windicss": "^3.1.3"
"windicss": "^3.1.4"
},
"repository": {
"type": "git",

View File

@ -1,14 +1,14 @@
<!--
* @Author: 卜启缘
* @Date: 2021-06-01 09:45:21
* @LastEditTime: 2021-06-25 08:47:36
* @LastEditTime: 2021-07-04 08:59:57
* @LastEditors: 卜启缘
* @Description:
* @FilePath: \vite-vue3-lowcode\preview\views\preview.vue
-->
<template>
<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>
@ -69,6 +69,8 @@ export default defineComponent({
return {
...toRefs(state),
actions: jsonData.actions,
models: jsonData.models,
visualConfig
}
}

View File

@ -1,17 +1,17 @@
<!--
* @Author: 卜启缘
* @Date: 2021-06-12 22:18:48
* @LastEditTime: 2021-06-25 08:48:07
* @LastEditTime: 2021-07-04 12:59:13
* @LastEditors: 卜启缘
* @Description:
* @FilePath: \vite-vue3-lowcode\preview\views\slot-item.vue
-->
<template>
<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="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>
</comp-render>
@ -22,7 +22,14 @@
import { defineComponent, onMounted, PropType } from 'vue'
import CompRender from './comp-render'
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({
name: 'SlotItem',
@ -32,12 +39,45 @@ export default defineComponent({
type: [Object] as PropType<VisualEditorBlockData>,
default: () => ({})
},
actions: {
type: Object as PropType<VisualEditorActions>,
default: () => ({})
},
models: {
type: Object as PropType<VisualEditorModel[]>,
default: () => ({})
},
config: {
type: Object,
default: () => ({})
}
},
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(() => {
const animations = props.element.animations
if (animations?.length) {
@ -53,7 +93,9 @@ export default defineComponent({
}
})
return {}
return {
events
}
}
})
</script>

View File

@ -30,6 +30,10 @@ export default {
height: true,
width: true
},
events: [
{ label: '点击按钮,且按钮状态不为加载或禁用时触发', value: 'click' },
{ label: '开始触摸按钮时触发', value: 'touchstart' }
],
props: {
text: createEditorInputProp({ label: '按钮文字', defaultValue: '按钮' }),
type: createEditorSelectProp({

View File

@ -1,3 +1,12 @@
/*
* @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 type { VisualEditorComponent } from '@/visual-editor/visual-editor.utils'
import { createFieldProps } from './createFieldProps'
@ -5,7 +14,8 @@ import { useGlobalProperties } from '@/hooks/useGlobalProperties'
import {
createEditorInputProp,
createEditorSelectProp,
createEditorTableProp
createEditorCrossSortableProp,
createEditorModelBindProp
} from '@/visual-editor/visual-editor.props'
export default {
@ -25,6 +35,11 @@ export default {
render: ({ size, block, props }) => {
const { registerRef } = useGlobalProperties()
const state = reactive({
checkList:
typeof props.modelValue === 'string' ? props.modelValue.split(',') : props.modelValue
})
return (
<Field
{...props}
@ -32,12 +47,13 @@ export default {
style={{
width: size.width ? `${size.width}px` : null
}}
name={Array.isArray(props.name) ? [...props.name].pop() : props.name}
v-slots={{
input: () => (
<CheckboxGroup
ref={(el) => registerRef(el, block._vid)}
{...props}
v-model={props.modelValue}
v-model={state.checkList}
>
{props.options?.map((item) => (
<Checkbox name={item.value} style={{ marginBottom: '5px' }} shape="square">
@ -51,30 +67,20 @@ export default {
)
},
props: {
modelValue: createEditorSelectProp({
modelValue: createEditorInputProp({
label: '默认值',
options: [
{ label: '萝卜', value: 'radish' },
{ label: '青菜', value: 'greens' }
],
multiple: true,
defaultValue: []
}),
name: createEditorInputProp({ label: '字段名', defaultValue: 'checkbox' }),
name: createEditorModelBindProp({ label: '字段绑定', defaultValue: '' }),
label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '复选框' }),
options: createEditorTableProp({
options: createEditorCrossSortableProp({
label: '默认选项',
option: {
options: [
{ label: '显示值', field: 'label' },
{ label: '绑定值', field: 'value' },
{ label: '备注', field: 'comments' }
],
showKey: 'label'
},
labelPosition: 'top',
multiple: true,
defaultValue: [
{ label: '萝卜', value: 'radish' },
{ label: '青菜', value: 'greens' }
{ label: '胡萝卜', value: 'carrot' },
{ label: '白菜', value: 'cabbage' },
{ label: '猪', value: 'pig' }
]
}),
direction: createEditorSelectProp({
@ -93,6 +99,10 @@ export default {
}),
...createFieldProps()
},
events: [
{ label: '当绑定值变化时触发的事件', value: 'change' },
{ label: '点击复选框时触发', value: 'click' }
],
resize: {
width: true
},

View File

@ -5,6 +5,7 @@ import { useGlobalProperties } from '@/hooks/useGlobalProperties'
import {
createEditorInputNumberProp,
createEditorInputProp,
createEditorModelBindProp,
createEditorSelectProp,
createEditorSwitchProp
} from '@/visual-editor/visual-editor.props'
@ -52,6 +53,7 @@ export default {
style={{
width: size.width ? `${size.width}px` : null
}}
name={Array.isArray(props.name) ? [...props.name].pop() : props.name}
v-slots={{
input: () =>
state.text?.trim() == '' ? (
@ -77,10 +79,7 @@ export default {
},
props: {
modelValue: createEditorInputProp({ label: '默认值' }),
name: createEditorInputProp({
label: '字段名',
defaultValue: 'datetimePicker'
}),
name: createEditorModelBindProp({ label: '字段绑定', defaultValue: '' }),
label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '时间选择器' }),
title: createEditorInputProp({ label: '顶部栏标题', defaultValue: '选择时间' }),
type: createEditorSelectProp({
@ -133,6 +132,11 @@ export default {
placeholder: createEditorInputProp({ label: '占位符', defaultValue: '请选择' }),
...createFieldProps()
},
events: [
{ label: '当值变化时触发的事件', value: 'change' },
{ label: '点击完成按钮时触发的事件', value: 'confirm' },
{ label: '点击取消按钮时触发的事件', value: 'cancel' }
],
resize: {
width: true
},

View File

@ -1,7 +1,7 @@
/*
* @Author:
* @Date: 2021-06-01 09:45:21
* @LastEditTime: 2021-06-25 08:53:12
* @LastEditTime: 2021-07-04 16:53:22
* @LastEditors:
* @Description:
* @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\image\index.tsx
@ -84,5 +84,10 @@ export default {
'show-error': createEditorSwitchProp({ label: '是否展示图片加载失败提示' }),
'show-loading': createEditorSwitchProp({ label: '是否展示图片加载中提示' }),
alt: createEditorInputProp({ label: '替代文本' })
}
},
events: [
{ label: '点击图片时触发', value: 'click' },
{ label: '图片加载完毕时触发', value: 'load' },
{ label: '图片加载失败时触发', value: 'error' }
]
} as VisualEditorComponent

View File

@ -1,7 +1,8 @@
import {
createEditorInputProp,
createEditorSelectProp,
createEditorSwitchProp
createEditorSwitchProp,
createEditorModelBindProp
} from '@/visual-editor/visual-editor.props'
/**
@ -16,7 +17,7 @@ export const createFieldProps = () => ({
label: '默认值',
defaultValue: ''
}),
name: createEditorInputProp({ label: '字段名', defaultValue: 'input' }),
name: createEditorModelBindProp({ label: '字段绑定', defaultValue: '' }),
label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '输入框' }),
type: createEditorSelectProp({
label: '输入框类型',
@ -132,7 +133,7 @@ export const createFieldProps = () => ({
defaultValue: 'left'
}),
'label-width': createEditorInputProp({ label: '左侧文本宽度' }),
maxlength: createEditorInputProp({ label: '输入的最大字符数' }),
maxlength: createEditorInputProp({ label: '输入的最大字符数', defaultValue: 500 }),
'show-word-limit': createEditorSwitchProp({
label: '是否显示字数统计',
tips: '需要设置 maxlength 属性'

View File

@ -1,7 +1,7 @@
/*
* @Author:
* @Date: 2021-05-04 05:36:58
* @LastEditTime: 2021-06-25 08:49:50
* @LastEditTime: 2021-07-03 09:45:56
* @LastEditors:
* @Description: -
* @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\input\index.tsx
@ -33,6 +33,7 @@ export default {
{...props}
{...model.default}
v-model={props.modelValue}
name={Array.isArray(props.name) ? [...props.name].pop() : props.name}
rules={rules}
style={{
width: size.width ? `${size.width}px` : null
@ -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(),
resize: {
width: true

View File

@ -1,7 +1,7 @@
/*
* @Author:
* @Date: 2021-05-04 05:36:58
* @LastEditTime: 2021-06-25 08:49:41
* @LastEditTime: 2021-07-04 16:54:00
* @LastEditors:
* @Description:
* @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\nav-bar\index.tsx
@ -48,6 +48,10 @@ export default {
rightText: createEditorInputProp({ label: '右侧文案', defaultValue: '按钮' }),
leftArrow: createEditorSwitchProp({ label: '是否显示左侧箭头', defaultValue: true })
},
events: [
{ label: '点击左侧按钮时触发', value: 'click-left' },
{ label: '点击右侧按钮时触发', value: 'click-right' }
],
resize: {
width: true
}

View File

@ -1,7 +1,7 @@
/*
* @Author:
* @Date: 2021-06-14 12:24:12
* @LastEditTime: 2021-06-25 08:53:22
* @LastEditTime: 2021-07-04 16:54:32
* @LastEditors:
* @Description:
* @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\notice-bar\index.tsx
@ -27,6 +27,11 @@ export default {
return <NoticeBar ref={(el) => registerRef(el, block._vid)} {...props} />
},
events: [
{ label: '点击通知栏时触发', value: 'click' },
{ label: '关闭通知栏时触发', value: 'close' },
{ label: '每当滚动栏重新开始滚动时触发', value: 'replay' }
],
props: createFieldProps(),
resize: {
width: true

View File

@ -1,8 +1,20 @@
/*
* @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 type { VisualEditorComponent } from '@/visual-editor/visual-editor.utils'
import { createFieldProps } from './createFieldProps'
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'
export default {
@ -14,13 +26,19 @@ export default {
const { registerRef } = useGlobalProperties()
const state = reactive({
showPicker: false,
text: ''
text: '',
defaultIndex: 0
})
const customFieldName = {
text: 'label',
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) => {
props.modelValue = value.value
state.text = value[props.valueKey || 'text']
@ -39,6 +57,7 @@ export default {
style={{
width: size.width ? `${size.width}px` : null
}}
name={Array.isArray(props.name) ? [...props.name].pop() : props.name}
>
{{
input: () =>
@ -53,6 +72,7 @@ export default {
<Picker
ref={(el) => registerRef(el, block._vid)}
{...props}
defaultIndex={state.defaultIndex}
columnsFieldNames={customFieldName}
onConfirm={onConfirm}
onCancel={() => (state.showPicker = false)}
@ -65,42 +85,26 @@ export default {
},
props: {
modelValue: createEditorInputProp({ label: '默认值' }),
name: createEditorInputProp({ label: '字段名', defaultValue: 'picker' }),
name: createEditorModelBindProp({ label: '字段绑定', defaultValue: '' }),
label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '选择器' }),
columns: createEditorTableProp({
label: '数据项',
option: {
options: [
{
label: '显示值',
field: 'label'
},
{
label: '绑定值',
field: 'value'
},
{
label: '备注',
field: 'comments'
}
],
showKey: 'label'
},
columns: createEditorCrossSortableProp({
label: '默认选项',
labelPosition: 'top',
multiple: false,
defaultValue: [
{
label: '杭州',
value: 'hangzhou'
},
{
label: '上海',
value: 'shanghai'
}
{ label: '杭州', value: 'hangzhou' },
{ label: '上海', value: 'shanghai' }
]
}),
valueKey: createEditorInputProp({ label: '选项对象的键名', defaultValue: 'label' }),
placeholder: createEditorInputProp({ label: '占位符', defaultValue: '请选择' }),
...createFieldProps()
},
events: [
{ label: '点击完成按钮时触发', value: 'confirm' },
{ label: '点击取消按钮时触发', value: 'cancel' },
{ label: '选项改变时触发', value: 'change' }
],
resize: {
width: true
},

View File

@ -1,7 +1,7 @@
/*
* @Author:
* @Date: 2021-06-12 22:18:48
* @LastEditTime: 2021-06-25 08:50:11
* @LastEditTime: 2021-07-04 17:00:12
* @LastEditors:
* @Description:
* @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\process\index.tsx

View File

@ -1,11 +1,20 @@
/*
* @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 type { VisualEditorComponent } from '@/visual-editor/visual-editor.utils'
import { createFieldProps } from './createFieldProps'
import { useGlobalProperties } from '@/hooks/useGlobalProperties'
import {
createEditorCrossSortableProp,
createEditorInputProp,
createEditorSelectProp,
createEditorTableProp
createEditorModelBindProp,
createEditorSelectProp
} from '@/visual-editor/visual-editor.props'
export default {
@ -28,6 +37,7 @@ export default {
style={{
width: size.width ? `${size.width}px` : null
}}
name={Array.isArray(props.name) ? [...props.name].pop() : props.name}
v-slots={{
input: () => (
<RadioGroup
@ -48,21 +58,16 @@ export default {
},
props: {
modelValue: createEditorInputProp({ label: '默认值', defaultValue: '' }),
name: createEditorInputProp({ label: '字段名', defaultValue: 'radio' }),
name: createEditorModelBindProp({ label: '字段绑定', defaultValue: '' }),
label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '单选框' }),
options: createEditorTableProp({
options: createEditorCrossSortableProp({
label: '默认选项',
option: {
options: [
{ label: '显示值', field: 'label' },
{ label: '绑定值', field: 'value' },
{ label: '备注', field: 'comments' }
],
showKey: 'label'
},
labelPosition: 'top',
multiple: false,
defaultValue: [
{ label: '萝卜', value: 'radish' },
{ label: '青菜', value: 'greens' }
{ label: '胡萝卜', value: 'carrot' },
{ label: '白菜', value: 'cabbage' },
{ label: '猪', value: 'pig' }
]
}),
direction: createEditorSelectProp({
@ -81,6 +86,7 @@ export default {
}),
...createFieldProps()
},
events: [{ label: '点击单选框时触发', value: 'click' }],
resize: {
width: true
},

View File

@ -1,7 +1,7 @@
/*
* @Author:
* @Date: 2021-06-01 09:45:21
* @LastEditTime: 2021-06-25 08:50:29
* @LastEditTime: 2021-07-03 09:38:17
* @LastEditors:
* @Description: -
* @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\rate\index.tsx
@ -13,6 +13,7 @@ import { useGlobalProperties } from '@/hooks/useGlobalProperties'
import {
createEditorInputNumberProp,
createEditorInputProp,
createEditorModelBindProp,
createEditorSwitchProp
} from '@/visual-editor/visual-editor.props'
@ -38,6 +39,7 @@ export default {
style={{
width: size.width ? `${size.width}px` : null
}}
name={Array.isArray(props.name) ? [...props.name].pop() : props.name}
v-slots={{
input: () => (
<Rate
@ -52,7 +54,7 @@ export default {
},
props: {
modelValue: createEditorInputNumberProp({ label: '默认值', defaultValue: 0 }),
name: createEditorInputProp({ label: '字段名', defaultValue: 'rate' }),
name: createEditorModelBindProp({ label: '字段绑定', defaultValue: '' }),
label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '评分' }),
count: createEditorInputNumberProp({ label: '图标总数' }),
size: createEditorInputProp({ label: '图标大小' }),

View File

@ -1,7 +1,7 @@
/*
* @Author:
* @Date: 2021-06-01 09:45:21
* @LastEditTime: 2021-06-25 08:50:47
* @LastEditTime: 2021-07-03 09:38:29
* @LastEditors:
* @Description: -
* @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\slider\index.tsx
@ -13,6 +13,7 @@ import { useGlobalProperties } from '@/hooks/useGlobalProperties'
import {
createEditorInputNumberProp,
createEditorInputProp,
createEditorModelBindProp,
createEditorSwitchProp
} from '@/visual-editor/visual-editor.props'
@ -38,6 +39,7 @@ export default {
style={{
width: size.width ? `${size.width}px` : null
}}
name={Array.isArray(props.name) ? [...props.name].pop() : props.name}
v-slots={{
input: () => (
<Slider
@ -52,7 +54,7 @@ export default {
},
props: {
modelValue: createEditorInputNumberProp({ label: '默认值', defaultValue: 0 }),
name: createEditorInputProp({ label: '字段名', defaultValue: 'slider' }),
name: createEditorModelBindProp({ label: '字段绑定', defaultValue: '' }),
label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '滑块' }),
min: createEditorInputNumberProp({ label: '最小值' }),
max: createEditorInputNumberProp({ label: '最大值' }),

View File

@ -1,7 +1,7 @@
/*
* @Author:
* @Date: 2021-06-01 09:45:21
* @LastEditTime: 2021-06-25 08:51:08
* @LastEditTime: 2021-07-03 09:38:50
* @LastEditors:
* @Description: ' -
* @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\stepper\index.tsx
@ -14,7 +14,8 @@ import {
createEditorInputNumberProp,
createEditorInputProp,
createEditorSwitchProp,
createEditorSelectProp
createEditorSelectProp,
createEditorModelBindProp
} from '@/visual-editor/visual-editor.props'
export default {
@ -39,6 +40,7 @@ export default {
style={{
width: size.width ? `${size.width}px` : null
}}
name={Array.isArray(props.name) ? [...props.name].pop() : props.name}
v-slots={{
input: () => (
<Stepper
@ -53,7 +55,7 @@ export default {
},
props: {
modelValue: createEditorInputNumberProp({ label: '默认值', defaultValue: 0 }),
name: createEditorInputProp({ label: '字段名', defaultValue: 'stepper' }),
name: createEditorModelBindProp({ label: '字段绑定', defaultValue: '' }),
label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '步进器' }),
min: createEditorInputNumberProp({ label: '最小值', defaultValue: 0 }),
max: createEditorInputNumberProp({ label: '最大值' }),

View File

@ -1,7 +1,7 @@
/*
* @Author:
* @Date: 2021-06-14 12:24:12
* @LastEditTime: 2021-06-21 23:06:36
* @LastEditTime: 2021-07-04 17:01:36
* @LastEditors:
* @Description:
* @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\swipe\index.tsx
@ -49,6 +49,7 @@ export default {
)
},
props: createFieldProps(),
events: [{ label: '每一页轮播结束后触发', value: 'change' }],
resize: {
width: true
},

View File

@ -1,7 +1,7 @@
/*
* @Author:
* @Date: 2021-06-01 09:45:21
* @LastEditTime: 2021-06-25 08:51:21
* @LastEditTime: 2021-07-04 17:02:06
* @LastEditors:
* @Description: -
* @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\switch\index.tsx
@ -13,7 +13,8 @@ import { useGlobalProperties } from '@/hooks/useGlobalProperties'
import {
createEditorInputProp,
createEditorSwitchProp,
createEditorColorProp
createEditorColorProp,
createEditorModelBindProp
} from '@/visual-editor/visual-editor.props'
export default {
@ -33,6 +34,7 @@ export default {
style={{
width: size.width ? `${size.width}px` : null
}}
name={Array.isArray(props.name) ? [...props.name].pop() : props.name}
v-slots={{
input: () => (
<Switch
@ -47,7 +49,7 @@ export default {
},
props: {
modelValue: createEditorInputProp({ label: '默认值', defaultValue: 'false' }),
name: createEditorInputProp({ label: '字段名', defaultValue: 'switch' }),
name: createEditorModelBindProp({ label: '字段绑定', defaultValue: '' }),
label: createEditorInputProp({ label: '输入框左侧文本', defaultValue: '开关' }),
activeColor: createEditorColorProp({ label: '打开时的背景色' }),
activeValue: createEditorInputProp({ label: '打开时对应的值', defaultValue: 'true' }),
@ -58,6 +60,10 @@ export default {
size: createEditorInputProp({ label: '开关尺寸', defaultValue: '20px' }),
...createFieldProps()
},
events: [
{ label: '开关状态切换时触发', value: 'change' },
{ label: '点击时触发', value: 'click' }
],
resize: {
width: true
},

View File

@ -1,9 +1,10 @@
/**
* @name: createProps
* @author:
* @date: 2021/5/30 10:50
* @descriptioncreateProps
* @update: 2021/5/30 10:50
/*
* @Author:
* @Date: 2021-06-01 09:45:21
* @LastEditTime: 2021-07-03 09:35:21
* @LastEditors:
* @Description:
* @FilePath: \vite-vue3-lowcode\src\packages\container-component\form\compProps.ts
*/
import {
@ -70,7 +71,22 @@ export const compProps = {
}),
submitOnEnter: createEditorSwitchProp({ label: '是否在按下回车键时提交表单' }),
validateFirst: createEditorSwitchProp({ label: '是否在某一项校验不通过时停止校验' }),
validateTrigger: createEditorInputProp({
label: '表单校验触发时机,可选值为 onChange、onSubmit详见下表'
validateTrigger: createEditorSelectProp({
label: '表单校验触发时机',
options: [
{
label: 'onChange',
value: 'onChange'
},
{
label: 'onSubmit',
value: 'onSubmit'
},
{
label: 'onBlur',
value: 'onBlur'
}
],
defaultValue: 'onBlur'
})
}

View File

@ -1,3 +1,11 @@
/*
* @Author:
* @Date: 2021-06-01 09:45:21
* @LastEditTime: 2021-06-27 18:01:21
* @LastEditors:
* @Description:
* @FilePath: \vite-vue3-lowcode\src\packages\container-component\form\index.tsx
*/
import { Form, Field, Button } from 'vant'
import { renderSlot, getCurrentInstance } from 'vue'
import type { VisualEditorComponent } from '@/visual-editor/visual-editor.utils'
@ -37,5 +45,9 @@ export default {
height: true,
width: true
},
events: [
{ label: '提交表单且验证通过后触发', value: 'submit' },
{ label: '提交表单且验证不通过后触发', value: 'failed' }
],
props: compProps
} as VisualEditorComponent

View File

@ -19,3 +19,12 @@ body {
img {
image-rendering: pixelated;
}
.el-dialog__body {
max-height: 66vh;
overflow: auto;
}
.h5-preview .el-dialog__body {
overflow: hidden;
}

View File

@ -1,43 +1,44 @@
.list-group {
}
.list-group-item {
position: relative;
display: flex;
width: calc(100% - 20px);
min-height: 120px;
padding: 0 5px;
margin-top: 20px;
margin-left: 10px;
border: solid 3px #ebeef5;
margin-top: 20px;
min-height: 120px;
display: flex;
box-sizing: border-box;
align-items: center;
justify-content: center;
padding: 0px 5px;
box-sizing: border-box;
&:hover {
border-color: #409EFF;
cursor: move;
border-color: #409eff;
}
&:last-of-type {
margin-bottom: 20px;
}
&::before {
content: attr(data-label);
position: absolute;
top: -3px;
left: -3px;
background-color: #409EFF;
color: white;
z-index: 1;
padding: 4px 8px;
font-size: 12px;
z-index: 1;
color: white;
background-color: #409eff;
content: attr(data-label);
}
&::after {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 2;
content: '';
}
}

View File

@ -1,7 +1,7 @@
<!--
* @Author: 卜启缘
* @Date: 2021-06-24 18:36:03
* @LastEditTime: 2021-06-27 14:59:24
* @LastEditTime: 2021-06-28 10:10:53
* @LastEditors: 卜启缘
* @Description: 接口请求
* @FilePath: \vite-vue3-lowcode\src\visual-editor\components\left-aside\components\data-source\data-fetch.vue
@ -149,7 +149,6 @@ const showModelMoal = () => {
label-width="100px"
size={'mini'}
rules={rules}
class="demo-ruleForm"
>
<ElFormItem label="名称" prop="name">
<ElInput v-model={state.ruleForm.name} placeholder={'请输入接口名称'}></ElInput>
@ -190,6 +189,22 @@ const showModelMoal = () => {
options={models.value}
></ElCascader>
</ElFormItem>
<ElFormItem label="响应数据" prop={'data.recv'}>
<ElCascader
clearable={true}
props={{
checkStrictly: true,
children: 'entitys',
label: 'name',
value: 'key',
expandTrigger: 'hover'
}}
placeholder="请选择绑定的响应数据"
onChange={handleBindChange}
v-model={state.ruleForm.data.recv}
options={models.value}
></ElCascader>
</ElFormItem>
</ElForm>
),
onConfirm: () => {

View File

@ -147,7 +147,6 @@ const showModelMoal = () => {
ref={(el) => el && (state.ruleFormRef = el)}
label-width="100px"
size={'mini'}
class="demo-ruleForm"
>
<ElFormItem
label="数据源名称"

View File

@ -1,7 +1,7 @@
/*
* @Author:
* @Date: 2021-06-27 13:15:19
* @LastEditTime: 2021-06-27 14:17:31
* @LastEditTime: 2021-06-27 15:22:51
* @LastEditors:
* @Description:
* @FilePath: \vite-vue3-lowcode\src\visual-editor\components\left-aside\components\data-source\utils.tsx
@ -84,7 +84,7 @@ export const useImportSwaggerJsonModal = () => {
return {
showImportSwaggerJsonModal: () =>
useModal({
title: '导入swagger JSON (导入swagger: 2.0)',
title: '导入swagger JSON (支持swagger: 2.0)',
props: {
width: 760
},

View File

@ -52,11 +52,11 @@
width="380px"
:title="operatePageData ? '编辑页面' : '新增页面'"
>
<el-form :model="form">
<el-form-item label="页面标题" label-width="80px">
<el-form ref="ruleForm" :model="form" :rules="rules">
<el-form-item prop="title" label="页面标题" label-width="80px">
<el-input v-model="form.title" autocomplete="off" />
</el-form-item>
<el-form-item label="页面路径" label-width="80px">
<el-form-item prop="path" label="页面路径" label-width="80px">
<el-input v-model="form.path" autocomplete="off" />
</el-form-item>
</el-form>
@ -75,6 +75,11 @@ import { useVisualData, createNewPage } from '@/visual-editor/hooks/useVisualDat
import { useRouter, useRoute } from 'vue-router'
import { ElMessage } from 'element-plus'
const rules = {
title: [{ required: true, message: '请输入页面标题', trigger: 'blur' }],
path: [{ required: true, message: '请输入页面路径', trigger: 'blur' }]
}
export default defineComponent({
name: 'PageTree',
setup() {
@ -84,6 +89,7 @@ export default defineComponent({
const { jsonData, setCurrentPage, deletePage, updatePage, incrementPage } = useVisualData()
const state = reactive({
ruleForm: null as any,
defaultProps: {
children: 'children',
label: 'title'
@ -141,24 +147,36 @@ export default defineComponent({
}
//
const onSubmit = async () => {
const { title, path } = state.form
if (title.trim() == '' || path.trim() == '') {
return ElMessage.error('标题或路径不能为空!')
}
if (state.operatePageData) {
updatePage({ newPath: path, oldPath: state.operatePageData.path || path, page: { title } })
await router.replace(path)
state.currentNodeKey = path
} else {
incrementPage(path, createNewPage({ title }))
}
state.dialogFormVisible = false
const onSubmit = () => {
state.ruleForm?.validate(async (valid) => {
if (valid) {
const { title, path } = state.form
if (title.trim() == '' || path.trim() == '') {
return ElMessage.error('标题或路径不能为空!')
}
if (state.operatePageData) {
updatePage({
newPath: path,
oldPath: state.operatePageData.path || path,
page: { title }
})
await router.replace(path)
state.currentNodeKey = path
} else {
incrementPage(path, createNewPage({ title }))
}
state.dialogFormVisible = false
} else {
console.log('error submit!!')
return false
}
})
}
return {
...toRefs(state),
pages,
rules,
setCurrentPage,
onSubmit,
setDefaultPage,

View File

@ -1,7 +1,7 @@
/*
* @Author:
* @Date: 2021-06-01 09:39:52
* @LastEditTime: 2021-06-24 18:50:16
* @LastEditTime: 2021-06-28 17:25:30
* @LastEditors:
* @Description:
* @FilePath: \vite-vue3-lowcode\src\visual-editor\components\left-aside\tabs.ts

View File

@ -1,12 +1,12 @@
/*
* @Author:
* @Date: 2021-06-10 16:23:06
* @LastEditTime: 2021-06-24 18:32:04
* @LastEditTime: 2021-07-02 22:02:53
* @LastEditors:
* @Description:
* @FilePath: \vite-vue3-lowcode\src\visual-editor\components\right-attribute-panel\components\attr-editor\AttrEditor.tsx
*/
import { defineComponent } from 'vue'
import { defineComponent, computed } from 'vue'
import {
ElColorPicker,
ElForm,
@ -16,16 +16,22 @@ import {
ElOption,
ElSelect,
ElSwitch,
ElPopover
ElPopover,
ElCascader
} from 'element-plus'
import { VisualEditorProps, VisualEditorPropsType } from '@/visual-editor/visual-editor.props'
import { TablePropEditor, CrossSortableOptionsEditor } from './components'
import { useDotProp } from '@/visual-editor/hooks/useDotProp'
import { useVisualData } from '@/visual-editor/hooks/useVisualData'
import { cloneDeep } from 'lodash'
export const AttrEditor = defineComponent({
setup() {
const { visualConfig, currentBlock } = useVisualData()
const { visualConfig, currentBlock, jsonData } = useVisualData()
/**
* @description
*/
const models = computed(() => cloneDeep(jsonData.models))
const renderEditor = (propName: string, propConfig: VisualEditorProps) => {
const { propObj, prop } = useDotProp(currentBlock.value.props, propName)
@ -33,14 +39,19 @@ export const AttrEditor = defineComponent({
propObj[prop] ??= propConfig.defaultValue
return {
[VisualEditorPropsType.input]: () => (
<ElInput v-model={propObj[prop]} placeholder={propConfig.tips || propConfig.label} />
),
[VisualEditorPropsType.input]: () => {
if (!Object.is(propObj[prop], undefined) && !Object.is(propObj[prop], null)) {
propObj[prop] = `${propObj[prop]}`
}
return (
<ElInput v-model={propObj[prop]} placeholder={propConfig.tips || propConfig.label} />
)
},
[VisualEditorPropsType.inputNumber]: () => <ElInputNumber v-model={propObj[prop]} />,
[VisualEditorPropsType.switch]: () => <ElSwitch v-model={propObj[prop]} />,
[VisualEditorPropsType.color]: () => <ElColorPicker v-model={propObj[prop]} />,
[VisualEditorPropsType.crossSortable]: () => (
<CrossSortableOptionsEditor v-model={propObj[prop]} />
<CrossSortableOptionsEditor v-model={propObj[prop]} multiple={propConfig.multiple} />
),
[VisualEditorPropsType.select]: () => (
<ElSelect v-model={propObj[prop]} valueKey={'value'} multiple={propConfig.multiple}>
@ -51,6 +62,21 @@ export const AttrEditor = defineComponent({
),
[VisualEditorPropsType.table]: () => (
<TablePropEditor v-model={propObj[prop]} propConfig={propConfig} />
),
[VisualEditorPropsType.modelBind]: () => (
<ElCascader
clearable={true}
props={{
checkStrictly: true,
children: 'entitys',
label: 'name',
value: 'key',
expandTrigger: 'hover'
}}
placeholder="请选择绑定的请求数据"
v-model={propObj[prop]}
options={models.value}
></ElCascader>
)
}[propConfig.type]()
}
@ -58,18 +84,7 @@ export const AttrEditor = defineComponent({
// 表单项
const FormEditor = () => {
const content: JSX.Element[] = []
if (!currentBlock.value) {
content.push(
<>
<ElFormItem label="容器宽度">
<ElInputNumber v-model={currentBlock.value.width} {...({ step: 100 } as any)} />
</ElFormItem>
<ElFormItem label="容器高度">
<ElInputNumber v-model={currentBlock.value.height} {...({ step: 100 } as any)} />
</ElFormItem>
</>
)
} else {
if (currentBlock.value) {
const { componentKey } = currentBlock.value
const component = visualConfig.componentMap[componentKey]
console.log('props.block:', currentBlock.value)

View File

@ -1,30 +1,45 @@
/*
* @Author:
* @Date: 2021-06-14 15:00:45
* @LastEditTime: 2021-06-24 18:28:07
* @LastEditTime: 2021-07-03 10:00:59
* @LastEditors:
* @Description:
* @FilePath: \vite-vue3-lowcode\src\visual-editor\components\right-attribute-panel\components\cross-sortable-options-editor\cross-sortable-options-editor.tsx
* @FilePath: \vite-vue3-lowcode\src\visual-editor\components\right-attribute-panel\components\attr-editor\components\cross-sortable-options-editor\cross-sortable-options-editor.tsx
*/
import { defineComponent, reactive, computed, PropType } from 'vue'
import Draggable from 'vuedraggable'
import { ElInput } from 'element-plus'
import { ElInput, ElCheckboxGroup, ElCheckbox } from 'element-plus'
import { useVModel } from '@vueuse/core'
import { isObject } from '@/visual-editor/utils/is'
import { useVisualData } from '@/visual-editor/hooks/useVisualData'
export const CrossSortableOptionsEditor = defineComponent({
props: {
modelValue: {
type: Array as PropType<string[]>,
type: Array as PropType<(string | LabelValue)[]>,
default: () => []
}
},
multiple: Boolean // 是否多选
},
setup(props, { emit }) {
const { currentBlock } = useVisualData()
const state = reactive({
list: useVModel(props, 'modelValue', emit),
drag: false
})
const checkList = computed({
get: () => {
const value = currentBlock.value.props.modelValue
return Array.isArray(value) ? value : [...new Set(value?.split(','))]
},
set(value) {
currentBlock.value.props.modelValue = value
}
})
const dragOptions = computed(() => {
return {
animation: 200,
@ -34,39 +49,89 @@ export const CrossSortableOptionsEditor = defineComponent({
}
})
const onChange = (val) => {
val = val.filter((item) => item !== '')
val = props.multiple
? val
: val.filter((n) => !currentBlock.value.props.modelValue?.includes(n))
currentBlock.value.props.modelValue = val.join(',')
}
const incrementOption = (index) => {
const newItem = state.list.some((item) => isObject(item))
? {
label: '',
value: ''
}
: ''
state.list.splice(index + 1, 0, newItem)
}
return () => (
<Draggable
tag="ul"
list={state.list}
class="list-group"
component-data={{
tag: 'ul',
type: 'transition-group',
name: !state.drag ? 'flip-list' : null
}}
handle=".handle"
{...dragOptions.value}
itemKey={''}
onStart={() => (state.drag = true)}
onEnd={() => (state.drag = false)}
<ElCheckboxGroup
modelValue={checkList.value}
style={{ fontSize: 'inherit' }}
onChange={onChange}
>
{{
item: ({ element, index }) => (
<div class={'flex items-center justify-between'}>
<i class={'el-icon-rank handle'}></i>
<ElInput
v-model={state.list[index]}
class={'m-12px'}
style={{ width: '270px' }}
></ElInput>
<div class={'flex flex-col'}>
<i class={'el-icon-circle-plus-outline'} onClick={() => state.list.push('')}></i>
<i class={'el-icon-remove-outline'} onClick={() => state.list.splice(index, 1)}></i>
<Draggable
tag="ul"
list={state.list}
class="list-group"
component-data={{
tag: 'ul',
type: 'transition-group',
name: !state.drag ? 'flip-list' : null
}}
handle=".handle"
{...dragOptions.value}
itemKey={''}
onStart={() => (state.drag = true)}
onEnd={() => (state.drag = false)}
>
{{
item: ({ element, index }) => (
<div class={'flex items-center justify-between'}>
<i class={'el-icon-rank handle cursor-move'}></i>
{isObject(element) ? (
<>
<ElCheckbox label={element.value} class={'ml-5px'}>
{''}
</ElCheckbox>
label:
<ElInput
v-model={element.label}
class={'my-12px mx-3px'}
style={{ width: '108px' }}
></ElInput>
value:
<ElInput
v-model={element.value}
class={'my-12px mx-3px'}
style={{ width: '106px' }}
></ElInput>
</>
) : (
<ElInput
v-model={state.list[index]}
class={'m-12px'}
style={{ width: '270px' }}
></ElInput>
)}
<div class={'flex flex-col'}>
<i
class={'el-icon-circle-plus-outline'}
onClick={() => incrementOption(index)}
></i>
<i
class={'el-icon-remove-outline'}
onClick={() => state.list.splice(index, 1)}
></i>
</div>
</div>
</div>
)
}}
</Draggable>
)
}}
</Draggable>
</ElCheckboxGroup>
)
}
})

View File

@ -1,18 +1,319 @@
/*
* @Author:
* @Date: 2021-06-24 11:01:45
* @LastEditTime: 2021-06-24 11:12:56
* @LastEditTime: 2021-06-28 18:49:18
* @LastEditors:
* @Description: -
* @FilePath: \vite-vue3-lowcode\src\visual-editor\components\right-attribute-panel\components\event-action\index.tsx
*/
import { defineComponent } from 'vue'
import { computed, defineComponent, reactive } from 'vue'
import { useVisualData } from '@/visual-editor/hooks/useVisualData'
import {
ElForm,
ElFormItem,
ElInput,
ElSelect,
ElOption,
ElCard,
ElButton,
ElCascader,
ElCollapse,
ElCollapseItem,
ElMessage
} from 'element-plus'
import type { Action, ActionHandle } from '@/visual-editor/visual-editor.utils'
import { generateUUID } from '@/visual-editor/utils/'
import { useModal } from '@/visual-editor/hooks/useModal'
import { cloneDeep } from 'lodash'
interface IState {
ruleFormRef: NonNullable<any>
activeNames: string[]
ruleForm: Action
}
/**
* @description
*/
const createEmptyActionHandle = () => ({
key: generateUUID(),
name: '',
link: ''
})
/**
* @description
*/
const createEmptyAction = (): Action => ({
key: generateUUID(),
name: '',
event: '',
handle: [createEmptyActionHandle()]
})
export const EventAction = defineComponent({
setup() {
const { currentBlock, currentPage, jsonData } = useVisualData()
/**
* @description
*/
const isEdit = computed(() =>
currentBlock.value.actions.some((item) => item.key === state.ruleForm.key)
)
const state = reactive<IState>({
ruleFormRef: null,
activeNames: [],
ruleForm: createEmptyAction()
})
/**
* @description
*/
const actionOptions = computed(() => [
{
label: '全局',
value: 'global',
children: Object.keys(jsonData.actions).map((actionKey) => {
const item = cloneDeep(jsonData.actions[actionKey])
item.value = actionKey
item.label = item.name
const arrKey = Object.keys(item).find((key) => Array.isArray(item[key]))
item.children = (item[arrKey] || []).map((item: any) => {
item.label = item.name
item.value = item.key
return item
})
return item
})
},
{
label: '组件',
value: 'component',
children: cloneDeep(currentPage.value.blocks)
.filter((item) => item.actions?.length)
.map((item) => {
item.value = item._vid
item.label = item.label
item.children = (item.actions || []).map((item: any) => {
item.label = item.name
item.value = item.key
return item
})
return item
})
}
])
/**
*
*/
const getActionPath = (link: string[]) => {
let result = ''
const maxLength = link.length - 1
link.reduce((prev, curr, index) => {
const target = prev.find((item) => item.value == curr)
const append = maxLength !== index ? ' => ' : ''
result += target?.label + append
return target?.children
}, actionOptions.value)
return result
}
/**
* @description
*/
const deleteActionItem = (index: number) => {
currentBlock.value.actions.splice(index, 1)
}
/**
* @description
*/
const deleteActionHandleItem = (index: number) => {
state.ruleForm.handle.splice(index, 1)
}
/**
* @description
*/
const addActionItem = () => {
state.ruleForm = createEmptyAction()
showOperateModal()
}
/**
* @description
*/
const addActionHanleItem = () => {
state.ruleForm.handle.push(createEmptyActionHandle())
}
/**
* @description
*/
const showEditActionModal = (action: Action) => {
state.ruleForm = cloneDeep(action)
showOperateModal()
}
/**
* @description
*/
const showOperateModal = () => {
const operateType = isEdit.value ? '编辑' : '新增'
useModal({
title: `${operateType}动作`,
props: { width: 600 },
content: () => (
<ElForm
model={state.ruleForm}
ref={(el) => el && (state.ruleFormRef = el)}
label-width="100px"
size={'mini'}
>
<ElFormItem
label="事件"
prop={'event'}
rules={[{ required: true, message: '请选择事件', trigger: 'change' }]}
>
<ElSelect v-model={state.ruleForm.event} class={'w-full'}>
{currentBlock.value.events.map((eventItem) => (
<ElOption
key={eventItem.value}
label={eventItem.label}
value={eventItem.value}
></ElOption>
))}
</ElSelect>
</ElFormItem>
<ElFormItem
label="事件名称"
prop="name"
rules={[{ required: true, message: '请输入事件名称', trigger: 'change' }]}
>
<ElInput v-model={state.ruleForm.name} placeholder={'请输入事件名称'}></ElInput>
</ElFormItem>
{!state.ruleForm.handle?.length && (
<ElFormItem>
<ElButton onClick={addActionHanleItem} type={'primary'} size={'mini'}>
</ElButton>
</ElFormItem>
)}
{state.ruleForm.handle.map((handleItem, index) => (
<ElCard
key={handleItem.key}
shadow={'hover'}
class={'mt-10px'}
v-slots={{
header: () => (
<div class={'flex justify-between'}>
<ElFormItem
label="动作名称"
prop={`handle.${index}.name`}
rules={[{ required: true, message: '请输入动作名称', trigger: 'change' }]}
>
<ElInput v-model={handleItem.name} placeholder={'请输入动作名称'}></ElInput>
</ElFormItem>
<div>
<ElButton
onClick={() => deleteActionHandleItem(index)}
type={'danger'}
size={'mini'}
>
</ElButton>
<ElButton onClick={addActionHanleItem} type={'primary'} size={'mini'}>
</ElButton>
</div>
</div>
)
}}
>
<ElFormItem
label="触发的动作"
prop={`handle.${index}.link`}
rules={[{ required: true, message: '请选择你要触发的动作', trigger: 'change' }]}
>
<ElCascader
clearable={true}
class={'w-full'}
placeholder="请选择你要触发的动作"
v-model={handleItem.link}
options={actionOptions.value}
></ElCascader>
</ElFormItem>
</ElCard>
))}
</ElForm>
),
onConfirm: () => {
return new Promise((resolve, reject) => {
state.ruleFormRef.validate((valid) => {
if (valid) {
const index = currentBlock.value.actions.findIndex(
(item) => item.key == state.ruleForm.key
)
if (index === -1) {
currentBlock.value.actions.push(state.ruleForm)
} else {
currentBlock.value.actions.splice(index, 1, state.ruleForm)
}
state.ruleForm = createEmptyAction()
resolve('submit!')
} else {
reject()
console.log('error submit!!')
return false
}
})
})
},
onCancel: () => (state.ruleForm = createEmptyAction())
})
}
return () => (
<>
<div></div>
<ElButton onClick={addActionItem} type={'primary'} size={'mini'}>
</ElButton>
{currentBlock.value.actions?.map((actionItem, index) => (
<ElCard
key={index}
class={'mt-10px'}
v-slots={{
header: () => (
<div class={'flex justify-between'}>
{actionItem.name}
<div>
<ElButton onClick={() => deleteActionItem(index)} type={'danger'} size={'mini'}>
</ElButton>
<ElButton
onClick={() => showEditActionModal(actionItem)}
type={'primary'}
size={'mini'}
>
</ElButton>
</div>
</div>
)
}}
>
<ElCollapse v-model={state.activeNames}>
{actionItem.handle.map((item, index) => (
<ElCollapseItem title={`${index + 1}. ${item.name}`} key={item.key} name={item.key}>
{{
default: () => <div>{getActionPath(item.link)}</div>
}}
</ElCollapseItem>
))}
</ElCollapse>
</ElCard>
))}
</>
)
}

View File

@ -1,7 +1,7 @@
/*
* @Author:
* @Date: 2021-06-01 13:22:14
* @LastEditTime: 2021-06-24 11:21:35
* @LastEditTime: 2021-06-28 09:25:06
* @LastEditors:
* @Description:
* @FilePath: \vite-vue3-lowcode\src\visual-editor\components\right-attribute-panel\index.tsx

View File

@ -229,11 +229,11 @@ export default defineComponent({
display: flex;
width: 100%;
height: 100%;
padding-right: 240px;
padding-right: 380px;
align-items: center;
justify-content: center;
@media (max-width: 1314px) {
@media (max-width: 1114px) {
padding-right: 0;
}
}

View File

@ -50,14 +50,14 @@ const defaultValue: VisualEditorModelValue = {
},
models: [], // 模型实体集合
actions: {
// 动作
// 动作集合
fetch: {
name: '接口请求',
apis: []
},
dialog: {
name: '对话框',
handles: []
handlers: []
}
}
}
@ -219,7 +219,7 @@ export const initVisualData = () => {
}
return {
visualConfig,
visualConfig: visualConfig,
jsonData: readonly(state.jsonData), // 保护JSONData避免直接修改
currentPage: computed(() => state.currentPage),
currentBlock: computed(() => state.currentBlock),
@ -239,7 +239,7 @@ export const initVisualData = () => {
}
}
export const useVisualData = () => inject<ReturnType<typeof useVisualData>>(injectKey)!
export const useVisualData = () => inject<ReturnType<typeof initVisualData>>(injectKey)!
/**
*

View File

@ -1,11 +1,15 @@
/**
* @name: index.d
* @author:
* @date: 2021/5/30 10:40
* @descriptionindex.d
* @update: 2021/5/30 10:40
/*
* @Author:
* @Date: 2021-06-01 09:45:21
* @LastEditTime: 2021-07-02 20:25:58
* @LastEditors:
* @Description:
* @FilePath: \vite-vue3-lowcode\src\visual-editor\types\index.d.ts
*/
declare type LabelValueOptions = {
declare type LabelValue = {
label: string
value: any
}[]
}
declare type LabelValueOptions = OptionItem[]

View File

@ -5,7 +5,8 @@ export enum VisualEditorPropsType {
select = 'select',
table = 'table',
switch = 'switch',
crossSortable = 'crossSortable'
modelBind = 'ModelBind',
crossSortable = 'CrossSortable'
}
export type VisualEditorProps = {
@ -21,6 +22,26 @@ export type VisualEditorProps = {
table?: VisualEditorTableOption
}
/*---------------------------------------modelBind-------------------------------------------*/
interface EditorModelBindProp {
label: string
defaultValue?: any
tips?: string
}
export function createEditorModelBindProp({
label = '字段绑定',
defaultValue,
tips
}: EditorModelBindProp): VisualEditorProps {
return {
type: VisualEditorPropsType.modelBind,
label,
tips,
defaultValue
}
}
/*---------------------------------------switch-------------------------------------------*/
interface EditorSwitchProp {
label: string
@ -162,18 +183,21 @@ export function createEditorTableProp({
interface EditorCrossSortableProp {
label: string
labelPosition: string
defaultValue?: string[]
labelPosition: 'top' | ''
multiple?: boolean
defaultValue?: string[] | VisualEditorSelectOptions
}
export function createEditorCrossSortableProp({
label,
labelPosition,
multiple,
defaultValue
}: EditorCrossSortableProp): VisualEditorProps {
return {
type: VisualEditorPropsType.crossSortable,
label,
multiple,
labelPosition,
defaultValue
}

View File

@ -23,8 +23,32 @@ export interface VisualEditorBlockData {
model: Record<string, string> // 绑定的字段
slotName?: string // 组件唯一标识
animations?: Animation[] // 动画集
actions: Action[] // 组件动作集合
events: { label: string; value: string }[] // 组件事件集合
[prop: string]: any
}
/**
* @description
*/
export interface ActionHandle {
key: string
name: string
link: string
data?: {
bind?: string
recv?: string
}
}
/**
* @description
*/
export interface Action {
key: string
name: string
event: string
handle: ActionHandle[]
}
/**
* @description
*/
@ -93,7 +117,7 @@ export interface VisualEditorActions {
}
dialog: {
name: '对话框'
handles: []
handlers: []
}
}
/**
@ -133,6 +157,7 @@ export interface VisualEditorComponent {
}) => JSX.Element
props?: Record<string, VisualEditorProps>
animations?: Animation[] // 动画集
events?: { label: string; value: string }[] // 组件事件集合
resize?: { width?: boolean; height?: boolean }
}
@ -173,6 +198,8 @@ export function createNewBlock({
return prev
}, {}),
animations: [], // 动画集
actions: [], // 动作集合
events: component.events || [], // 事件集合
model: {}
}
}

View File

@ -16,6 +16,7 @@ export default ({ mode }: ConfigEnv): UserConfig => {
// 环境变量
const { VITE_BASE_URL } = loadEnv(mode, CWD)
return {
base: VITE_BASE_URL, // 设置打包路径
css: {
modules: {
localsConvention: 'camelCase' // 默认只支持驼峰,修改为同时支持横线和驼峰
@ -58,7 +59,6 @@ export default ({ mode }: ConfigEnv): UserConfig => {
'@': resolve(__dirname, 'src') // 设置 `@` 指向 `src` 目录
}
},
base: VITE_BASE_URL, // 设置打包路径
build: {
rollupOptions: {
input: {
@ -91,17 +91,17 @@ export default ({ mode }: ConfigEnv): UserConfig => {
server: {
port: 10086, // 设置服务启动端口号
open: false, // 设置服务启动时是否自动打开浏览器
cors: true // 允许跨域
cors: true, // 允许跨域
// 设置代理,根据我们项目实际情况配置
// proxy: {
// '/api': {
// target: 'http://xxx.xxx.xxx.xxx:x000',
// changeOrigin: true,
// secure: false,
// rewrite: (path) => path.replace('/api/', '/')
// }
// },
// 设置代理,根据项目实际情况配置
proxy: {
'/api': {
target: 'http://29135jo738.zicp.vip/api/v1',
changeOrigin: true,
secure: false,
rewrite: (path) => path.replace('/api/', '/')
}
}
}
}
}

352
yarn.lock
View File

@ -28,7 +28,7 @@
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.7.tgz#7b047d7a3a89a67d2258dc61f604f098f1bc7e08"
integrity sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==
"@babel/core@>=7.9.0", "@babel/core@^7.12.10":
"@babel/core@>=7.9.0", "@babel/core@^7.14.6":
version "7.14.6"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.6.tgz#e0814ec1a950032ff16c13a2721de39a8416fcab"
integrity sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==
@ -228,7 +228,7 @@
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
"@babel/plugin-transform-typescript@^7.12.1":
"@babel/plugin-transform-typescript@^7.14.6":
version "7.14.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.14.6.tgz#6e9c2d98da2507ebe0a883b100cde3c7279df36c"
integrity sha512-XlTdBq7Awr4FYIzqhmYY80WN0V0azF74DMPyFqVHBvf81ZUgc4X7ZOpx6O8eLDK6iM5cCQzeyJw0ynTaefixRA==
@ -237,7 +237,7 @@
"@babel/helper-plugin-utils" "^7.14.5"
"@babel/plugin-syntax-typescript" "^7.14.5"
"@babel/standalone@^7.14.6":
"@babel/standalone@^7.14.7":
version "7.14.7"
resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.14.7.tgz#68635da005d6a34a0259599e0720d2e73133ecc3"
integrity sha512-7RlfMPR4604SbYpj5zvs2ZK587hVhixgU9Pd9Vs8lB8KYtT3U0apXSf0vZXhy8XRh549eUmJOHXhWKTO3ObzOQ==
@ -445,6 +445,20 @@
minimatch "^3.0.4"
strip-json-comments "^3.1.1"
"@humanwhocodes/config-array@^0.5.0":
version "0.5.0"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9"
integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==
dependencies:
"@humanwhocodes/object-schema" "^1.2.0"
debug "^4.1.1"
minimatch "^3.0.4"
"@humanwhocodes/object-schema@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf"
integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
@ -667,11 +681,16 @@
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256"
integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==
"@types/node@*", "@types/node@^15.12.4":
"@types/node@*":
version "15.12.4"
resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.4.tgz#e1cf817d70a1e118e81922c4ff6683ce9d422e26"
integrity sha512-zrNj1+yqYF4WskCMOHwN+w9iuD12+dGm0rQ35HLl9/Ouuq52cEtd0CH9qMgrdNmi5ejC1/V7vKEXYubB+65DkA==
"@types/node@^16.0.0":
version "16.0.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.0.0.tgz#067a6c49dc7a5c2412a505628e26902ae967bf6f"
integrity sha512-TmCW5HoZ2o2/z2EYi109jLqIaPIi9y/lc2LmDCWzuCi35bcaQ+OtUh6nwBiFK7SOu25FAU5+YKdqFZUwtqGSdg==
"@types/normalize-package-data@^2.4.0":
version "2.4.0"
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
@ -708,73 +727,73 @@
"@types/unist" "*"
"@types/vfile-message" "*"
"@typescript-eslint/eslint-plugin@^4.28.0":
version "4.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.0.tgz#1a66f03b264844387beb7dc85e1f1d403bd1803f"
integrity sha512-KcF6p3zWhf1f8xO84tuBailV5cN92vhS+VT7UJsPzGBm9VnQqfI9AsiMUFUCYHTYPg1uCCo+HyiDnpDuvkAMfQ==
"@typescript-eslint/eslint-plugin@^4.28.1":
version "4.28.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.1.tgz#c045e440196ae45464e08e20c38aff5c3a825947"
integrity sha512-9yfcNpDaNGQ6/LQOX/KhUFTR1sCKH+PBr234k6hI9XJ0VP5UqGxap0AnNwBnWFk1MNyWBylJH9ZkzBXC+5akZQ==
dependencies:
"@typescript-eslint/experimental-utils" "4.28.0"
"@typescript-eslint/scope-manager" "4.28.0"
"@typescript-eslint/experimental-utils" "4.28.1"
"@typescript-eslint/scope-manager" "4.28.1"
debug "^4.3.1"
functional-red-black-tree "^1.0.1"
regexpp "^3.1.0"
semver "^7.3.5"
tsutils "^3.21.0"
"@typescript-eslint/experimental-utils@4.28.0":
version "4.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.0.tgz#13167ed991320684bdc23588135ae62115b30ee0"
integrity sha512-9XD9s7mt3QWMk82GoyUpc/Ji03vz4T5AYlHF9DcoFNfJ/y3UAclRsfGiE2gLfXtyC+JRA3trR7cR296TEb1oiQ==
"@typescript-eslint/experimental-utils@4.28.1":
version "4.28.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.1.tgz#3869489dcca3c18523c46018b8996e15948dbadc"
integrity sha512-n8/ggadrZ+uyrfrSEchx3jgODdmcx7MzVM2sI3cTpI/YlfSm0+9HEUaWw3aQn2urL2KYlWYMDgn45iLfjDYB+Q==
dependencies:
"@types/json-schema" "^7.0.7"
"@typescript-eslint/scope-manager" "4.28.0"
"@typescript-eslint/types" "4.28.0"
"@typescript-eslint/typescript-estree" "4.28.0"
"@typescript-eslint/scope-manager" "4.28.1"
"@typescript-eslint/types" "4.28.1"
"@typescript-eslint/typescript-estree" "4.28.1"
eslint-scope "^5.1.1"
eslint-utils "^3.0.0"
"@typescript-eslint/parser@^4.28.0":
version "4.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.0.tgz#2404c16751a28616ef3abab77c8e51d680a12caa"
integrity sha512-7x4D22oPY8fDaOCvkuXtYYTQ6mTMmkivwEzS+7iml9F9VkHGbbZ3x4fHRwxAb5KeuSkLqfnYjs46tGx2Nour4A==
"@typescript-eslint/parser@^4.28.1":
version "4.28.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.1.tgz#5181b81658414f47291452c15bf6cd44a32f85bd"
integrity sha512-UjrMsgnhQIIK82hXGaD+MCN8IfORS1CbMdu7VlZbYa8LCZtbZjJA26De4IPQB7XYZbL8gJ99KWNj0l6WD0guJg==
dependencies:
"@typescript-eslint/scope-manager" "4.28.0"
"@typescript-eslint/types" "4.28.0"
"@typescript-eslint/typescript-estree" "4.28.0"
"@typescript-eslint/scope-manager" "4.28.1"
"@typescript-eslint/types" "4.28.1"
"@typescript-eslint/typescript-estree" "4.28.1"
debug "^4.3.1"
"@typescript-eslint/scope-manager@4.28.0":
version "4.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.0.tgz#6a3009d2ab64a30fc8a1e257a1a320067f36a0ce"
integrity sha512-eCALCeScs5P/EYjwo6se9bdjtrh8ByWjtHzOkC4Tia6QQWtQr3PHovxh3TdYTuFcurkYI4rmFsRFpucADIkseg==
"@typescript-eslint/scope-manager@4.28.1":
version "4.28.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.1.tgz#fd3c20627cdc12933f6d98b386940d8d0ce8a991"
integrity sha512-o95bvGKfss6705x7jFGDyS7trAORTy57lwJ+VsYwil/lOUxKQ9tA7Suuq+ciMhJc/1qPwB3XE2DKh9wubW8YYA==
dependencies:
"@typescript-eslint/types" "4.28.0"
"@typescript-eslint/visitor-keys" "4.28.0"
"@typescript-eslint/types" "4.28.1"
"@typescript-eslint/visitor-keys" "4.28.1"
"@typescript-eslint/types@4.28.0":
version "4.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.0.tgz#a33504e1ce7ac51fc39035f5fe6f15079d4dafb0"
integrity sha512-p16xMNKKoiJCVZY5PW/AfILw2xe1LfruTcfAKBj3a+wgNYP5I9ZEKNDOItoRt53p4EiPV6iRSICy8EPanG9ZVA==
"@typescript-eslint/types@4.28.1":
version "4.28.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.1.tgz#d0f2ecbef3684634db357b9bbfc97b94b828f83f"
integrity sha512-4z+knEihcyX7blAGi7O3Fm3O6YRCP+r56NJFMNGsmtdw+NCdpG5SgNz427LS9nQkRVTswZLhz484hakQwB8RRg==
"@typescript-eslint/typescript-estree@4.28.0":
version "4.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.0.tgz#e66d4e5aa2ede66fec8af434898fe61af10c71cf"
integrity sha512-m19UQTRtxMzKAm8QxfKpvh6OwQSXaW1CdZPoCaQuLwAq7VZMNuhJmZR4g5281s2ECt658sldnJfdpSZZaxUGMQ==
"@typescript-eslint/typescript-estree@4.28.1":
version "4.28.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.1.tgz#af882ae41740d1f268e38b4d0fad21e7e8d86a81"
integrity sha512-GhKxmC4sHXxHGJv8e8egAZeTZ6HI4mLU6S7FUzvFOtsk7ZIDN1ksA9r9DyOgNqowA9yAtZXV0Uiap61bIO81FQ==
dependencies:
"@typescript-eslint/types" "4.28.0"
"@typescript-eslint/visitor-keys" "4.28.0"
"@typescript-eslint/types" "4.28.1"
"@typescript-eslint/visitor-keys" "4.28.1"
debug "^4.3.1"
globby "^11.0.3"
is-glob "^4.0.1"
semver "^7.3.5"
tsutils "^3.21.0"
"@typescript-eslint/visitor-keys@4.28.0":
version "4.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.0.tgz#255c67c966ec294104169a6939d96f91c8a89434"
integrity sha512-PjJyTWwrlrvM5jazxYF5ZPs/nl0kHDZMVbuIcbpawVXaDPelp3+S9zpOz5RmVUfS/fD5l5+ZXNKnWhNYjPzCvw==
"@typescript-eslint/visitor-keys@4.28.1":
version "4.28.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.1.tgz#162a515ee255f18a6068edc26df793cdc1ec9157"
integrity sha512-K4HMrdFqr9PFquPu178SaSb92CaWe2yErXyPumc8cYWxFmhgJsNY9eSePmO05j0JhBvf2Cdhptd6E6Yv9HVHcg==
dependencies:
"@typescript-eslint/types" "4.28.0"
"@typescript-eslint/types" "4.28.1"
eslint-visitor-keys "^2.0.0"
"@vant/icons@^1.6.0":
@ -804,33 +823,33 @@
resolved "https://registry.yarnpkg.com/@vant/use/-/use-1.1.2.tgz#d35265e05df88a47b04196a308efb5e89e44ca10"
integrity sha512-s4YO6zqJ3NlGeAZ104exb0c/KvlXB908pOhWhCyhfedVBn1eBnKH401ildK0sttazmq0CH8jme6mnw2ZzZvutw==
"@vitejs/plugin-legacy@^1.4.2":
version "1.4.2"
resolved "https://registry.yarnpkg.com/@vitejs/plugin-legacy/-/plugin-legacy-1.4.2.tgz#219e7b86a9febe62b85a66b68127a89954ed93e5"
integrity sha512-D2ADBSpImP0QT8w9Eo+8KKOLg3I8OQhFwuBXGM8WQCRrEs55E3bCf9PTkL8S+tgliyLbJM+gjemxpRuoTTwphA==
"@vitejs/plugin-legacy@^1.4.3":
version "1.4.3"
resolved "https://registry.yarnpkg.com/@vitejs/plugin-legacy/-/plugin-legacy-1.4.3.tgz#d022275d08e6f1f777891fb405816a9dd41a9f1f"
integrity sha512-lxZUJaMWYMQuqvZM1wPzDP6KABQgA/drVL5fnaygEPcz9adc2OHhfFNN/SvvHQ1V0rP8gybIc7uA+iI1gAdkVQ==
dependencies:
"@babel/standalone" "^7.14.6"
core-js "^3.14.0"
"@babel/standalone" "^7.14.7"
core-js "^3.15.1"
magic-string "^0.25.7"
regenerator-runtime "^0.13.7"
systemjs "^6.10.1"
"@vitejs/plugin-vue-jsx@^1.1.5":
version "1.1.5"
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-1.1.5.tgz#e856ef42f59048e59c85f8714dc8397e15f81738"
integrity sha512-YujG7IgbZR8zWGY/hZFxYKrAUdO+9OV4t3pqqQrvbtP/ESwvTY8vb0Zpw1VMO8zLWNGqf8jSbjBaCjN49diplw==
"@vitejs/plugin-vue-jsx@^1.1.6":
version "1.1.6"
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-1.1.6.tgz#c9e7b63d1ebf537a24a0b4b3b31f4beb8055cef6"
integrity sha512-1vKGALnBFt7hUIOgkC4ZAhTRgENpSgGBsdltJn3fPNcqrbrvR/HaRS5VThjCCoN69d0d+VlDXOTlWcfUpE3pfQ==
dependencies:
"@babel/core" "^7.12.10"
"@babel/core" "^7.14.6"
"@babel/plugin-syntax-import-meta" "^7.10.4"
"@babel/plugin-transform-typescript" "^7.12.1"
"@babel/plugin-transform-typescript" "^7.14.6"
"@rollup/pluginutils" "^4.1.0"
"@vue/babel-plugin-jsx" "^1.0.3"
"@vue/babel-plugin-jsx" "^1.0.6"
hash-sum "^2.0.0"
"@vitejs/plugin-vue@^1.2.3":
version "1.2.3"
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-1.2.3.tgz#2e8e008b1cc3a6ad1dfbec75743c7ffd9b4872a6"
integrity sha512-LlnLpObkGKZ+b7dcpL4T24l13nPSHLjo+6Oc7MbZiKz5PMAUzADfNJ3EKfYIQ0l0969nxf2jp/9vsfnuJ7h6fw==
"@vitejs/plugin-vue@^1.2.4":
version "1.2.4"
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-1.2.4.tgz#a7aa6e6a31c556a8b781de730316deeecf7f56f2"
integrity sha512-D/3H9plevPQGgQGwmV6eecvOnooLTecPR63HPffVVWPEhbfvmtYLWgznzs456NBb2DItiRTCIa1yWxvGqC+I8A==
"@volar/code-gen@^0.25.22":
version "0.25.22"
@ -877,7 +896,7 @@
resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.2.tgz#9b9c691cd06fc855221a2475c3cc831d774bc7dc"
integrity sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==
"@vue/babel-plugin-jsx@^1.0.3":
"@vue/babel-plugin-jsx@^1.0.6":
version "1.0.6"
resolved "https://registry.yarnpkg.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.0.6.tgz#184bf3541ab6efdbe5079ab8b20c19e2af100bfb"
integrity sha512-RzYsvBhzKUmY2YG6LoV+W5PnlnkInq0thh1AzCmewwctAgGN6e9UFon6ZrQQV1CO5G5PeME7MqpB+/vvGg0h4g==
@ -903,6 +922,17 @@
estree-walker "^2.0.1"
source-map "^0.6.1"
"@vue/compiler-core@3.1.4":
version "3.1.4"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.1.4.tgz#a3a74cf52e8f01af386d364ac8a099cbeb260424"
integrity sha512-TnUz+1z0y74O/A4YKAbzsdUfamyHV73MihrEfvettWpm9bQKVoZd1nEmR1cGN9LsXWlwAvVQBetBlWdOjmQO5Q==
dependencies:
"@babel/parser" "^7.12.0"
"@babel/types" "^7.12.0"
"@vue/shared" "3.1.4"
estree-walker "^2.0.1"
source-map "^0.6.1"
"@vue/compiler-dom@3.1.2", "@vue/compiler-dom@^3.0.11":
version "3.1.2"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.1.2.tgz#75a7731bcc5d9718183a3c56c18e992f7c13e7b1"
@ -911,7 +941,38 @@
"@vue/compiler-core" "3.1.2"
"@vue/shared" "3.1.2"
"@vue/compiler-sfc@3.1.2", "@vue/compiler-sfc@^3.0.11":
"@vue/compiler-dom@3.1.4":
version "3.1.4"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.1.4.tgz#bf3795e1449f32c965d38c4ea6d808ca05fdfc97"
integrity sha512-3tG2ScHkghhUBuFwl9KgyZhrS8CPFZsO7hUDekJgIp5b1OMkROr4AvxHu6rRMl4WkyvYkvidFNBS2VfOnwa6Kw==
dependencies:
"@vue/compiler-core" "3.1.4"
"@vue/shared" "3.1.4"
"@vue/compiler-sfc@3.1.4":
version "3.1.4"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.1.4.tgz#93e87db950e0711339c18baa7bb7d28d3522d7bc"
integrity sha512-4KDQg60Khy3SgnF+V/TB2NZqzmM4TyGRmzsxqG1SebGdMSecCweFDSlI/F1vDYk6dKiCHgmpoT9A1sLxswkJ0A==
dependencies:
"@babel/parser" "^7.13.9"
"@babel/types" "^7.13.0"
"@types/estree" "^0.0.48"
"@vue/compiler-core" "3.1.4"
"@vue/compiler-dom" "3.1.4"
"@vue/compiler-ssr" "3.1.4"
"@vue/shared" "3.1.4"
consolidate "^0.16.0"
estree-walker "^2.0.1"
hash-sum "^2.0.0"
lru-cache "^5.1.1"
magic-string "^0.25.7"
merge-source-map "^1.1.0"
postcss "^8.1.10"
postcss-modules "^4.0.0"
postcss-selector-parser "^6.0.4"
source-map "^0.6.1"
"@vue/compiler-sfc@^3.0.11":
version "3.1.2"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.1.2.tgz#23ff1e366d887b964899568bffcb11e3d0511fc4"
integrity sha512-SeG/2+DvwejQ7oAiSx8BrDh5qOdqCYHGClPiTvVIHTfSIHiS2JjMbCANdDCjHkTOh/O7WZzo2JhdKm98bRBxTw==
@ -942,33 +1003,48 @@
"@vue/compiler-dom" "3.1.2"
"@vue/shared" "3.1.2"
"@vue/compiler-ssr@3.1.4":
version "3.1.4"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.1.4.tgz#7f6eaac5b1851fc15c82c083e8179eb1216b303c"
integrity sha512-Box8fCuCFPp0FuimIswjDkjwiSDCBkHvt/xVALyFkYCiIMWv2eR53fIjmlsnEHhcBuZ+VgRC+UanCTcKvSA1gA==
dependencies:
"@vue/compiler-dom" "3.1.4"
"@vue/shared" "3.1.4"
"@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.0.0-beta.14":
version "6.0.0-beta.14"
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.0.0-beta.14.tgz#6ed2d6f8d66a9256c9ad04bfff08309ba87b9723"
integrity sha512-44fPrrN1cqcs6bFkT0C+yxTM6PZXLbR+ESh1U1j8UD22yO04gXvxH62HApMjLbS3WqJO/iCNC+CYT+evPQh2EQ==
"@vue/reactivity@3.1.2", "@vue/reactivity@^3.0.11":
"@vue/reactivity@3.1.4":
version "3.1.4"
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.1.4.tgz#d926ed46fb0d48582ccf8665b062d37b5d35ba99"
integrity sha512-YDlgii2Cr9yAoKVZFzgY4j0mYlVT73986X3e5SPp6ifqckSEoFSUWXZK2Tb53TB/9qO29BEEbspnKD3m3wAwkA==
dependencies:
"@vue/shared" "3.1.4"
"@vue/reactivity@^3.0.11":
version "3.1.2"
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.1.2.tgz#66fa530dd726d2fef285ae55d02106a727db463b"
integrity sha512-glJzJoN2xE7I2lRvwKM5u1BHRPTd1yc8iaf//Lai/78/uYAvE5DXp5HzWRFOwMlbRvMGJHIQjOqoxj87cDAaag==
dependencies:
"@vue/shared" "3.1.2"
"@vue/runtime-core@3.1.2":
version "3.1.2"
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.1.2.tgz#f4dbc503cfc9a02ab5f1ebe002c3322512064a54"
integrity sha512-gsPZG4dRIkixuuKmoj4P9IHgfT0yaFLcqWOM5F/bCk0nxQn1XtxH8oUehWuET726KhbukvDoJfe9G2CKviy80w==
"@vue/runtime-core@3.1.4":
version "3.1.4"
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.1.4.tgz#3e30ae6ecbfff06df5adc9414491143191a375ba"
integrity sha512-qmVJgJuFxfT7M4qHQ4M6KqhKC66fjuswK+aBivE8dWiZ2rtIGl9gtJGpwqwjQEcKEBTOfvvrtrwBncYArJUO8Q==
dependencies:
"@vue/reactivity" "3.1.2"
"@vue/shared" "3.1.2"
"@vue/reactivity" "3.1.4"
"@vue/shared" "3.1.4"
"@vue/runtime-dom@3.1.2":
version "3.1.2"
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.1.2.tgz#0fd8724f14bc7ba64b6c954d874a8d8a4fcb5fe9"
integrity sha512-QvINxjLucEZFzp5f0NVu7JqWYCv5TKQfkH2FDs/N6QNE4iKcYtKrWdT0HKfABnVXG28Znqv6rIH0dH4ZAOwxpA==
"@vue/runtime-dom@3.1.4":
version "3.1.4"
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.1.4.tgz#acfeee200d5c45fc2cbdf7058cda1498f9b45849"
integrity sha512-vbmwgTxku1BU87Kw7r29adv0OIrDXCW0PslOPQT0O/9R5SqcXgS94Yj6zsztDjvghegenwIAPNLlDR1Auh5s+w==
dependencies:
"@vue/runtime-core" "3.1.2"
"@vue/shared" "3.1.2"
"@vue/runtime-core" "3.1.4"
"@vue/shared" "3.1.4"
csstype "^2.6.8"
"@vue/shared@3.1.2", "@vue/shared@^3.0.11":
@ -976,6 +1052,11 @@
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.1.2.tgz#1069c0bc7d6f4bd15ccf3a5f3be29450aca368f9"
integrity sha512-EmH/poaDWBPJaPILXNI/1fvUbArJQmmTyVCwvvyDYDFnkPoTclAbHRAtyIvqfez7jybTDn077HTNILpxlsoWhg==
"@vue/shared@3.1.4":
version "3.1.4"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.1.4.tgz#c14c461ec42ea2c1556e86f60b0354341d91adc3"
integrity sha512-6O45kZAmkLvzGLToBxEz4lR2W6kXohCtebV2UxjH9GXjd8X9AhEn68FN9eNanFtWNzvgw1hqd6HkPRVQalqf7Q==
"@vueuse/core@^5.0.3":
version "5.0.3"
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-5.0.3.tgz#8f3170e2a51ae62fb1725c84d4cc02a7552aad0b"
@ -1006,10 +1087,10 @@
dependencies:
vue-demi "*"
"@windicss/plugin-utils@1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@windicss/plugin-utils/-/plugin-utils-1.1.1.tgz#7f70952adc8d33f607706e434a153e2cdff52b64"
integrity sha512-niKEDyUpOfCGemFHopI9fxdWPpJQIZ/jmaU4spQXsGc1oEts164P8LUJPQmXc8C6vjKwkrH7KA+lxYNG5LmlDA==
"@windicss/plugin-utils@1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@windicss/plugin-utils/-/plugin-utils-1.2.0.tgz#f9c657f981d7696dfa6b8e8069b311161a2ac9b4"
integrity sha512-6OAsyz2yI0VKNHACT35FjWWzMZlMEF7Z0pIiNUd9+R9jc73+qJcK1DRCZ3YxnjuGk0G76b542uXQEJgv2jL3vA==
dependencies:
"@antfu/utils" "^0.2.3"
debug "^4.3.2"
@ -1543,7 +1624,7 @@ chardet@^0.7.0:
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.1:
"chokidar@>=3.0.0 <4.0.0":
version "3.5.2"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75"
integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==
@ -1812,7 +1893,7 @@ cookie@^0.4.0:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1"
integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==
core-js@^3.14.0:
core-js@^3.15.1:
version "3.15.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.15.1.tgz#6c08ab88abdf56545045ccf5fd81f47f407e7f1a"
integrity sha512-h8VbZYnc9pDzueiS2610IULDkpFFPunHwIpl8yRwFahAEEdSpHlTy3h3z3rKq5h11CaUdBEeRViu9AYvbxiMeg==
@ -2153,10 +2234,10 @@ electron-to-chromium@^1.3.723:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.755.tgz#4b6101f13de910cf3f0a1789ddc57328133b9332"
integrity sha512-BJ1s/kuUuOeo1bF/EM2E4yqW9te0Hpof3wgwBx40AWJE18zsD1Tqo0kr7ijnOc+lRsrlrqKPauJAHqaxOItoUA==
element-plus@1.0.2-beta.52:
version "1.0.2-beta.52"
resolved "https://registry.yarnpkg.com/element-plus/-/element-plus-1.0.2-beta.52.tgz#c7ed94d498e390658478aa2438bc35247325b2d0"
integrity sha512-oAuJHwXyvM4dsuOz7HSDPIBVPqRJ1KEzFzGqYdqbBjQ/aw79uCJxvS9Q4q9/XrPMfPire09+bPTypiIaHkNBhA==
element-plus@1.0.2-beta.54:
version "1.0.2-beta.54"
resolved "https://registry.yarnpkg.com/element-plus/-/element-plus-1.0.2-beta.54.tgz#70eda3fc0ef4c28a1cdc6bffec8f9c34ef83cc16"
integrity sha512-XXgZMnVt2ECtLyxJLVMq+faTxcYKNy9ZTaQ4cgbITgR/iGF5iXPHHjn1J1DWNLIKJ0XQRo8atAM1fyOpJsyJzw==
dependencies:
"@popperjs/core" "^2.4.4"
"@types/lodash" "^4.14.161"
@ -2385,13 +2466,14 @@ eslint-visitor-keys@^2.0.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
eslint@^7.29.0:
version "7.29.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.29.0.tgz#ee2a7648f2e729485e4d0bd6383ec1deabc8b3c0"
integrity sha512-82G/JToB9qIy/ArBzIWG9xvvwL3R86AlCjtGw+A29OMZDqhTybz/MByORSukGxeI+YPCR4coYyITKk8BFH9nDA==
eslint@^7.30.0:
version "7.30.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.30.0.tgz#6d34ab51aaa56112fd97166226c9a97f505474f8"
integrity sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==
dependencies:
"@babel/code-frame" "7.12.11"
"@eslint/eslintrc" "^0.4.2"
"@humanwhocodes/config-array" "^0.5.0"
ajv "^6.10.0"
chalk "^4.0.0"
cross-spawn "^7.0.2"
@ -2580,6 +2662,17 @@ fast-glob@^3.1.1, fast-glob@^3.2.5:
micromatch "^4.0.2"
picomatch "^2.2.1"
fast-glob@^3.2.6:
version "3.2.6"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.6.tgz#434dd9529845176ea049acc9343e8282765c6e1a"
integrity sha512-GnLuqj/pvQ7pX8/L4J84nijv6sAnlwvSDpMkJi9i7nPmPxGtRPkBSStfvDW5l6nMdX9VWe+pkKWFTgD+vF2QSQ==
dependencies:
"@nodelib/fs.stat" "^2.0.2"
"@nodelib/fs.walk" "^1.2.3"
glob-parent "^5.1.2"
merge2 "^1.3.0"
micromatch "^4.0.4"
fast-json-stable-stringify@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
@ -3191,10 +3284,10 @@ human-signals@^2.1.0:
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
husky@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/husky/-/husky-6.0.0.tgz#810f11869adf51604c32ea577edbc377d7f9319e"
integrity sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ==
husky@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.0.tgz#3dbd5d28e76234689ee29bb41e048f28e3e46616"
integrity sha512-xK7lO0EtSzfFPiw+oQncQVy/XqV7UVVjxBByc+Iv5iK3yhW9boDoWgvZy3OGo48QKg/hUtZkzz0hi2HXa0kn7w==
iconv-lite@^0.4.24:
version "0.4.24"
@ -5982,10 +6075,10 @@ typescript-vscode-sh-plugin@^0.6.14:
resolved "https://registry.yarnpkg.com/typescript-vscode-sh-plugin/-/typescript-vscode-sh-plugin-0.6.14.tgz#a81031b502f6346a26ea49ce082438c3e353bb38"
integrity sha512-AkNlRBbI6K7gk29O92qthNSvc6jjmNQ6isVXoYxkFwPa8D04tIv2SOPd+sd+mNpso4tNdL2gy7nVtrd5yFqvlA==
typescript@^4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.4.tgz#3f85b986945bcf31071decdd96cf8bfa65f9dcbc"
integrity sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==
typescript@^4.3.5:
version "4.3.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4"
integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==
unbox-primitive@^1.0.1:
version "1.0.1"
@ -6233,10 +6326,10 @@ validate-npm-package-license@^3.0.1:
spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0"
vant@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/vant/-/vant-3.1.0.tgz#d8a734caed4df4fb2babe4c3f8930c728151d5ac"
integrity sha512-P4Ko8YXThjOiu3aBbTE9SId9r8VvFPNyABkl5+EabT1nn4UzdultcNMCyEjRiKes00QH5p+kXBi+e+wSDxZEyQ==
vant@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/vant/-/vant-3.1.2.tgz#8777290f38c4b042d22612343e72dcab95b044ed"
integrity sha512-uw+ZKZTD44L2YojenZjRuF/rETR28rnuI7cQ4tFtEJBLKc1TNxsxl3PYmoGbYt7jd5rMrHYST8SkBsbB5i4kNA==
dependencies:
"@vant/icons" "^1.6.0"
"@vant/lazyload" "^1.2.0"
@ -6320,14 +6413,13 @@ vfile@^4.0.0, vfile@^4.0.1:
unist-util-stringify-position "^2.0.0"
vfile-message "^2.0.0"
vite-plugin-components@^0.11.2:
version "0.11.2"
resolved "https://registry.yarnpkg.com/vite-plugin-components/-/vite-plugin-components-0.11.2.tgz#83cd0ebf3388329464ccaf6e259a416492a728a3"
integrity sha512-FfW88iOmOHx1GlGJ2KT3r51Oyu7pntgkMxv7X7WxwPS69lOCWzmDO0n2+TWiWYPDpboDLJsPKBDeSBN1BhTtXQ==
vite-plugin-components@^0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/vite-plugin-components/-/vite-plugin-components-0.12.0.tgz#7a20ba88be63625f759902d670c1310cf7cd9d0b"
integrity sha512-LJAn25KFLFw97mNQw74fsWvGAaaFXbDNGkReFpITPtIrmdRrwWowieg23INXAniPaGJVIhspLk0ippMPi/q0qA==
dependencies:
chokidar "^3.5.1"
debug "^4.3.2"
fast-glob "^3.2.5"
fast-glob "^3.2.6"
magic-string "^0.25.7"
minimatch "^3.0.4"
@ -6342,12 +6434,12 @@ vite-plugin-style-import@^1.0.1:
es-module-lexer "^0.6.0"
magic-string "^0.25.7"
vite-plugin-windicss@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/vite-plugin-windicss/-/vite-plugin-windicss-1.1.1.tgz#c13d4c2d9fec4afae2eea5058f426c693255d02f"
integrity sha512-J1n3DoSg8BkQ42HDNzh+FqPhvBgCRgQ0Nvp2HLvb5FVl8FKEPw26Frc/oLaC1g9ypSlvkSM8011gHi+c+pxsRQ==
vite-plugin-windicss@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/vite-plugin-windicss/-/vite-plugin-windicss-1.2.0.tgz#6b21e76f3aae1cd2f71c548c4bfe8d87b4328ad0"
integrity sha512-3teAmQHCDDDcy7On5fOj1sYTRVo8zAwJJd4SOapeGI7EuEzO2fHy6oDS6sPXVUnstbfoPbvrng1xvc3VAqI+sg==
dependencies:
"@windicss/plugin-utils" "1.1.1"
"@windicss/plugin-utils" "1.2.0"
chalk "^4.1.1"
debug "^4.3.2"
windicss "^3.1.3"
@ -6538,6 +6630,19 @@ vue-eslint-parser@^7.6.0:
esquery "^1.4.0"
lodash "^4.17.15"
vue-eslint-parser@^7.7.2:
version "7.7.2"
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-7.7.2.tgz#a723080b29c27fa0b3737bedceaeebe30fd0f359"
integrity sha512-zkfxSttpwBW9SQEa+rLR+j6sFHGGhanVH3VuzHQwybCQWJsg/Yi1W619gXOW01U/zekN4D+J4/S4Zufd1sClZg==
dependencies:
debug "^4.1.1"
eslint-scope "^5.1.1"
eslint-visitor-keys "^1.1.0"
espree "^6.2.1"
esquery "^1.4.0"
lodash "^4.17.21"
semver "^6.3.0"
vue-router@^4.0.10:
version "4.0.10"
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.0.10.tgz#ec8fda032949b2a31d3273170f8f376e86eb52ac"
@ -6552,14 +6657,14 @@ vue-tsc@^0.2.0:
dependencies:
vscode-vue-languageservice "^0.25.22"
vue@3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.1.2.tgz#647f8e3949a3d600771dca25d50225dc3e594c64"
integrity sha512-q/rbKpb7aofax4ugqu2k/uj7BYuNPcd6Z5/qJtfkJQsE0NkwVoCyeSh7IZGH61hChwYn3CEkh4bHolvUPxlQ+w==
vue@3.1.4:
version "3.1.4"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.1.4.tgz#120d6818c51eaa35d0879e5bc1cff60135bc69fd"
integrity sha512-p8dcdyeCgmaAiZsbLyDkmOLcFGZb/jEVdCLW65V68LRCXTNX8jKsgah2F7OZ/v/Ai2V0Fb1MNO0vz/GFqsPVMA==
dependencies:
"@vue/compiler-dom" "3.1.2"
"@vue/runtime-dom" "3.1.2"
"@vue/shared" "3.1.2"
"@vue/compiler-dom" "3.1.4"
"@vue/runtime-dom" "3.1.4"
"@vue/shared" "3.1.4"
vuedraggable@^4.0.3:
version "4.0.3"
@ -6617,6 +6722,11 @@ windicss@^3.1.3:
resolved "https://registry.yarnpkg.com/windicss/-/windicss-3.1.3.tgz#a4b80af48bdd5d4be13520f700b497af455df700"
integrity sha512-l7fpoba2LY9AYRy4UgcuOpbPsed8UsbpEQYUVWRR1wdAwiKxK6bGIMfpiKJtjPAPdh0GOGUqr6KJar0EDZSxzg==
windicss@^3.1.4:
version "3.1.4"
resolved "https://registry.yarnpkg.com/windicss/-/windicss-3.1.4.tgz#557eaf8e3c08064a309ccb5d887c82c4bce25069"
integrity sha512-3RBcANxdOy/n4dLVT8+0X409sGI+piO06ARbQ8RncxGuYgdw5Ip3hrhGIYajH67lV+tHc7xNVGxj73amOC9N0g==
with@^7.0.0:
version "7.0.2"
resolved "https://registry.yarnpkg.com/with/-/with-7.0.2.tgz#ccee3ad542d25538a7a7a80aad212b9828495bac"