【架构师(第二十二篇)】编辑器开发之项目整体搭建
分类:vue
这个阶段更多的是编写业务代码,除了编辑器之外没什么难度,需要记录笔记的部分并不多,除非有特殊需要记录的地 方,否则代码不会放在笔记里。
TypeScript 技术补充
由于对 ts
和 vue3
已经有了初步了解,本文就不对基础记录笔记,只补充一些自己不是很掌握的知识点。
interface
// 声明函数类型
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";
}
};
泛型
// 泛型基础
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
相同的输入,永远得到相同的输出
// 输入 2 ,永远输出 4
function foo(a){
return a * 2
}
// 输入 2, 输出不确定
function bar(a){
return a * Math.random()
}
没有副作用
- 网络请求
DOM
操作- 订阅数据来源
- 写入文件系统
- 获取用户输入
- ... ...
watchEffect
- 初始化的时候会执行一次进行依赖的收集
- 组件销毁的时候会自动移除
watchEffect
- 返回一个函数可以手动清除
watchEffect
- 可以提供一个参数修改
watchEffect
的执行时机
const count = ref(0);
const stop = watchEffect(()=>{
console.log(count.value)
});
stop();
watchEffect(
()=>{
console.log(count.value)
},
{
flush:"post" // 更新 dom 之后
}
);
编辑器开发之项目整体搭建
将收获什么
- 前端工具链的相关工具介绍
- 脚手架工具的使用和对比
imooc-cli
vue-cli
vite
- 编码规范
ESLint
Prettier
- 产出文档
- 项目结构规范
- 产出文档
Git
操作规范- 产出文档
创建项目
安装 imooc-cli
脚手架,并生成项目。
npm install -g @imooc-cli/core
npm install -g cnpm
imooc-cli --version
imooc-cli init
Git Flow 标准操作流程
- 根据需求,从
master
拉出分支 - 开发阶段,提交
commit
- 开发完毕,发起
PR(pull request)
- 代码评审
- 部署,测试
merge
到master
两大规则
- 分支命名
feature
开头代表新功能开发hotfix
开头代表bug
修复
commit
信息需要明确,杜绝update
,bugfix
等废话,言之有物,言简意赅的把一次commit
说清楚。
项目基础搭建
安装第三方组件库 ant-design-vue
通过 npm
安装
npm install ant-design-vue --save
引入
// 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');
使用
// App.vue
<template>
<a-button type="primary">Primary Button</a-button>
</template>
vue-router
通过 npm
安装
npm install vue-router@next --save
配置
// 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 实例
// src\main.ts
import router from './routes/index';
app.use(router);
vuex
通过 npm
安装
npm install vuex@next --save
配置
// src\store\index.ts
import { createStore } from 'vuex';
const store = createStore({
state: { count: 0 },
});
export default store;
挂载到 vue 实例
// src\main.ts
import vuex from './routes/index';
app.use(vuex);
结合 ts
// src\store\index.ts
import { createStore } from 'vuex';
export interface GlobalStore {
count: number;
}
const store = createStore<GlobalStore>({
state: { count: 0 },
});
export default store;
vue
文件中使用
// 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
模块
// 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;
// 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;
// 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;
一线大厂高级前端编写,前端初中阶面试题,帮助初学者应聘,需要联系微信:javadudu