阶段二:B 端项目分析和设计

第 7 周 B 端项目需求分析和架构设计

分析需求,找出技术难点,攻克难点制定方案,编写伪代码,绘制流程图,整理成写文档,给后面的开发提供思路指导。

组件的属性应该怎么设计?

伪代码

// 方案一,将css作为一个统一的对象传入
<LText css={{color: '#fff', ...}} text="文字内容" />

// 组件内部实现比较简单,但是保存的时候多一层结构,并且在更新的时候也麻烦
<p style={props.css}></p>

// 方案二,将所有属性平铺传入
<LText text="文字内容" color="#fff" ...></LText>

// 内部实现会复杂一点,需要区分属性和内容,但是保存简单,更新数据不需要再做辨别
const styles = stylePick(props)
<p style={styles}></p>
1
2
3
4
5
6
7
8
9
10
11
12

选择第方案二更简单。

编辑器的难题

左侧画布是固定模板可以点击添加到中间,中间画布可编辑,右侧画布可使用表单编辑。

中间画布内容是一个数组,每一个元素都是一个组件,都是自己的属性,所有的新增、删除、编辑都是在操作这个数组中的数据。

// 编辑器的状态
interface EditorStore {
  components: ComponentData[];  // 所有组件的数据
  currentElement: string; // 当前选中的组件
}

// 组件数据结构
interface ComponentData {
  props: { [key: string]: any }; // 所有属性的混合体
  id: number;
  name: string;
}

// 将组件数据渲染到画布中,循环渲染components
const components = [
  {
    id: 1,
    name: 'l-text',
    props: { text: '文本', color: '#fff', fontSize: '14px' }
  }
]
components.map(component => <component.name {...component.props} />)

// 点击左侧模板,添加到中间画布,就是往components中push一条数据
components.push({...})

// 删除中间画布中的组件,也是操作components,过滤掉要删除的组件
components.filter(component => component.id !== id)

// 左侧模板渲染,也是渲染一套相似结构的模板数据,可以在管理后台单独维护,渲染的时候可以在外面再包裹一层,添加点击事件
const templateComponents = [...]
templateComponents.map(component => <Wrapper @click><component.name {...component.props} /></Wrapper>)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

编辑器右侧表单渲染

界面是数据的反应,将复杂的界面用数据来描述。

表单数据结构

// 组件数据
const textComponentProps = {
  text: '文本',
  fontFamily: 'HeiTi',
  color: '#fff'
}

// 对应的表单组件数据,可扩展性高,能二次开发
const propsMap = {
  text: {
    component: 'input', // 使用 input 组件来渲染
  },
  fontFamily: {
    component: 'dropdown',
  },
  color: {
    component: 'color-picker',
  },
}

// 渲染出对应的组件
map(textComponentProps, (key, value) => {
  // 添加事件,更新数据
  const handleChange = (propKey, newValue, id) => {
    const updatedComponent = store.components.find(component.id === id)
    updatedComponent.props[propKey] = newValue
  }
  // 渲染表单
  <propsMap[key].component value={value} @change={handleChange} />
})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

流程图: image

总体技术选型

image

第 8 周 前端基础技术回顾

Typescript

  1. 为什么使用
  2. 基础知识点
  3. interface
  4. 泛型(难点)
  5. 高级特性
  6. 定义文件

type inference(类型自动推论),在没有明确指定类型的时候,ts 会自动推论出一个类型。

类型自动推论无法进入函数里面,所以需要使用到泛型。泛型使用<>表示,定义一个或多个特殊的变量,在函数中传递,调用函数的时候再传递具体的类型。

Vue3

  1. 为什么
  2. 基础知识点
  3. 响应式对象基本原理的解析
  4. 副作用
  5. 自定义 Hooks

第 9 周 项目整体搭建

前端工具链

  • 静态类型语言:typescript、flow

  • 代码风格检查:eslint

  • 包管理器:npm、yarn

  • 转译器:babel

  • 开发服务器:webpack-dev-server、live reload、HMR

  • 打包工具:webpack、rollup

  • 任务管理工具:webpack、gulp

用脚手架将工具链聚合在一个工具内,简单,快熟,零配置。

使用 imooc-cli 新建项目

shims-vue.d.ts.vue文件的类型定义。如果没有 TS 会报错Cannot find module './App.vue' or its corresponding type declarations.

Vue CLI 和 Vite 对比

在开发环境,Vite 速度快 10 - 100 倍,它舍弃了兼容性要求,目前在测试阶段,要求第三方库都需要支持 ES modules,开发环境和打包上线是不同的代码,可能运行不太一样。

Vite 适合学习,测试项目,不太适合正式项目,不太适合需要做浏览器兼容的项目。

ESLint

是一个开源的 JavaScript 的 linting 工具,使用 espree 将 JavaScript 代码解析成抽象的语法树(AST)。

  • 编辑器内也安装 ESLint 插件

项目结构规范

  • 不要嵌套太多
  • 不要过度思考,开始阶段花费时间不要超过 5 分钟

第 10 周

  • 完成第一个业务组件 LText 的编写
  • 完成业务组件属性和表单组件的显示和实时更新
  • 代码升级:支持 vNodevue template 中的展示
Last Updated: 2023/8/2 10:45:34
Contributors: licong96