首页
学习
活动
专区
圈层
工具
发布
50 篇文章
1
【架构师(第一篇)】整体需求分析和架构设计
2
【架构师(第二篇)】脚手架架构设计和框架搭建
3
【架构师(第三篇)】脚手架开发之掌握Lerna操作流程
4
【架构师(第四篇)】脚手架开发之Lerna源码分析
5
【架构师(第五篇)】脚手架之import-local执行流程及简历设计
6
【架构师(第六篇)】脚手架之需求分析和架构设计
7
【架构师(第七篇)】脚手架之准备阶段编写
8
【架构师(第八篇)】脚手架之 commander 框架使用方法
9
【架构师(第九篇)】如何让 Node 环境支持 ES Module
10
【架构师(第十篇)】脚手架之注册命令及架构优化
11
【架构师(第十一篇)】脚手架之命令注册和执行过程开发
12
【架构师(第十二篇)】脚手架之命令行交互工具 inquirer.js 使用方法
13
【架构师(第十三篇)】脚手架之创建项目准备阶段开发
14
【架构师(第十四篇)】脚手架之 egg.js 和 mongodb 的使用
15
【架构师(第十五篇)】脚手架之创建项目模板开发
16
【架构师(第十六篇)】脚手架之创建项目模板的下载与更新
17
【架构师(第十七篇)】脚手架之 ejs 和 glob 的使用
18
【架构师(第十八篇)】脚手架之项目模板的安装
19
【架构师(第十九篇)】脚手架之组件库模板开发
20
【架构师(第二十篇)】脚手架之自定义模板及第一阶段总结
21
【架构师(第二十一篇)】编辑器开发之需求分析和架构设计
22
【架构师(第二十二篇)】编辑器开发之项目整体搭建
23
【架构师(第二十三篇)】编辑器开发之画布区域组件的渲染
24
【架构师(第二十四篇)】编辑器开发之添加模版到画布
25
【架构师(第二十五篇)】编辑器开发之属性编辑区域表单渲染
26
【架构师(第二十六篇)】编辑器开发之属性编辑同步渲染
27
【架构师(第二十七篇)】前端单元测试框架 Jest 基础知识入门
28
【架构师(第二十八篇)】 测试工具 Vue-Test-Utils 基础语法
29
【架构师(第二十九篇)】Vue-Test-Utils 触发事件和异步请求
30
【架构师(第三十篇)】Vue-Test-Utils 全局组件和第三方库 vuex | vue-router
31
【架构师(第三十一篇)】前端测试之 TDD 的开发方式
32
【架构师(第三十二篇)】 通用上传组件开发及测试用例
33
【架构师(第三十三篇)】 Vue 中的实例及本地图片预览
34
【架构师(第三十四篇)】 业务组件库开发之 vue3 的插件系统
35
【架构师(第三十五篇)】 业务组件库开发之使用 Rollup 进行打包
36
【架构师(第三十六篇)】 业务组件库开发之发布到 NPM
37
【架构师(第三十七篇)】 服务端开发之后端框架与数据库技术选型
38
【架构师(第三十八篇)】 服务端开发之本地安装最新版 MySQL 数据库
39
【架构师(第三十九篇)】 服务端开发之连接 MySQL 数据库
40
【架构师(第四十篇)】 服务端开发之连接 Mongodb 数据库
41
【架构师(第四十一篇)】 服务端开发之安装并连接 Redis数据库
42
【架构师(第四十二篇)】 服务端开发之常用的登录鉴权方式
43
【架构师(第四十三篇)】 服务端开发之单元测试和接口测试
44
【架构师(第四十四篇)】 服务端开发之 pm2 和 nginx 介绍
45
【架构师(第四十五篇)】 服务端开发之认识 Github actions
46
【架构师(第四十六篇)】 服务端开发之安装 Docker
47
【架构师(第四十七篇)】 服务端开发之认识 Docker
48
【架构师(第四十八篇)】 服务端开发之 Dockerfile
49
【架构师(第四十九篇)】 服务端开发之认识 Docker-compose
50
【架构师(第五十篇)】 服务端开发之自动发布到测试机
清单首页架构文章详情

【架构师(第二十二篇)】编辑器开发之项目整体搭建


这个阶段更多的是编写业务代码,除了编辑器之外没什么难度,需要记录笔记的部分并不多,除非有特殊需要记录的地 方,否则代码不会放在笔记里。

TypeScript 技术补充

由于对 tsvue3 已经有了初步了解,本文就不对基础记录笔记,只补充一些自己不是很掌握的知识点。

👉👉 【初学者笔记】🐯年要掌握 Typescript

👉👉 【初学者笔记】整理的一些Vue3知识点

interface

代码语言:javascript
复制
// 声明函数类型
interface Foo {
  (x: number, y: number): number;
}

// 可索引类型
interface RandomMap {
  [propName: string]: string;
}

// 类数组 , 可以通过数组取值 , 但是不能调用方法
interface LikeArray {
  [index: number]: string;
}

// 函数添加属性
interface FunctionWithProps {
  (x: number): number;
  name: string;
}

// 定义接口类型
interface Animal {
  name: string;
  run(): void;
}

// 实现接口
class cat implements Animal {
  name: string = "cat";
  run() {
    this.name + "run";
  }
}

// 定义接口类型
interface Live {
  breathe(): void;
}

// 实现多个类型的接口
class liveCat implements Animal, Live {
  name: string = "cat";
  run() {
    this.name + "run";
  }
  breathe() {
    this.name + "breathing";
  }
}

// 定义类的静态类型
interface CatStatic {
  // 可以被 new 调用的构造函数
  new (eyes: number, hands: number): void;
}

// 类的阴阳两面, 包含静态类型和实例类型
const FooCat: CatStatic = class FooCat implements Cat {
  constructor(eyes: number, hands: number) {}
  name: string = "cat";
  run() {
    this.name + "run";
  }
};

泛型

代码语言:javascript
复制
// 泛型基础
function foo<T>(arg: T): T {
  return arg;
}

// 交换 tuple 的位置
function swap<T, K>(tuple: [T, K]): [K, T] {
  return [tuple[1], tuple[0]];
}

interface Person {
  name: string;
  age: number;
}

interface Car {
  color: string;
  wheels: number;
}

// 约定请求返回值结果
function getInfo<T>(url: string): Promise<T> {
  return fetch(url).then((resp) => resp.json());
}

// resp 是 Person 类型
getInfo<Person>('/getperson').then((resp) => {});
// resp 是 Car 类型
getInfo<Car>('/getcar').then((resp) => {});

// 传入一个泛型, 把泛型中的属性全部变为可选
type PersonPartial = Partial<Person>;

// 遍历某个类型的键,返回由这些键组成的新的类型
type PersonKeys = keyof Person;

// lookup types 返回某个属性的类型
type NameType = Person['name'];

// mapped types 遍历
type Test = {
  [key in PersonKeys]: any;
};

// 相当于复制了一份 Person 类型
type PersonCopy = {
  [p in PersonKeys]: Person[p];
};

// 实现了 Partial 
type PersonCopy = {
  [p in PersonKeys]?: Person[p];
};

// 泛型约束
interface IWithLength {
  length: number;
}
// 传入的类型必须包含 length 属性
function echoWithArr<T extends IWithLength>(arg: T): T {
  console.log(arg.length);
  return arg;
}

// 条件类型关键字
// 判断一个类型是否满足另一个类型的约束
type NonType<T> = T extends null | undefined ? never : T;

Vue3 技术补充

纯函数 pure function

相同的输入,永远得到相同的输出

代码语言:javascript
复制
// 输入 2 ,永远输出 4
function foo(a){
 return a * 2
}
// 输入 2, 输出不确定
function bar(a){
 return a * Math.random()
}

没有副作用

  • 网络请求
  • DOM 操作
  • 订阅数据来源
  • 写入文件系统
  • 获取用户输入
  • ... ...

watchEffect

  • 初始化的时候会执行一次进行依赖的收集
  • 组件销毁的时候会自动移除 watchEffect
  • 返回一个函数可以手动清除 watchEffect
  • 可以提供一个参数修改 watchEffect 的执行时机
代码语言:javascript
复制
const count = ref(0);
const stop = watchEffect(()=>{
    console.log(count.value)
});
stop();
watchEffect(
    ()=>{
        console.log(count.value)
    },
    {
        flush:"post" // 更新 dom 之后
    }
);

编辑器开发之项目整体搭建

将收获什么

  • 前端工具链的相关工具介绍
  • 脚手架工具的使用和对比
代码语言:txt
复制
- `imooc-cli`
- `vue-cli`
- `vite`编码规范
代码语言:txt
复制
- `ESLint`
- `Prettier` 
- 产出文档项目结构规范
代码语言:txt
复制
- 产出文档
代码语言:txt
复制
- 产出文档

创建项目

安装 imooc-cli 脚手架,并生成项目。

代码语言:javascript
复制
npm install -g @imooc-cli/core
npm install -g cnpm
imooc-cli --version
imooc-cli init

Git Flow 标准操作流程

  • 根据需求,从 master 拉出分支
  • 开发阶段,提交 commit
  • 开发完毕,发起 PR(pull request)
  • 代码评审
  • 部署,测试
  • mergemaster

两大规则

  • 分支命名
    • feature 开头代表新功能开发
    • hotfix 开头代表 bug 修复
  • commit 信息需要明确,杜绝 updatebugfix 等废话,言之有物,言简意赅的把一次 commit 说清楚。

项目基础搭建

安装第三方组件库 ant-design-vue

通过 npm 安装

代码语言:javascript
复制
npm install ant-design-vue --save

引入

代码语言:javascript
复制
// src\main.ts

import { createApp } from 'vue';
import App from './App.vue';

// 引入 Antd 组件库
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';

const app = createApp(App);

app.use(Antd).mount('#app');

使用

代码语言:javascript
复制
// App.vue
<template>
  <a-button type="primary">Primary Button</a-button>
</template>

vue-router

通过 npm 安装

代码语言:javascript
复制
npm install vue-router@next --save

配置

代码语言:javascript
复制
// src\routes\index.ts

import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
import Editor from '../views/Editor.vue';
import TemplateDetail from '../views/TemplateDetail.vue';

const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home,
    },
    {
      path: '/editor',
      name: 'editor',
      component: Editor,
    },
    {
      path: '/template/:id',
      name: 'template',
      component: TemplateDetail,
    },
  ],
});
export default router;

挂载到 vue 实例

代码语言:javascript
复制
// src\main.ts

import router from './routes/index';
app.use(router);

vuex

通过 npm 安装

代码语言:javascript
复制
npm install vuex@next --save

配置

代码语言:javascript
复制
// src\store\index.ts

import { createStore } from 'vuex';

const store = createStore({
  state: { count: 0 },
});

export default store;

挂载到 vue 实例

代码语言:javascript
复制
// src\main.ts

import vuex from './routes/index';
app.use(vuex);

结合 ts

代码语言:javascript
复制
// src\store\index.ts

import { createStore } from 'vuex';

export interface GlobalStore {
  count: number;
}

const store = createStore<GlobalStore>({
  state: { count: 0 },
});

export default store;

vue 文件中使用

代码语言:javascript
复制
// src\App.vue

import { useStore } from 'vuex'
import { GlobalStore} from './store/index'
import { computed } from 'vue';

const store = useStore<GlobalStore>()
const count = computed(() => store.state.count)

使用 Module 分割 Vuex 模块

代码语言:javascript
复制
// src\store\index.ts

import { createStore } from 'vuex';
import user from './user';
import template from './template';
import type { UserStore } from './user';
import type { TemplateStore } from './template';

export interface GlobalStore {
  user: UserStore;
  template: TemplateStore;
}

const store = createStore<GlobalStore>({
  modules: {
    user,
    template,
  },
});

export default store;
代码语言:javascript
复制
//  src\store\user.ts

import type { Module } from 'vuex';
import type { GlobalStore } from './index';
export interface UserProps {
  username: string;
  age: number;
}

export type UserList = UserProps[];

export interface UserStore {
  userList: UserList;
}

const userList: UserList = [
  {
    username: 'foo',
    age: 18,
  },
  {
    username: 'boo',
    age: 20,
  },
];

const userStore: Module<UserStore, GlobalStore> = {
  state: {
    userList: userList,
  },
  getters: {
    getUserByName: (state) => (name: string) => {
      return state.userList.find((u) => u.username === name);
    },
  },
};

export default userStore;
代码语言:javascript
复制
//  src\store\template.ts

import type { Module } from 'vuex';
import type { GlobalStore } from './index';
export interface TemplateProps {
  templateName: string;
  age: number;
}

export type TemplateList = TemplateProps[];

export interface TemplateStore {
  templateList: TemplateList;
}

const templateList: TemplateList = [
  {
    templateName: 'foo',
    age: 18,
  },
  {
    templateName: 'boo',
    age: 20,
  },
];

const templateStore: Module<TemplateStore, GlobalStore> = {
  state: {
    templateList: templateList,
  },
  getters: {
    getTemplateByName: (state) => (name: string) => {
      return state.templateList.find((t) => t.templateName === name);
    },
  },
};

export default templateStore;
下一篇
举报
领券