React(Hooks) 项目分层

一、先上示例代码

按业务功能优先、文件类型其次原则来组织项目文件结构。

- src
	- helpers
    - components  # 类型,没有数据状态、或完全内部数据状态封闭的组件,能独立、能复用
        + LineChart
        + BarChart
        + PieChart
    - views       # 业务,调用组件组装成一个个页面,不能复用,可给组件分发数据状态
        + Report
        + Document
        + Dashbord
        - Resources
            - index.jsx
            - List
                - index.jsx
                - useController.jsx                
                - service.jsx
            - Detail
                - index.jsx
                - useController.jsx
                - service.jsx
// service.jsx

// Service 层
// + 负责声明数据请求,只是声明,并未执行
// + 处理数据
import api from '../../helpers/api';

export default class ResourceService {
	constructor(){}
	
	async getResource (requestData) {
		const url = 'api/getResource'; 
		const response = await api.get(url, requestData);
		const responseData = this.handleGetResponseData(response);
		return responseData;
	}

	handleGetResponseData(data) {
		// handle data
		return data;
	}
}
// useController.jsx

// 第一个 Controller 区域
// + 要是负责数据连接
// + 声明数据发起,只是声明,并没发起请求
// + 处理 view 中交互逻辑,如显示、隐藏、Loading
// + 它在 ECMAScript 模块中,可以复用,算是一个变相的 service
import { useState, useEffect } from 'react';
import ResourceService from './service'export default function useGetResource (id) {
	const [resource, setResource] = useState(null);
	
	useEffect(() => {
		const fetchData = async () => {
			let resourceService= new ResourceService();
			let requestData = await resourceService.getResource(id);
			setResource(requestData);
		};
		fetchData();
	}, [id])

	return resource;
}
// Controller + Template
import React from 'react';
import { useParams } from 'react-router-dom';
import useGetResource from './useController'

export default function Response() {
	// 第二个 Controller 区域
	// + 负责数据绑定、事件绑定
	// + 负责发起数据请求
	const { id } = useParams();
	const { resource } = useGetResource(id);
	
	// 视图层 View/Template
	return (
		<>		
			<section>{resource.name}</section>
			<!-- 或,调用其它组件 -->
		</>
	);
}

二、抛问题

1、有的一个需求,其实就是对一个资源进行流程上的管理,如 OA 中的事务,一条资源,贯穿不同的视图。
这时,公用的 service 应该怎样处理?

2、有的一个需求,比较复杂,需要在当前页面中组合多个视图,如 “航班”:出发/到达城市+日历(含节假日) → Search → 日历菜单(含特价机票) → 航班列表。各个之间如何拆、装?


三、代码分层

其实,什么东西拆,拆解、分割到最后的,都是一个个单独的同性质、不同性质的资源,这样,就能隔离、复用;

页面,只是组装视图、映射数据、绑定事件。

React 中数据业务逻辑视图显示实现及各个之间映射,是需要开发者自己提炼的。React 就只有 JSX 、State(Props)、组件生命周期、渲染机制,React 只是一个库,它没有 template,没有 controller,,也没有 service;也就没有 di 机制管理 providerinject

开发者需要自己借助 ECMAScript 模块机制,约定 servicecontrollertemplate 等分层。

template,分成两类,一类是用于以隔离、或以复用的组件,一类用来组装组件页面化;

service,只负责数据获取和数据逻辑处理;

controller,会存在两个 controller,一个声明,一个发起,代码中已经详细叙述;

model,按业务功能拆,每个业务需求,就需要一个对应的容器(一个数据结构)model,用来描述业务,可以用来存放后端接口数据,也就是一个 stage


四、接口设计

RPC、RESTful、GraphQL 形式不强制;

只是最终数据结构需要强制一下;

用一个示例说一下:浏览器打开 https://api.github.com/repos/vuejs/vue

这个接口设计,除了有 vue 这个资源的数据信息外,还提供了 "owner" 对象、"organization" 对象,将相关性对象组合成一个完整的资源数据,内部不同性质的对象挂载在各自的属性中,而不是杂糅在一个扁平结构、或者嵌套在一个多层结构中。

后端接口设计,应该这样尽可能的分割成最小粒度,然后按资源、性质进行组合、包装。

你可能感兴趣的:(web前端)