parent
71ea3834da
commit
152495d379
@ -0,0 +1,50 @@ |
|||||||
|
// Nie 2023/2/8 元素添加迭代递归渲染 |
||||||
|
|
||||||
|
import {useEffect, useState} from "react"; |
||||||
|
import css from './index.module.scss'; |
||||||
|
import {defaultStore} from "@/store/index.js"; |
||||||
|
|
||||||
|
export default function Atom(props) { |
||||||
|
const AtomList = props.AtomList; |
||||||
|
const [boxState, setBoxState] = useState(new Array(AtomList.length).fill(false)); |
||||||
|
// 打开关闭标签 |
||||||
|
function handleChangeBoxState(index){ |
||||||
|
const temporaryState = new Array(boxState.length).fill(false); |
||||||
|
if(!boxState[index]){ |
||||||
|
temporaryState[index] = true; |
||||||
|
} |
||||||
|
setBoxState(temporaryState) |
||||||
|
} |
||||||
|
// 添加元素 |
||||||
|
function handleAddElement(item){ |
||||||
|
defaultStore.setNewElementIdentify(item.identify) |
||||||
|
} |
||||||
|
useEffect(() => { |
||||||
|
if(props.state){ |
||||||
|
setBoxState(new Array(boxState.length).fill(false)) |
||||||
|
} |
||||||
|
}, [props.state]) |
||||||
|
return AtomList.map((item, index) => { |
||||||
|
if (item.children && Array.isArray(item.children)) { |
||||||
|
return <div key={index} className={css.atomBox}> |
||||||
|
<div className={css.atomTitle} onClick={() => handleChangeBoxState(index)}>{item.name}</div> |
||||||
|
<div className={boxState[index] ? [css.atomSon, css.atomBoxOpen].join(' ') : css.atomSon}> |
||||||
|
<div className={css.atomDescribe}>{item.describe}</div> |
||||||
|
<div>{Atom({AtomList: item.children, state: boxState[index]})}</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
} else { |
||||||
|
return <div key={index} className={css.atomBox}> |
||||||
|
<div className={css.atomTitle}> |
||||||
|
<div className={css.text} onClick={() => handleChangeBoxState(index)}>{item.name}</div> |
||||||
|
<div className={css.cmd}> |
||||||
|
<div onClick={() => handleAddElement(item)}>+</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className={boxState[index] ? [css.atomSon, css.atomBoxOpen].join(' ') : css.atomSon}> |
||||||
|
<div className={css.atomDescribe}>{item.describe}</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
@ -0,0 +1,84 @@ |
|||||||
|
@import '@/assets/default.scss'; |
||||||
|
|
||||||
|
$open: open; |
||||||
|
$close: close; |
||||||
|
|
||||||
|
.atomBox { |
||||||
|
position: relative; |
||||||
|
margin: 0.5rem 0; |
||||||
|
padding-left: 0.5rem; |
||||||
|
|
||||||
|
|
||||||
|
.atomTitle { |
||||||
|
@include font-serif; |
||||||
|
font-weight: 600; |
||||||
|
cursor: pointer; |
||||||
|
display: flex; |
||||||
|
|
||||||
|
& > div.text { |
||||||
|
position: relative; |
||||||
|
white-space: nowrap; |
||||||
|
flex: 1; |
||||||
|
} |
||||||
|
|
||||||
|
& > div.cmd { |
||||||
|
position: relative; |
||||||
|
flex-shrink: 0; |
||||||
|
width: 40px; |
||||||
|
@include font-mono; |
||||||
|
font-size: 30px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.atomSon { |
||||||
|
position: relative; |
||||||
|
overflow: hidden; |
||||||
|
//padding: 1rem 0; |
||||||
|
box-sizing: border-box; |
||||||
|
max-height: 0; |
||||||
|
animation: close linear 300ms; |
||||||
|
|
||||||
|
& > div.atomDescribe { |
||||||
|
position: relative; |
||||||
|
white-space: nowrap; |
||||||
|
font-size: 14px; |
||||||
|
padding-left: 1.2rem; |
||||||
|
color: #666; |
||||||
|
|
||||||
|
&:before { |
||||||
|
content: ""; |
||||||
|
position: absolute; |
||||||
|
left: 0.7rem; |
||||||
|
width: 0.3rem; |
||||||
|
height: 100%; |
||||||
|
background: #1a1a1a; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.atomBoxOpen { |
||||||
|
animation: open ease-in-out 300ms forwards; |
||||||
|
|
||||||
|
&:hover { |
||||||
|
overflow: overlay; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@keyframes open { |
||||||
|
from { |
||||||
|
max-height: 0; |
||||||
|
} |
||||||
|
to { |
||||||
|
max-height: 300px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@keyframes close { |
||||||
|
to { |
||||||
|
max-height: 0; |
||||||
|
} |
||||||
|
from { |
||||||
|
max-height: 300px; |
||||||
|
} |
||||||
|
} |
@ -1,4 +1,7 @@ |
|||||||
import icon from '../assets/react.svg' |
import icon from '../assets/react.svg' |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const config = { |
export const config = { |
||||||
projectName:'西安升帮联创技术服务有限公司', |
projectName:'西安升帮联创技术服务有限公司', |
||||||
icon, |
icon, |
||||||
|
@ -0,0 +1,230 @@ |
|||||||
|
// 从元素模板中获取指定元素
|
||||||
|
export function getTargetElement(identify, AtomTemplate){ |
||||||
|
let element = null; |
||||||
|
for(let i in AtomTemplate){ |
||||||
|
if(AtomTemplate[i].identify == identify){ |
||||||
|
element = AtomTemplate[i]; |
||||||
|
break |
||||||
|
}else if(Array.isArray(AtomTemplate[i].children)){ |
||||||
|
const s = getTargetElement(identify, AtomTemplate[i].children); |
||||||
|
if(s) element = s |
||||||
|
} |
||||||
|
} |
||||||
|
return element |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
// 框架基础属性
|
||||||
|
const style1 = [ |
||||||
|
'background', |
||||||
|
'backdrop-filter', |
||||||
|
'position', |
||||||
|
'top', |
||||||
|
'bottom', |
||||||
|
'left', |
||||||
|
'right', |
||||||
|
'width', |
||||||
|
'height', |
||||||
|
'margin', |
||||||
|
'padding', |
||||||
|
'border', |
||||||
|
'border-radius', |
||||||
|
'href',// 跳转
|
||||||
|
'overflow', |
||||||
|
'全剧中', |
||||||
|
] |
||||||
|
// 文字属性
|
||||||
|
const style2 = [ |
||||||
|
'color', 'font-size', 'font-weight', '是否换行', '下划线', '首行缩进', 'line-height', 'text-align' |
||||||
|
] |
||||||
|
|
||||||
|
|
||||||
|
// 元素原型
|
||||||
|
export class NE { |
||||||
|
constructor() { |
||||||
|
return [ |
||||||
|
{ |
||||||
|
name: '框架',// 元素名称
|
||||||
|
// dir:true,// 是否为叶子节点
|
||||||
|
describe: "此类元素为页面提供骨架",// 描述
|
||||||
|
identify: 'frame',// 标识
|
||||||
|
config: {}, |
||||||
|
depth: '', |
||||||
|
children: [ |
||||||
|
{ |
||||||
|
name: '单元素结构',// 元素名称
|
||||||
|
// dir:true,// 是否为叶子节点
|
||||||
|
describe: "此结构仅可容纳一个子元素",// 描述
|
||||||
|
identify: 'singleFrame',// 标识
|
||||||
|
config: { |
||||||
|
childrenLength: 1, |
||||||
|
childrenType: 'element', |
||||||
|
middle: '中间件', |
||||||
|
style: [...style1], |
||||||
|
styleLimit: {}, |
||||||
|
event: {} |
||||||
|
}, |
||||||
|
depth: '', |
||||||
|
childElement: [] |
||||||
|
}, { |
||||||
|
name: '横向多元素结构',// 元素名称
|
||||||
|
// dir:true,// 是否为叶子节点
|
||||||
|
describe: "此结构可在横向上排列多个子元素",// 描述
|
||||||
|
identify: 'transverseFrame',// 标识
|
||||||
|
config: { |
||||||
|
childrenLength: 'n', |
||||||
|
childrenType: 'element', |
||||||
|
middle: '中间件', |
||||||
|
style: [...style1, 'flex'], |
||||||
|
styleLimit: {}, |
||||||
|
event: {} |
||||||
|
}, |
||||||
|
depth: '', |
||||||
|
childElement: [] |
||||||
|
}, { |
||||||
|
name: '纵向多元素结构',// 元素名称
|
||||||
|
// dir:true,// 是否为叶子节点
|
||||||
|
describe: "此结构可在纵向上排列多个子元素",// 描述
|
||||||
|
identify: 'longitudinalFrame',// 标识
|
||||||
|
config: { |
||||||
|
childrenLength: 'n', |
||||||
|
childrenType: 'element', |
||||||
|
middle: '中间件', |
||||||
|
style: [...style1, 'flex'], |
||||||
|
styleLimit: {}, |
||||||
|
event: {} |
||||||
|
}, |
||||||
|
depth: '', |
||||||
|
childElement: [] |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: '内元素',// 元素名称
|
||||||
|
// dir:true,// 是否为叶子节点
|
||||||
|
describe: "",// 描述
|
||||||
|
identify: 'innerElement',// 标识
|
||||||
|
config: {}, |
||||||
|
depth: '', |
||||||
|
children: [ |
||||||
|
{ |
||||||
|
name: '行内文本',// 元素名称
|
||||||
|
// dir:true,// 是否为叶子节点
|
||||||
|
describe: "",// 描述
|
||||||
|
identify: 'span',// 标识
|
||||||
|
config: { |
||||||
|
childrenType: 'text', |
||||||
|
middle: '中间件', |
||||||
|
style: [...style2], |
||||||
|
styleLimit: {}, |
||||||
|
event: {} |
||||||
|
}, |
||||||
|
depth: '', |
||||||
|
}, { |
||||||
|
name: '块文本',// 元素名称
|
||||||
|
// dir:true,// 是否为叶子节点
|
||||||
|
describe: "",// 描述
|
||||||
|
identify: 'blockText',// 标识
|
||||||
|
config: { |
||||||
|
childrenType: 'text', |
||||||
|
middle: '中间件', |
||||||
|
style: [...style2, 'flex'], |
||||||
|
styleLimit: {}, |
||||||
|
event: {} |
||||||
|
}, |
||||||
|
depth: '', |
||||||
|
}, { |
||||||
|
name: '图像',// 元素名称
|
||||||
|
// dir:true,// 是否为叶子节点
|
||||||
|
describe: "",// 描述
|
||||||
|
identify: 'image',// 标识
|
||||||
|
config: { |
||||||
|
childrenType: 'images', |
||||||
|
middle: '中间件', |
||||||
|
style: [...style1, 'flex'], |
||||||
|
styleLimit: {}, |
||||||
|
event: {} |
||||||
|
}, |
||||||
|
depth: '', |
||||||
|
}, { |
||||||
|
name: '视频',// 元素名称
|
||||||
|
// dir:true,// 是否为叶子节点
|
||||||
|
describe: "",// 描述
|
||||||
|
identify: 'video',// 标识
|
||||||
|
config: { |
||||||
|
childrenType: 'video', |
||||||
|
middle: '中间件', |
||||||
|
style: [...style2, 'flex'], |
||||||
|
styleLimit: {}, |
||||||
|
event: {} |
||||||
|
}, |
||||||
|
depth: '', |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: '输入元素',// 元素名称
|
||||||
|
// dir:true,// 是否为叶子节点
|
||||||
|
describe: "信息录入元素",// 描述
|
||||||
|
identify: 'input',// 标识
|
||||||
|
config: {}, |
||||||
|
depth: '', |
||||||
|
children: [ |
||||||
|
{ |
||||||
|
name: '基本输入',// 元素名称
|
||||||
|
// dir:true,// 是否为叶子节点
|
||||||
|
describe: "单行文本输入",// 描述
|
||||||
|
identify: 'input-text',// 标识
|
||||||
|
config: { |
||||||
|
childrenType: 'text', |
||||||
|
middle: '中间件', |
||||||
|
style: [...style2], |
||||||
|
styleLimit: {}, |
||||||
|
event: {} |
||||||
|
}, |
||||||
|
depth: '', |
||||||
|
}, { |
||||||
|
name: '块输入',// 元素名称
|
||||||
|
// dir:true,// 是否为叶子节点
|
||||||
|
describe: "多行文本输入",// 描述
|
||||||
|
identify: 'input-textarea',// 标识
|
||||||
|
config: { |
||||||
|
childrenType: 'text', |
||||||
|
middle: '中间件', |
||||||
|
style: [...style2, 'flex'], |
||||||
|
styleLimit: {}, |
||||||
|
event: {} |
||||||
|
}, |
||||||
|
depth: '', |
||||||
|
}, { |
||||||
|
name: '代码块',// 元素名称
|
||||||
|
// dir:true,// 是否为叶子节点
|
||||||
|
describe: "等宽字体的代码多行输入",// 描述
|
||||||
|
identify: 'input-code',// 标识
|
||||||
|
config: { |
||||||
|
childrenType: 'text', |
||||||
|
middle: '中间件', |
||||||
|
style: [...style1, 'flex'], |
||||||
|
styleLimit: {}, |
||||||
|
event: {} |
||||||
|
}, |
||||||
|
depth: '', |
||||||
|
}, { |
||||||
|
name: '等待开发',// 元素名称
|
||||||
|
// dir:true,// 是否为叶子节点
|
||||||
|
describe: "可拓展的输入选项",// 描述
|
||||||
|
identify: 'nomal',// 标识
|
||||||
|
config: { |
||||||
|
childrenType: 'text', |
||||||
|
middle: '中间件', |
||||||
|
style: [...style2, 'flex'], |
||||||
|
styleLimit: {}, |
||||||
|
event: {} |
||||||
|
}, |
||||||
|
depth: '', |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
]; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue