课程名称:Web前端架构师2022版
课程章节: 第七周 B端项目需求分析 和 架构设计
主讲老师:张轩
课程内容:
今天学习的内容包括:
3-2 编辑器难点解析一
3-3 编辑器难点解析二
课程收获:
先来看看编辑器页面主要有三个部分,为左中右结构,左侧为组件模版库,中间为画布,右侧是设置面板。(和后端相关的暂不讨论 - 预览 发布 等)
-
左侧是预设各种组件模版并进行添加。
-
中间是使用交互的手段更新元素的值。
-
右侧是使用表单的手段更新元素的值。
第一个问题: 整体状态设计
不难看出我们的编辑器其实就是围绕着中间画布的元素来进行一系列操作,那么自然而然着
是一系列的元素组成的,我们应把它抽象成一系列拥有特定数据结构的数组。
export interface EditorStore {
// 供中间编辑器渲染的数组
components: ComponentData[];
// 一系列和其他状态相关的信息,应该有很多
// 当前编辑的是哪个元素,uuid
currentElement: string;
}
interface ComponentData {
// 每个元素 props 所有属性
// 我们上节课已经分析过了,是 css 属性和其他属性的混合体
// 并且我们会把这些属性完全平铺开来,其实在编辑器分析过后,你就能更感受到平铺的一个好处
props: { [key: string]: any };
// id,uuid v4 生成
id: string;
// 业务组件库名称 l-text,l-image 等等
name: string;
}
场景设计
将元素渲染到画布
使用 store 中 compoents 当中的数据,循环渲染
compoents.map(component => <component.name {...props} />)
渲染左侧预设组件模版
原理和上面一样的,只不过数据是预设好的,这个可以写死在本地,也可以从服务器端取得。他们和中间元素不一样的是,这些组件都有一个点击事件,我们可以添加一层 wrapper 来解决这个问题。这样也可以和内部的 lego components 做到隔离,互不影响。
compoents.map(component => <Wrapper><component.name {...props} /></Wrapper>)
添加和删除组件
非常简单的逻辑,向 store 中添加和删除组件即可。
// 添加
components.push({type: '', props: {} })
// 删除
components = components.filter((component) => component.id !== id)
将属性映射到表单
几个典型场景的实现,大家应该发现,其实没那么复杂,就是对全局状态中的 components 字段进行修改而已。
组件更新
我们的数据流始终保持自上而下的顺序,也就是说表单更新最终要反射回到总体的 store 当中去。这个时候我们在对应的组件当中发射出一个事件,change,当 change 发生的时候,我们能够知道是哪个元素的哪个属性,以及新的值是什么,我们就用这些信息更新这个值,这样 store 完成更新,元素的 props 发生更新,那么整个数据流动就完成了。
map(textComponentProps, (key, value) => {
const handleChange = (propKey, newValue, id) => {
const updatedComponent = store.components.find(component.id === id)
updatedComponent.props[propKey] = newValue
}
<propsMap[key] value={value} @change={handleChange}>
}
除了表单的更新,还要说一下画布中的交互更新,其实画布中的更新也是采用发射事件的方式对store 的某些值进行更新,比如说拖动改变位置,最终拖动的过程中也是触发对应的change 事件去用相同的逻辑对值进行更新,这里也要注意,我们需要在业务组件外层,添加一个Wrapper,各种事件都是放在这个 Wrapper 上面的,比如支持拖动,改变位置后发送 change 事件。
对于复杂组件也是如此,不管你内部的逻辑有多复杂,添加上传图片,删除,编辑,最终发送出来的事件里面的值,就是对这个 pictures 的值的变换,比如多加了一张照片,那就是数组中的值变成了三项。
画布操作的插件化
比如快捷键,他只写成普通的可重用的函数即可,提供回调即可,在回调中,我们可以对全局 store 进行一系列的改写,而快捷键这个功能和编辑器是没有任何关系的。
共同学习,写下你的评论
评论加载中...
作者其他优质文章