目录
- 低代码之构建框架1
- 1:项目初始化
- 2:src / data.json 数据 ( 容器大小与渲染的表单数据 )
- 3:App.vue ( 导入editor组件传递data.json之中的数据与 向下提供组件配置数据config )
- 4:src / packages / editor.jsx 框架区域样式与组件引入
- 5:editor.scss
- 6:src / packages / editor-block.jsx 子组件
- 7:src / utils / editor.config.jsx 编辑区域的配置文件
- 8:main.js
- 效果
低代码之构建框架1
1:项目初始化
- vue create vue-lesson 初始化项目文件
- npm i 初始化 package.json
- package.json 配置运行脚本
{"name": "vue-lesson","version": "0.1.0","private": true,"scripts": {"serve": "vue-cli-service serve","build": "vue-cli-service build"},"dependencies": {"core-js": "^3.8.3","element-plus": "^2.3.6","vue": "^3.2.13"},"devDependencies": {"@vue/cli-plugin-babel": "~5.0.0","@vue/cli-service": "~5.0.0","sass": "^1.32.7","sass-loader": "^12.0.0"}
}
- 安装依赖
npm i element-plus
2:src / data.json 数据 ( 容器大小与渲染的表单数据 )
{"container":{"width":550,"height":550},"blocks":[{"top":100,"left":100,"zIndex":1,"key":"text"},{"top":200,"left":200,"zIndex":1,"key":"button"},{"top":300,"left":300,"zIndex":1,"key":"input"}]
}
3:App.vue ( 导入editor组件传递data.json之中的数据与 向下提供组件配置数据config )
<template><div class="app"><Editor v-model="state"></Editor></div>
</template><script>
import { provide, ref } from "vue";
import data from "./data.json";
import Editor from "./packages/editor"
import { registerConfig as config } from "./utils/editor.config";
export default {components:{Editor},setup() {const state = ref(data);provide('config',config) return {state,};},
};
</script>
<style lang="scss">
html,body,#app{margin: 0;padding: 0;width: 100%;height: 100%;
}
.app {background: #fff;width: 100%;height: 100%;
}
</style>
4:src / packages / editor.jsx 框架区域样式与组件引入
import { computed, defineComponent ,inject} from "vue";
import "./editor.scss"
import EditorBlock from "./editor-block";
export default defineComponent({props:{modelValue:{type:Object},},setup(props){const data = computed({get () {return props.modelValue}})const contentStyle = computed(()=>({width: data.value.container.width + 'px',height: data.value.container.height + 'px'}))const config = inject('config')return () => <div class='editor'><div class='editor-left'>{}{ config.componetsList.map(component=>(<div class="editor-left-item"><span class="editor-left-item-label">{ component.label }</span><div>{ component.preview() }</div></div>))}</div><div className="editor-center"><div class="editor-top">top</div><div class="editor-content">{}<div class="editor-content-canvas">{}<div class="editor-content-canvas_content" style={contentStyle.value}>{(data.value.blocks.map(block=>(<EditorBlock block={block}></EditorBlock>)))}</div></div></div></div><div class="editor-right">right</div></div>}
})
5:editor.scss
.editor {width: 100%;height: 100%;overflow: hidden;display: flex;.editor-left ,.editor-right{width: 270px;background: yellow;height: 100%;}.editor-left {.editor-left-item {position: relative;width: 250px;margin: 20px auto;display: flex;justify-content: center;align-items: center;background: #ccc;padding: 20px;box-sizing: border-box;cursor: move;user-select: none; min-height: 100px;.editor-left-item-label {position: absolute;left: 0;top: 0;background: rgb(96, 205, 224);color: #fff;padding: 4px;}&::after {content: '';position: absolute;top: 0;left: 0;right: 0;bottom: 0;background: #ccc;opacity: 0.2;}}}.editor-center {width: calc(100% - 270px - 270px - 20px);padding: 0 10px;background: orange;height: 100%;}.editor-top {height: 80px;background: pink;}.editor-content {height: calc(100% - 80px);background: orange;.editor-content-canvas {overflow: scroll;height: 100%;}.editor-content-canvas_content {position: relative;margin: 20px auto;background: #ccc;}}
}
.editor-block {position: absolute;
}
6:src / packages / editor-block.jsx 子组件
import { computed, defineComponent,inject } from "vue";export default defineComponent({props:{block:{type:Object}},setup(props){const blockStyle = computed(()=>({top:`${props.block.top}px`,left: `${props.block.left}px`,zIndex:`${props.block.zIndex}`}))const config = inject('config') return ()=> {const component = config.componetsMap[props.block.key];console.log('component',component);const componentRender = component.render();return <div class="editor-block" style={blockStyle.value}>{componentRender}</div>}}
})
7:src / utils / editor.config.jsx 编辑区域的配置文件
import { ElButton,ElInput } from "element-plus"
function createEditorConfig(){const componetsList = []const componetsMap = {}return {componetsList,componetsMap,register:(component)=>{componetsList.push(component)componetsMap[component.key] = component}}
}export let registerConfig = createEditorConfig()
console.log('registerConfig',registerConfig);
registerConfig.register({label:'文本',preview:()=> '预览文本',render:()=> '渲染文本',key:'text'
})
registerConfig.register({label:'按钮',preview:()=> <ElButton>预览按钮</ElButton>,render:()=> <ElButton>渲染按钮</ElButton>,key:'button'
})
registerConfig.register({label:'输入框',preview:()=> <ElInput placeholder='预览输入框'></ElInput>,render:()=> <ElInput placeholder='渲染输入框'></ElInput>,key:'input'
})
8:main.js
import { createApp } from 'vue'
import App from './App.vue'
import 'element-plus/dist/index.css'createApp(App).mount('#app')
效果