基于Abp React前端的项目建立与运行
1 Abp项目配置
2 运行WebApi后端项目
2.1 创建C3D数据库,并且将数据库对应链接字符串替换
2.2 建立数据库进行数据迁移
主项目选择到StartUp所在的项目,C3D.Web.Host,nuget console窗口打到C3D.EntityFrameWork.Core项目;
然后输入数据迁移指令
Add-Migration first_init
Update-Database
2.3 运行WebApi项目
选择C3D.Web.Host,点击运行。
Swagger WebApi 接口页面如下:
3 运行React前端项目
3.1 利用yarn包安装工具
利用yarn包安装工具安装react客户端运行所需依赖包。
备注:会发现用npm无法安装成功,用yarn包安装时需要删除package-lock.json文件。
3.2 运行React项目
npm start
登录页面
-
登录用户名:admin
密码:123qwe -
dashboard
3.3 使用React客户端的意义
有没有感觉3.2的UI很好看,是的,个人感觉UI的精细程度已经远远超过VUE的Element 跟Iview UI了。因为该项目使用的是ant-design UI。
而 github上直接搜索UI,按start排名。前两个UI 的都是react。这也就是我选择react的意义了。使用哪个框架其实都差不多,个人比较看重UI展示的精细化程度与美感。
这两个UI框架的贡献者与使用者规模已很大。
4 React 前端项目架构
4.1 技术栈
- React 构建用户UI的js库;
- Typescript 强类型语言,更适合后台编程人员;
- Mobx 简单,可扩展的状态管理框架;
- AntDesign 可为企业应用程序提供更好的用户体验;
4.2 设计原则
SOLID
简写 | 全拼 | 中文翻译 |
---|---|---|
SRP | The Single Responsibility Principle | 单一责任原则 |
OCP | The Open Closed Principle | 开放封闭原则 |
LSP | The Liskov Substitution Principle | 里氏替换原则 |
ISP | The Interface Segregation Principle | 接口分离原则 |
DIP | The Dependency Inversion Principle | 依赖倒置原则 |
-
单一责任原则:
当需要修改某个类的时候原因有且只有一个(THERE SHOULD NEVER BE MORE THAN ONE REASON FOR A CLASS TO CHANGE)。换句话说就是让一个类只做一种类型责任,当这个类需要承当其他类型的责任的时候,就需要分解这个类。 -
开放封闭原则:
软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。这个原则是诸多面向对象编程原则中最抽象、最难理解的一个。 -
里氏替换原则:
当一个子类的实例应该能够替换任何其超类的实例时,它们之间才具有is-A关系。 -
接口分离原则:
不能强迫用户去依赖那些他们不使用的接口。换句话说,使用多个专门的接口比使用单一的总接口总要好。 -
依赖倒置原则:
1.高层模块不应该依赖于低层模块,二者都应该依赖于抽象
2.抽象不应该依赖于细节,细节应该依赖于抽象
4.3 mobx架构
官方例子
import React from "react"
import ReactDOM from "react-dom"
import { makeAutoObservable } from "mobx"
import { observer } from "mobx-react"
// Model the application state.
class Timer {
secondsPassed = 0
constructor() {
makeAutoObservable(this)
}
increase() {
this.secondsPassed += 1
}
reset() {
this.secondsPassed = 0
}
}
const myTimer = new Timer()
// Build a "user interface" that uses the observable state.
const TimerView = observer(({ timer }) => (
<button onClick={() => timer.reset()}>Seconds passed: {timer.secondsPassed}</button>
))
ReactDOM.render(<TimerView timer={myTimer} />, document.body)
// Update the 'Seconds passed: X' text every second.
setInterval(() => {
myTimer.increase()
}, 1000)
每个UI 组件(TimerView)都可定义一个observer 观察者,无需强制绑定,一旦该组件值发生变化,则会对UI进行自动计算渲染。也即如下流程图,一旦值变化事件发生,则会更新observer的状态,进而计算,进而出发UI重新渲染,而定义好,这些都通过mobx自动完成。
4.4 React前端整体架构
- 所有与后端通信都通过服务层完成;
- 每个容器里的组件都会存在一个仓储与一个模型;
- 所有的服务在仓储层被调用,而非组件层;组件会执行仓储的actions来获取最新状态;
- 展示组件的属性可以直接存储到仓储中,也能直接去仓储中取出;
- 容器或者展示组件可以调用仓储的actions,Mobx能直接将注册过的组件进行自动渲染。
5 小结
这里为什么要用仓储层呢,笔者根据自己理解解释下,
- 如果没加仓储,所有获取后台数据的服务都会泄漏到组件容器中,那样万一哪天需要改服务,则要到各组件中去改,会让人抓狂,而该框架中只需要在仓储层中改即可;
- 另外有了仓储层,比如vue的vuex与react的redux或者mobx,可以在仓储层中作区分,而业务层代码完全可以写成一样,这样更易于vue与react之间的移植;
这应该是属于依赖倒置原则,组件调用依赖于仓储这个抽象并没有依赖于获取数据的对应服务,从而实现了易扩展,易复用,易维护的目的。
版权声明:本文为博主翻译文章+自己理解,部分代码自己写,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://www.cnblogs.com/JerryMouseLi/p/14336688.html