您现在的位置是:首页 >技术交流 >低代码01之构建项目框架网站首页技术交流
低代码01之构建项目框架
简介低代码01之构建项目框架
目录
低代码之构建框架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){
// console.log('props',props.modelValue);
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的注册列表 渲染出左侧的物料区域 */}
{
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;
}
// 设置 item 项目不可点击等
&::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;
// height: calc(100% - 40px);
// width: 550px;
// height: 550px;
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') // 获取从app.vue 提供的组件配置
return ()=> {
// 通过block之中的key 获取config之中对应的组件
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 编辑区域的配置文件
// 列表区可以显示所有的物料
// key对应的组件隐射关系
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'
})
// echarts等
8:main.js
import { createApp } from 'vue'
import App from './App.vue'
import 'element-plus/dist/index.css'
createApp(App).mount('#app')
效果
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。