【架构师(第二十四篇)】编辑器开发之添加模版到画布

2022-12-10 13:38:32 浏览数 (1)


当前只有一个 l-text 组件,所以所有的操作都只针对 l-text 组件。

流程图

点击模版列表添加到画布的行为流程图如下。

  • TemplatesData 为本地写死的模板数据,内部包含 l-text 组件的各个属性 。
  • 通过 Editor.vueTemplatesData 传递给 ComponentsList.vue 组件。
  • ComponentsList.vue 组件接受并渲染父组件传递过来的 TemplatesData
  • l-text 外层包裹 Wrapper 用来传递事件。
  • 当点击 Wrapper 的时候,发送事件 onItemClick
  • 父组件执行 store.commitstore 中添加一条数据。
  • 由于 store 是响应式的,所以当 store 多了一条数据的时候,画布就会自动渲染出来。

代码部分

defaultProps.ts

新添加了两个类型,这里推荐一个 vscode 插件,vscode-code-to-type ,复制 js 对象,生成 ts 类型,非常的好用。

使用 ts 要尽量消灭 any,尽管这会浪费你前期的部分时间,但是会节省后期的大量时间。

代码语言:javascript复制
// 通用的默认属性类型
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 组件的各个属性,大概就是四种文本的类型。

代码语言:javascript复制
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('


	

0 人点赞