当前只有一个 l-text
组件,所以所有的操作都只针对 l-text
组件。
流程图
点击模版列表添加到画布的行为流程图如下。
TemplatesData
为本地写死的模板数据,内部包含l-text
组件的各个属性 。- 通过
Editor.vue
把TemplatesData
传递给ComponentsList.vue
组件。 ComponentsList.vue
组件接受并渲染父组件传递过来的TemplatesData
。- 在
l-text
外层包裹Wrapper
用来传递事件。 - 当点击
Wrapper
的时候,发送事件onItemClick
。 - 父组件执行
store.commit
向store
中添加一条数据。 - 由于
store
是响应式的,所以当store
多了一条数据的时候,画布就会自动渲染出来。
代码部分
defaultProps.ts
新添加了两个类型,这里推荐一个 vscode
插件,vscode-code-to-type
,复制 js
对象,生成 ts
类型,非常的好用。
使用 ts
要尽量消灭 any
,尽管这会浪费你前期的部分时间,但是会节省后期的大量时间。
// 通用的默认属性类型
export interface CommonComponentProps {
// actions
actionType: string;
url: string;
// size
height: string;
width: string;
paddingLeft: string;
paddingRight: string;
paddingTop: string;
paddingBottom: string;
// border type
borderStyle: string;
borderColor: string;
borderWidth: string;
borderRadius: string;
// shadow and opacity
boxShadow: string;
opacity: string;
// position and x,y
position: string;
top: string;
left: string;
right: string;
bottom: string;
}
// l-text 组件特有默认属性类型
export interface TextComponentProps extends CommonComponentProps {
// basic props - font styles
text: string;
fontSize: string;
fontFamily: string;
fontWeight: string;
fontStyle: string;
textDecoration: string;
lineHeight: string;
textAlign: string;
color: string;
backgroundColor: string;
}
// 把属性改为可选
export type PartialTextComponentProps = Partial<TextComponentProps>;
defaultTemplates.ts
本地写死的模板数据,内部包含 l-text
组件的各个属性,大概就是四种文本的类型。
export const defaultTemplates = [
{
text: '大标题',
fontSize: '30px',
fontWeight: 'bold',
tag: 'h2',
},
{
text: '小标题',
fontSize: '24px',
fontWeight: 'bold',
tag: 'h3',
},
{
text: '正文内容',
fontSize: '14px',
tag: 'p',
},
{
text: '链接内容',
tag: 'p',
color: '#1890ff',
},
];
Editor.vue
代码语言:javascript复制// template
<!-- 左侧组件列表 -->
<a-layout-sider width="300"
style="background:#fff">
<div class="sidebar-container">
组件列表
<components-list @on-item-click="addItem"
:list="defaultTemplates"></components-list>
</div>
</a-layout-sider>
// script
import { PartialTextComponentProps } from '../defaultProps'
// 从组件列表添加组件到画布区域
const addItem = (props: PartialTextComponentProps) => {
store.commit("addComponent", props)
}
ComponentsList.vue
代码语言:javascript复制// template
<div class="create-component-list">
<div v-for="(item, index) in list"
@click="onItemClick(item)"
class="component-item"
:key="index">
<l-text v-bind="item"></l-text>
</div>
</div>
// script
import LText from '../components/LText.vue'
import { defineProps, withDefaults, defineEmits } from 'vue';
import { PartialTextComponentProps } from '../defaultProps'
interface MyProps {
list: Array<PartialTextComponentProps>;
}
// 接收 TemplatesData 数据
const props = withDefaults(defineProps<MyProps>(), {
list: () => [],
})
console.log('