首页 > 其他分享 >如何结合整洁架构和MVP模式提升前端开发体验(三) - 项目工程化配置、规范篇

如何结合整洁架构和MVP模式提升前端开发体验(三) - 项目工程化配置、规范篇

时间:2022-09-07 23:55:33浏览次数:71  
标签:MVP return string service export 工程化 model 前端开发 const

工程化配置

还是开发体验的问题,跟开发体验有关的项目配置无非就是使用 eslint、prettier、stylelint 统一代码风格。

formatting and lint

eslint、prettier、stylelint 怎么配这里就不说了,网上文章太多了。想说的是eslint rule 'prettier/prettier': 'error'一定要开启,以及 stylelint rule 'prettier/prettier': true 也一定要开启。

虽然配置了eslint、prettier、stylelint,但是可能你队友的编辑器并没有装相应的插件,格式化用的也不是 prettier,然后他修改一行代码顺便把整个文件格式化了一遍。所以还得配置 husky + lint-staged,提交代码的时候按规范格式化回去,不符合规范的代码不允许提交。

如果公司的电脑配置还行的话,可以开发阶段就做相应的 lint, 把错误抛出来,中断编译。webpack 可以使用 eslint-loader,stylelint-webpack-plugin;vite 可以使用 vite-plugin-eslint,vite-plugin-stylelint;vue-cli 配置几个参数就可以开启,具体看文档。

ts-check

什么是 ts-check?举个例子,有一个后端接口的某个字段名称变了,由 user_name 改为了 userName,如果没有配置开发阶段进行 ts-check 并把错误抛出来,那么只能全局查找调用接口的地方去修改,如果改漏了,那就喜提一个 BUG。

ts-check 可以开发阶段就做,也可以提交代码的时候做。开发阶段 webpack 安装 fork-ts-checker-webpack-plugin ,vite 也是找相应的插件(暂时没找到用的比较多的)。提交代码的时候,结合 husky 做一次全量的 check (比较耗时),react 项目执行 tsc --noEmit --skipLibCheck,vue 项目执行 vue-tsc --noEmit --skipLibCheck

ts-check 能好用的前提是你的项目是 TS 写的,接口返回值有具体的类型定义,而不是 any。

代码规范

主要讲讲 model,service,presenter,view 这几层的代码规范,之前的文章也有简单提到过,这里做个归纳。

model

import { reactive, ref } from "vue";
import { IFetchUserListResult } from "./api";

export const useModel = () => {
  const userList = reactive<{ value: IFetchUserListResult["result"]["rows"] }>({
    value: [],
  });
 
  return {
    userList,
  };
};

export type Model = ReturnType<typeof useModel>;

  1. 每一个字段都要声明类型,不要因为字段多就用 Object[k: string]: string | number | booleanRecord<string, string> 之类的来偷懒。
  2. 可以包含一些简单逻辑的方法,比如重置 state。
  3. vue 中字段声明可以移到 useModel 外面,达到状态共享的作用,在 useModel 中 return 出去使用。

service

  1. react 技术栈,presenter 层调用的时候使用单例方法,避免每次re-render 都生成新的实例。
  2. service 要尽量保持“整洁”,不要直接调用特定环境,端的 API,尽量遵循 依赖倒置原则。比如 fetch,WebSocket,cookie,localStorage 等 web 端原生 API 以及 APP 端 JSbridge,不建议直接调用,而是抽象,封装成单独的库或者工具函数,保证是可替换,容易 mock 的。Taro,uni-app 等框架的 API 也不要直接调用,可以放到 presenter 层。组件库提供的命令式调用的组件,也不要使用。
  3. service 方法的入参要合理,不要为了适配组件库而声明不合理的参数,比如某个组件返回 string[] 类型的数据,实际只需要数组第一个元素,参数声明为 string 类型即可。2个以上参数改为使用对象。
  4. 业务不复杂可以省略 service 层。

service 保证足够的“整洁”,model 和 service 是可以直接进行单元测试的,不需要去关心是 web 环境还是小程序环境。

import { Model } from './model';

export default class Service {
  private static _indstance: Service | null = null;

  private model: Model;

  static single(model: Model) {
    if (!Service._indstance) {
      Service._indstance = new Service(model);
    }
    return Service._indstance;
  }

  constructor(model: Model) {
    this.model = model;
  }
}

presenter

import { message, Modal } from 'antd';
import { useModel } from './model';
import Service from './service';

const usePresenter = () => {
  const model = useModel();
  const service = Service.single(model);

  const handlePageChange = (page: number, pageSize: number) => {
    service.changePage(page, pageSize);
  };

  return {
    model,
    handlePageChange,
  };
};

export default usePresenter;

  1. 处理 view 事件的方法以 handle 或 on 开头。
  2. 不要出现过多的逻辑。
  3. 生成 jsx 片段的方法以 render 开头,比如 renderXXX。
  4. 不管是 react 还是 vue 不要解构 model,直接 model.xxxx 的方式使用。

view

  1. 组件 props 写完整类型。
  2. jsx 不要出现嵌套的三元运算。
  3. 尽量所有的逻辑都放到 presenter 中。
  4. 不要解构 presenter 以及 model,以 presenter.xxx,model.xxxx 方式调用。

store

  1. 不要在外层去使用内层的 store。

接口请求方法

  1. 封装的接口请求方法支持泛型
import axios, { AxiosRequestConfig } from "axios";
import { message } from "ant-design-vue";

const instance = axios.create({
  timeout: 30 * 1000,
});

// 请求拦截
instance.interceptors.request.use(
  (config) => {
    return config;
  },
  (error) => {
    return Promise.reject(error);
  },
);

// 响应拦截
instance.interceptors.response.use(
  (res) => {
    return Promise.resolve(res.data);
  },
  (error) => {
    message.error(error.message || "网络异常");
    return Promise.reject(error);
  },
);

type Request = <T = unknown>(config: AxiosRequestConfig) => Promise<T>;

export const request = instance.request as Request;

  1. 具体接口的请求方法,入参及返回值都要声明类型,参数量最多两个,body 数据命名为 data,非 body 数据命名为 params,都是对象类型。
  2. 参数类型及返回值类型都声明放在一起,不需要用单独的文件夹去放,觉得代码太多不好看可以用 region 注释块折叠起来(vscode 支持)。
  3. 接口请求方法以 fetch,del,submit,post 等单词开头。
  4. 建议接口请求方法直接放在组件同级目录里,建一个 api.ts 的文件。很多人都习惯把接口请求统一放到一个 servcies 的文件夹里,但是复用的接口又有几个呢,维护代码的时候在编辑器上跨一大段距离来回切换文件夹真的是很糟糕的开发体验。
// #region 编辑用户
export interface IEditUserResult {
  code: number;
  msg: string;
  result: boolean;
}

export interface IEditUserParams {
  id: number;
}

export interface IEditUserData {
  name: string;
  age: number;
  mobile: string;
  address?: string;
  tags?: string[];
}

/**
 * 编辑用户
 * http://yapi.smart-xwork.cn/project/129987/interface/api/1796964
 * @author 划水摸鱼糊屎工程师
 *
 * @param {IEditUserParams} params
 * @param {IEditUserData} data
 * @returns
 */
export function editUser(params: IEditUserParams, data: IEditUserData) {
  return request<IEditUserResult>(`${env.API_HOST}/api/user/edit`, {
    method: 'POST',
    data,
    params,
  });
}

// #endregion

上面代码是工具生成的,下篇说说提升开发效率及体验的工具。

标签:MVP,return,string,service,export,工程化,model,前端开发,const
From: https://www.cnblogs.com/jaycewu/p/16667770.html

相关文章

  • 如何结合整洁架构和MVP模式提升前端开发体验(二) - 代码实现篇
    上一篇文章介绍了整体架构,接下来说说怎么按照上图的分层结构实现下面的增删改查的功能。代码结构vueuserManage└──List├──api.ts├──EditMo......
  • xx技术2023前端开发卷A
    xx技术2023前端开发卷A选择以下哪种情况会导致浏览器报HTTPS证书告警()网站的https安全证书确实已经过期,根据https安全证书签发国际标准,https安全证书颁发不能超过两......
  • 【2022.8.26】前端开发(5)
    学习内容概要JS获取用户输入值JS事件绑定jQuery类库jQuery常见操作内容详细JS获取用户输入普通数据(输入、选择) 标签对象.value文件数据(上传) 标签对象.......
  • 【2022.8.29】前端开发(6)
    学习内容概要jQuery更多操作(属性、样式、数据值)jQuery绑定事件jQuery简易动画效果Bootstrap页面框架内容详细筛选器方法$("#id").next()$("#id").nextAll()......
  • 前端开发常用工具
    记录自己经常用到的工具,换电脑时使用----------不定时更新 一:电脑相关1.windows系统,安装nvmnode包管理工具,可以切换多个node版本,以适应vue2,vue3,react等开发需求,安......
  • 【2022-08-26】python前端开发(五)
    python前端开发(五)JS获取值操作普通数据(输入、选择) 标签对象.value文件数据(上传) 标签对象.files 标签对象.files[0]leti1Ele=document.getElementById('d1......
  • 【2022.8.25】前端开发(4)
    学习内容概要JS基本数据类型流程控制函数与面向对象JS的BOM与DOM操作学习内容详细JS数据类型之布尔值1.回顾之前python中布尔值(bool)TrueFalse:0None[]......
  • 【2022.8.24】前端开发(3)
    学习内容概要盒子模型浮动布局定位属性z-indexJavaScript基础语法内容详细盒子模型所有的标签都可以看成是一个快递盒1.两个快递盒之间的距离标签之间......
  • 【2022-08-24】python前端开发(三)
    python前端开发(三)CSS盒子模型margin:用于控制元素与元素之间的距离;margin的最基本用途就是控制元素周围空间的间隔,从视觉角度上达到相互隔开的目的。......
  • 前端开发3
    目录一、CSS盒子模型1.margin外边距2.padding内填充二、浮动布局(float)1.浮动的特点2.浮动的三种取值3.clear属性4.清除浮动4.1.清除浮动主要的三种方式:4.2.伪元素清除法(使......