diff --git a/README.EN.md b/README.EN.md index 93ee768..3028721 100644 --- a/README.EN.md +++ b/README.EN.md @@ -8,8 +8,6 @@ ```shell git clone --single-branch https://github.com/buqiyuan/vite-vue3-lowcode.git -# or -git clone --single-branch https://gitee.com/buqiyuan/vite-vue3-lowcode.git ``` ## technology stack @@ -67,6 +65,22 @@ JSON.stringify( ).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(/(? { - const { bgImage, bgColor } = currentPage.config - const bodyStyleStr = ` + if (currentPage?.config) { + const { bgImage, bgColor } = currentPage.config + const bodyStyleStr = ` body { background-color: ${bgColor}; background-image: url(${bgImage}); } ` - document.styleSheets[0].insertRule(bodyStyleStr) + document.styleSheets[0].insertRule(bodyStyleStr) + } }) return { diff --git a/src/packages/base-widgets/datetimePicker/index.tsx b/src/packages/base-widgets/datetimePicker/index.tsx index 463a58e..e79cebc 100644 --- a/src/packages/base-widgets/datetimePicker/index.tsx +++ b/src/packages/base-widgets/datetimePicker/index.tsx @@ -9,7 +9,7 @@ import { createEditorSelectProp, createEditorSwitchProp } from '@/visual-editor/visual-editor.props' -import { getCurrentInstance, reactive } from 'vue' +import { useAttrs, reactive } from 'vue' import { isDate } from '@/visual-editor/utils/is' import dayjs from 'dayjs' @@ -29,7 +29,7 @@ export default { render: ({ styles, block, props }) => { const { registerRef } = useGlobalProperties() - const { attrs } = getCurrentInstance()! + const attrs = useAttrs() const state = reactive({ showPicker: false, diff --git a/src/packages/base-widgets/nav-bar/index.tsx b/src/packages/base-widgets/nav-bar/index.tsx index abe6e4a..e8370fa 100644 --- a/src/packages/base-widgets/nav-bar/index.tsx +++ b/src/packages/base-widgets/nav-bar/index.tsx @@ -1,7 +1,7 @@ /* * @Author: 卜启缘 * @Date: 2021-05-04 05:36:58 - * @LastEditTime: 2021-07-07 10:56:56 + * @LastEditTime: 2021-07-11 16:36:05 * @LastEditors: 卜启缘 * @Description: 导航栏 * @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\nav-bar\index.tsx @@ -19,23 +19,37 @@ export default { preview: () => ( ), - render: ({ props, styles, block, custom }) => { + render: ({ props, block }) => { const { registerRef } = useGlobalProperties() - return ( -
- registerRef(el, block._vid)} placeholder {...custom} {...props} /> -
- ) + setTimeout(() => { + const compEl = window.$$refs[block._vid]?.$el + const draggableEl = compEl?.closest('div[data-draggable]') + const navbarEl = draggableEl?.querySelector('.van-nav-bar--fixed') as HTMLDivElement + if (draggableEl && navbarEl) { + navbarEl.style.position = 'unset' + draggableEl.style.top = '0' + draggableEl.style.left = '0' + draggableEl.style.width = '100%' + } else { + const slotEl = compEl?.closest('__slot-item') + if (slotEl) { + slotEl.style.position = 'fixed' + slotEl.style.bottom = '0' + } + } + }) + + return registerRef(el, block._vid)} placeholder {...props} /> }, props: { title: createEditorInputProp({ label: '标题', defaultValue: '标题' }), fixed: createEditorSwitchProp({ label: '是否固定', defaultValue: true }), - placeholder: createEditorSwitchProp({ - label: '是否生成占位元素', - defaultValue: true, - tips: '固定在顶部时,是否在标签位置生成一个等高的占位元素' - }), + // placeholder: createEditorSwitchProp({ + // label: '是否生成占位元素', + // defaultValue: true, + // tips: '固定在顶部时,是否在标签位置生成一个等高的占位元素' + // }), zIndex: createEditorInputProp({ label: 'z-index' }), border: createEditorSwitchProp({ label: '是否显示下边框', defaultValue: false }), leftText: createEditorInputProp({ label: '左侧文案', defaultValue: '返回' }), @@ -46,6 +60,8 @@ export default { { label: '点击左侧按钮时触发', value: 'click-left' }, { label: '点击右侧按钮时触发', value: 'click-right' } ], + showStyleConfig: false, + draggable: false, resize: { width: true } diff --git a/src/packages/base-widgets/picker/index.tsx b/src/packages/base-widgets/picker/index.tsx index d5701bf..1bd6c71 100644 --- a/src/packages/base-widgets/picker/index.tsx +++ b/src/packages/base-widgets/picker/index.tsx @@ -1,7 +1,7 @@ /* * @Author: 卜启缘 * @Date: 2021-06-01 09:45:21 - * @LastEditTime: 2021-07-07 10:57:41 + * @LastEditTime: 2021-07-08 15:15:52 * @LastEditors: 卜启缘 * @Description: 表单项类型 - 选择器 * @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\picker\index.tsx @@ -15,7 +15,7 @@ import { createEditorInputProp, createEditorModelBindProp } from '@/visual-editor/visual-editor.props' -import { reactive, getCurrentInstance } from 'vue' +import { reactive, useAttrs } from 'vue' export default { key: 'picker', @@ -25,7 +25,7 @@ export default { render: ({ styles, block, props }) => { const { registerRef } = useGlobalProperties() - const { attrs } = getCurrentInstance()! + const attrs = useAttrs() const state = reactive({ showPicker: false, diff --git a/src/packages/base-widgets/swipe/index.tsx b/src/packages/base-widgets/swipe/index.tsx index 4373bc3..75fa2cc 100644 --- a/src/packages/base-widgets/swipe/index.tsx +++ b/src/packages/base-widgets/swipe/index.tsx @@ -1,7 +1,7 @@ /* * @Author: 卜启缘 * @Date: 2021-06-14 12:24:12 - * @LastEditTime: 2021-07-07 11:01:14 + * @LastEditTime: 2021-07-11 16:43:31 * @LastEditors: 卜启缘 * @Description: 轮播图组件 * @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\swipe\index.tsx @@ -29,11 +29,11 @@ export default { 4 ), - render: ({ block, props, styles }) => { + render: ({ block, props }) => { const { registerRef } = useGlobalProperties() return ( -
+
registerRef(el, block._vid)} {...props} @@ -52,6 +52,7 @@ export default { }, props: createFieldProps(), events: [{ label: '每一页轮播结束后触发', value: 'change' }], + showStyleConfig: false, resize: { width: true }, diff --git a/src/packages/base-widgets/tabbar/index.tsx b/src/packages/base-widgets/tabbar/index.tsx new file mode 100644 index 0000000..8b74973 --- /dev/null +++ b/src/packages/base-widgets/tabbar/index.tsx @@ -0,0 +1,116 @@ +/* + * @Author: 卜启缘 + * @Date: 2021-05-04 05:36:58 + * @LastEditTime: 2021-07-11 22:38:54 + * @LastEditors: 卜启缘 + * @Description: 导航栏 + * @FilePath: \vite-vue3-lowcode\src\packages\base-widgets\tabbar\index.tsx + */ +import { Tabbar, TabbarItem } from 'vant' +import type { VisualEditorComponent } from '@/visual-editor/visual-editor.utils' +import { + createEditorCrossSortableProp, + createEditorInputProp, + createEditorSwitchProp, + createEditorColorProp +} from '@/visual-editor/visual-editor.props' +import { useGlobalProperties } from '@/hooks/useGlobalProperties' +import tabbarItem from './tabbar-item' +import { createNewBlock } from '@/visual-editor/visual-editor.utils' +import { BASE_URL } from '@/visual-editor/utils' + +export default { + key: 'tabbar', + moduleName: 'baseWidgets', + label: '底部标签栏', + preview: () => ( + + 首页 + 导航 + 我的 + + ), + render: ({ props, block }) => { + const { registerRef } = useGlobalProperties() + + setTimeout(() => { + const compEl = window.$$refs[block._vid]?.$el + const draggableEl = compEl?.closest('div[data-draggable]') + const tabbarEl = draggableEl?.querySelector('.van-tabbar') as HTMLDivElement + if (draggableEl && tabbarEl) { + tabbarEl.style.position = 'unset' + draggableEl.style.position = 'fixed' + draggableEl.style.bottom = '0' + draggableEl.style.left = '0' + draggableEl.style.width = '100%' + draggableEl.style.zIndex = '1000' + } else { + document.body.style.paddingBottom = '50px' + const slotEl = compEl?.closest('__slot-item') + if (slotEl) { + slotEl.style.position = 'fixed' + slotEl.style.bottom = '0' + } + } + }) + + return ( + registerRef(el, block._vid)} v-model={props.modelValue} {...props}> + {props.tabs?.map((item) => { + const itemProps = item.block?.props + const url = `${BASE_URL}${props.baseUrl}${itemProps.url}`.replace(/\/{2,}/g, '/') + return ( + + {item.label} + + ) + })} + + ) + }, + props: { + modelValue: createEditorInputProp({ + label: '当前选中标签的名称或索引值', + defaultValue: '' + }), + tabs: createEditorCrossSortableProp({ + label: '默认选项', + labelPosition: 'top', + multiple: false, + showItemPropsConfig: true, + defaultValue: [ + { label: '首页', value: 'index', component: tabbarItem, block: createNewBlock(tabbarItem) }, + { + label: '导航', + value: 'navigation', + component: tabbarItem, + block: createNewBlock(tabbarItem) + }, + { label: '我的', value: 'user', component: tabbarItem, block: createNewBlock(tabbarItem) } + ] + }), + fixed: createEditorSwitchProp({ label: '是否固定在底部', defaultValue: true }), + border: createEditorSwitchProp({ label: '是否显示外边框', defaultValue: true }), + zIndex: createEditorInputProp({ label: '元素 z-index', defaultValue: '1' }), + baseUrl: createEditorInputProp({ label: '路由路径前缀', defaultValue: '/preview/#/' }), + activeColor: createEditorColorProp({ label: '选中标签的颜色', defaultValue: '#1989fa' }), + inactiveColor: createEditorColorProp({ label: '未选中标签的颜色', defaultValue: '#7d7e80' }), + route: createEditorSwitchProp({ label: '是否开启路由模式', defaultValue: false }), + // placeholder: createEditorSwitchProp({ + // label: '固定在底部时,是否在标签位置生成一个等高的占位元素', + // defaultValue: true + // }), + safeAreaInsetBottom: createEditorSwitchProp({ + label: '是否开启底部安全区适配,设置 fixed 时默认开启', + defaultValue: false + }) + }, + events: [ + { label: '点击左侧按钮时触发', value: 'click-left' }, + { label: '点击右侧按钮时触发', value: 'click-right' } + ], + draggable: false, + resize: { + width: true + } +} as VisualEditorComponent diff --git a/src/packages/base-widgets/tabbar/tabbar-item.tsx b/src/packages/base-widgets/tabbar/tabbar-item.tsx new file mode 100644 index 0000000..0fc68f1 --- /dev/null +++ b/src/packages/base-widgets/tabbar/tabbar-item.tsx @@ -0,0 +1,47 @@ +/* + * @Author: 卜启缘 + * @Date: 2021-05-04 05:36:58 + * @LastEditTime: 2021-07-11 19:58:14 + * @LastEditors: 卜启缘 + * @Description: 导航栏项 + * @FilePath: \vite-vue3-lowcode\src\packages\container-component\tabbar\tabbar-item.tsx + */ +import type { VisualEditorComponent } from '@/visual-editor/visual-editor.utils' +import { createEditorInputProp, createEditorSwitchProp } from '@/visual-editor/visual-editor.props' + +export default { + key: 'tabbar-item', + moduleName: 'baseWidgets', + label: '底部标签栏', + preview: () => <>, + render: () => <>, + props: { + // name: createEditorInputProp({ + // label: '标签名称,作为匹配的标识符', + // defaultValue: '当前标签的索引值' + // }), + icon: createEditorInputProp({ label: '图标名称或图片链接', defaultValue: 'home-o' }), + iconPrefix: createEditorInputProp({ + label: '图标类名前缀', + tips: '图标类名前缀,同 Icon 组件的 class-prefix 属性', + defaultValue: 'van-icon' + }), + dot: createEditorSwitchProp({ label: '是否显示图标右上角小红点', defaultValue: false }), + badge: createEditorInputProp({ label: '图标右上角徽标的内容', defaultValue: '' }), + url: createEditorInputProp({ label: '点击后跳转的链接地址', defaultValue: '' }), + // to: createEditorInputProp({ + // label: '点击后跳转的目标路由对象', + // tips: '点击后跳转的目标路由对象,同 vue-router 的 to 属性', + // defaultValue: '' + // }), + replace: createEditorSwitchProp({ label: '是否在跳转时替换当前页面历史', defaultValue: false }) + }, + events: [ + { label: '点击左侧按钮时触发', value: 'click-left' }, + { label: '点击右侧按钮时触发', value: 'click-right' } + ], + draggable: false, + resize: { + width: true + } +} as VisualEditorComponent diff --git a/src/packages/container-component/form/index.tsx b/src/packages/container-component/form/index.tsx index 15e35ef..7b0b3ac 100644 --- a/src/packages/container-component/form/index.tsx +++ b/src/packages/container-component/form/index.tsx @@ -1,13 +1,13 @@ /* * @Author: 卜启缘 * @Date: 2021-06-01 09:45:21 - * @LastEditTime: 2021-07-07 21:23:23 + * @LastEditTime: 2021-07-08 15:13:02 * @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 { renderSlot, useSlots } from 'vue' import type { VisualEditorComponent } from '@/visual-editor/visual-editor.utils' import { useGlobalProperties } from '@/hooks/useGlobalProperties' import { compProps } from './compProps' @@ -28,7 +28,7 @@ export default { ), render: function ({ props, styles, block }) { - const { slots } = getCurrentInstance()! + const slots = useSlots() const { registerRef } = useGlobalProperties() const onSubmit = (values) => { diff --git a/src/packages/container-component/layout/index.tsx b/src/packages/container-component/layout/index.tsx index 77ef8f6..5b5c596 100644 --- a/src/packages/container-component/layout/index.tsx +++ b/src/packages/container-component/layout/index.tsx @@ -1,5 +1,5 @@ import { Col, Row } from 'vant' -import { renderSlot, getCurrentInstance } from 'vue' +import { renderSlot, useSlots } from 'vue' import { createEditorInputProp, createEditorSelectProp } from '@/visual-editor/visual-editor.props' import type { VisualEditorComponent } from '@/visual-editor/visual-editor.utils' import styleModule from './index.module.scss' @@ -36,8 +36,8 @@ export default { span: 8 ), - render: function ({ props, styles, block, custom }) { - const { slots } = getCurrentInstance()! + render: ({ props, styles, block, custom }) => { + const slots = useSlots() const { registerRef } = useGlobalProperties() slotsTemp[block._vid] ??= {} diff --git a/src/shims-vue.d.ts b/src/shims-vue.d.ts deleted file mode 100644 index 46391fd..0000000 --- a/src/shims-vue.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -type RequestIdleCallbackHandle = any -type RequestIdleCallbackOptions = { - timeout: number -} -type RequestIdleCallbackDeadline = { - readonly didTimeout: boolean - timeRemaining: () => number -} - -declare interface Window { - $$refs: any - requestIdleCallback: ( - callback: (deadline: RequestIdleCallbackDeadline) => void, - opts?: RequestIdleCallbackOptions - ) => RequestIdleCallbackHandle - cancelIdleCallback: (handle: RequestIdleCallbackHandle) => void -} - -// declare module '*.vue' { -// import { DefineComponent } from 'vue' -// -// const component: DefineComponent<{}, {}, any> -// export default component -// } - -// declare module '*.module.scss' - -declare module '*.vue' { - import { ComponentOptions } from 'vue' - const component: ComponentOptions - export default component -} diff --git a/src/visual-editor/components/header/preview.vue b/src/visual-editor/components/header/preview.vue index 7446d35..22daa99 100644 --- a/src/visual-editor/components/header/preview.vue +++ b/src/visual-editor/components/header/preview.vue @@ -2,7 +2,7 @@