update:增加内容编辑区
This commit is contained in:
parent
1c3e71dc49
commit
4384b16ba9
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
自定义组件插件化,提供对外的按需加载
|
||||
处理插件的入口
|
||||
*/
|
||||
|
||||
import Text from './text'
|
||||
|
||||
const components = [
|
||||
Text
|
||||
]
|
||||
// 定义全局变量
|
||||
const rigester_component = {}
|
||||
components.forEach(item => {
|
||||
rigester_component[item.name] = item
|
||||
})
|
||||
|
||||
export {
|
||||
rigester_component
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
// 注册install 方法可以实现插件引用
|
||||
|
||||
import Component from './src/index'
|
||||
Component.install = Vue => {
|
||||
Vue.component(Component.name, Component)
|
||||
}
|
||||
|
||||
export default Component
|
|
@ -0,0 +1,28 @@
|
|||
<template>
|
||||
<div class="qa-text">
|
||||
{{ text }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'QaText',
|
||||
props: {
|
||||
text: {
|
||||
type: String,
|
||||
default: '用来输入文字'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
defaultStyle: {
|
||||
height: 40
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
const getters = {
|
||||
sidebar: state => state.app.sidebar,
|
||||
size: state => state.app.size,
|
||||
|
@ -10,7 +11,6 @@ const getters = {
|
|||
introduction: state => state.user.introduction,
|
||||
roles: state => state.user.roles,
|
||||
permission_routes: state => state.permission.routes,
|
||||
errorLogs: state => state.errorLog.logs,
|
||||
pageMode: state => state.editor.pageMode
|
||||
errorLogs: state => state.errorLog.logs
|
||||
}
|
||||
export default getters
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import editorProjectConfig from '@/views/h5/ele-config'
|
||||
/*
|
||||
新建/编辑页面数据
|
||||
|
||||
|
@ -5,10 +6,57 @@
|
|||
const state = {
|
||||
projectData: {
|
||||
pageMode: ''
|
||||
},
|
||||
activePageUUID: '', // 正在编辑页面的uuid
|
||||
activeElementUUID: '' // 选中元素的uuid
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
/*
|
||||
画板添加元素
|
||||
|
||||
*/
|
||||
addElement(state, elData) {
|
||||
// 找到当前活动页
|
||||
const index = state.projectData.pages.findIndex(item => { return item.uuid === state.activePageUUID })
|
||||
state.projectData.pages[index].elements.push(elData)
|
||||
}
|
||||
}
|
||||
|
||||
const actions = {
|
||||
/*
|
||||
添加组件元素
|
||||
*/
|
||||
addElement({ commit }, elData) {
|
||||
const activePage = getters.activePage(state)
|
||||
// 每添加一个元素,获取其数据模型并修改层叠属性
|
||||
// 数据模型 是基于基础模版和元素具体类型
|
||||
const data = editorProjectConfig.getElementConfig(elData, { zIndex: activePage.elements.length + 1 })
|
||||
commit('addElement', data)
|
||||
// commit('setActiveElementUUID', data.uuid)
|
||||
// commit('addHistoryCache')
|
||||
}
|
||||
}
|
||||
|
||||
const getters = {
|
||||
// 当前选中的页面
|
||||
activePage: state => {
|
||||
if (!state.projectData.pages || !state.activePageUUID) {
|
||||
return {
|
||||
commonStyle: {},
|
||||
config: {}
|
||||
}
|
||||
}
|
||||
return state.projectData.pages.find(item => { item.uuid === state.activePageUUID })
|
||||
},
|
||||
// 当前页面模式
|
||||
pageMode: state => state.projectData.pageMode
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state
|
||||
state,
|
||||
getters,
|
||||
actions,
|
||||
mutations
|
||||
}
|
||||
|
|
|
@ -345,3 +345,20 @@ export function removeClass(ele, cls) {
|
|||
ele.className = ele.className.replace(reg, ' ')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@returns {String}
|
||||
生成uuid随机数
|
||||
*/
|
||||
export function createUUID() {
|
||||
var d = new Date().getTime()
|
||||
if (window.performance && typeof window.performance.now === 'function') {
|
||||
d += performance.now() // use high-precision timer if available
|
||||
}
|
||||
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
var r = (d + Math.random() * 16) % 16 | 0
|
||||
d = Math.floor(d / 16)
|
||||
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16)
|
||||
})
|
||||
return uuid
|
||||
}
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
设计页面的数据结构
|
||||
单个组件元素
|
||||
单个页面
|
||||
单个项目
|
||||
*/
|
||||
|
||||
import createUUID from '@/utils/index.js'
|
||||
|
||||
const elementConfig = {
|
||||
elName: '',
|
||||
animations: [],
|
||||
// 对于一个元素会关注哪些定位属性
|
||||
commonStyle: {
|
||||
position: 'absolute',
|
||||
width: 30,
|
||||
height: 30,
|
||||
top: 200,
|
||||
left: 0,
|
||||
rotate: 0,
|
||||
paddingTop: 0,
|
||||
paddingLeft: 0,
|
||||
paddingRight: 0,
|
||||
paddingBottom: 0,
|
||||
marginTop: 0,
|
||||
marginLeft: 0,
|
||||
marginRight: 0,
|
||||
marginBottom: 0,
|
||||
borderWidth: 0,
|
||||
borderColor: '',
|
||||
borderStyle: 'solid',
|
||||
borderRadius: 0,
|
||||
boxShadow: '',
|
||||
fontSize: 16,
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.4,
|
||||
letterSpacing: 0,
|
||||
textAlign: 'center',
|
||||
color: '#000000',
|
||||
backgroundColor: '',
|
||||
backgroundImage: '',
|
||||
backgroundSize: 'cover',
|
||||
opacity: 1,
|
||||
zIndex: 1
|
||||
},
|
||||
events: [],
|
||||
propsValue: {} // 组件绑定属性
|
||||
}
|
||||
|
||||
const pageConfig = {
|
||||
name: '',
|
||||
elements: [],
|
||||
commonStyle: {
|
||||
backgroundColor: '',
|
||||
backgroundImage: '',
|
||||
backgroundSize: 'cover'
|
||||
},
|
||||
config: {}
|
||||
}
|
||||
|
||||
const projectConfig = {
|
||||
name: '',
|
||||
title: 'ccccc',
|
||||
description: '',
|
||||
coverImage: '',
|
||||
author: '',
|
||||
pages: [],
|
||||
script: '',
|
||||
width: 200,
|
||||
height: 200
|
||||
}
|
||||
|
||||
// 获取组件的数据对象
|
||||
const getElementConfig = function(element, extendStyle = {}) {
|
||||
const elementData = JSON.parse(JSON.stringify(element))
|
||||
// const type = elementData.valueType || 'String'
|
||||
// 字典类型
|
||||
// const dict = {
|
||||
// 'String': '',
|
||||
// 'Array': [],
|
||||
// 'Object': {},
|
||||
// 'Boolean': false,
|
||||
// 'Number': 0
|
||||
// }
|
||||
// 复制数据模版
|
||||
const elementConfigData = JSON.parse(JSON.stringify(elementConfig))
|
||||
// 在通用配置上根据组件名具体添加
|
||||
const config = {
|
||||
uuid: createUUID(),
|
||||
...elementConfigData,
|
||||
elName: elementData.elName,
|
||||
propsvalue: JSON.parse(JSON.stringify(elementData.needProps))
|
||||
}
|
||||
// 处理样式
|
||||
// 样式来源有三种,可以实现松耦合,模版样式 | 组件自定义样式 | 拓展样式
|
||||
config.commonStyle = Object.assign({}, config.commonStyle, elementData.defaultStyle, extendStyle)
|
||||
// value,valueType暂时不知用处
|
||||
config.isForm = !!element.isForm
|
||||
return config
|
||||
}
|
||||
|
||||
export default {
|
||||
elementConfig,
|
||||
pageConfig,
|
||||
projectConfig,
|
||||
getElementConfig
|
||||
}
|
|
@ -23,7 +23,14 @@
|
|||
|
||||
<el-col :span="9">
|
||||
<!-- 内容编辑区 -->
|
||||
<div class="edit-content" />
|
||||
<div class="edit-content">
|
||||
<!-- 顶部控制条 -->
|
||||
<div class="controll-bar" />
|
||||
|
||||
<div class="edit-content-area">
|
||||
<editorPan />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="7">
|
||||
|
@ -40,11 +47,13 @@
|
|||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import componentLibs from './components/component-libs.vue'
|
||||
import componentLibs from './components/component-libs.vue' // 组件选择区域
|
||||
import editorPan from './components/editor-panel.vue' // 核心操作区域
|
||||
|
||||
export default {
|
||||
components: {
|
||||
componentLibs
|
||||
componentLibs,
|
||||
editorPan
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
<div class="component-libs-wrapper">
|
||||
<p class="page-title">组件库</p>
|
||||
<el-scrollbar>
|
||||
<ul class="scrollbar-wrapper">
|
||||
<li v-for="(item, index) in componentsList" :key="index">
|
||||
<div class="scrollbar-wrapper">
|
||||
<div v-for="(item, index) in componentsList" :key="index">
|
||||
<!-- 二级标题 -->
|
||||
<div class="components-libs-title">
|
||||
<p>{{ item.title }}</p>
|
||||
|
@ -21,14 +21,16 @@
|
|||
<p class="lib-item-title">{{ ele.title }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div v-else>待完善。。。</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import eleConfig from '../ele-config'
|
||||
import { rigester_component } from '@/plugin/index'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
@ -39,8 +41,19 @@ export default {
|
|||
console.log('ll;', this.componentsList)
|
||||
},
|
||||
methods: {
|
||||
handleItemClick() {
|
||||
|
||||
handleItemClick(obj) {
|
||||
// 获取组件属性
|
||||
const props = this.getComponentProps(obj.elName)
|
||||
// 触发数据更新
|
||||
this.$store.dispatch('addElement', { ...obj, needProps: props })
|
||||
},
|
||||
/*
|
||||
根据组件名判断需要添加的属性props,这个在自定义组件中已经定义了,目前取出即可
|
||||
一个组件其实就是一个obj
|
||||
*/
|
||||
getComponentProps(elName) {
|
||||
const elComponentData = rigester_component[elName] || ''
|
||||
if (!elComponentData) return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,21 +61,29 @@ export default {
|
|||
|
||||
<style lang="scss">
|
||||
.component-libs-wrapper {
|
||||
height: 700px;
|
||||
.page-title {
|
||||
text-align: center;
|
||||
}
|
||||
.scrollbar-wrapper {
|
||||
height: 600px;
|
||||
height: 700px;
|
||||
.item-wrapper {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
justify-content: start;
|
||||
flex-flow: wrap;
|
||||
.component-item {
|
||||
background-color: gray;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border: 1px solid white;
|
||||
text-align: center;
|
||||
margin-left: 15px;
|
||||
margin-top: 10px;
|
||||
transition: all 0.3s;
|
||||
&:hover {
|
||||
border-color: aqua;
|
||||
background-color: white;
|
||||
color: aqua;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<template>
|
||||
<div class="edit-area-wrapper">
|
||||
<div class="edit-area-inner">
|
||||
<!-- 用来控制展示区缩放 -->
|
||||
<div class="edit-main" :style="{width: projectData.width + 'px', height: projectData.height + 'px', transform: 'scale('+scale+')'}">
|
||||
<div class="page-preview-wrapper">
|
||||
<!-- 提供一个容器组件,包裹选中的组件 -->
|
||||
<edit-shape
|
||||
v-for="item in activePage.elements"
|
||||
:key="item.uuid"
|
||||
>
|
||||
<!-- 用动态组件来渲染 -->
|
||||
<component :is="item.elName" class="ele-edit-pane" />
|
||||
</edit-shape>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
scale: 1
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
projectData: state => state.editor.projectData,
|
||||
activePageUUID: state => state.editor.activePageUUID,
|
||||
activeElementUUID: state => state.editor.activeElementUUID
|
||||
}),
|
||||
...mapGetters([
|
||||
'activePage'
|
||||
])
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
有关组件的一些配置文件,也可以写到数据库从接口来取
|
||||
这里是组件的通用描述,具体信息会在datamodel里被再次修改
|
||||
*/
|
||||
export default [
|
||||
{
|
||||
|
@ -8,7 +9,7 @@ export default [
|
|||
{
|
||||
elName: 'qk-text',
|
||||
title: '文字',
|
||||
icon: 'iconfont iconwenben',
|
||||
icon: 'el-icon-edit',
|
||||
// 每个组件设置props来展示哪些显示哪些编辑项
|
||||
valueType: '', // 标识数据类型,用于表单组件
|
||||
defaultStyle: {
|
||||
|
|
Loading…
Reference in New Issue