做该项目的初衷是想知道浏览器与数据库交互的过程,而由于现实中没有数据库,所以选用了 leancloud 这个云数据管理平台,通过这个平台,可以对数据进行增删改查等一系列工作,另一方面,它的 API 也的确很好用。
一、简单介绍下 leancloud
leancloud 是一个自带数据库和增删改查(CRUD)功能的后台系统,它会将数据封装在一个个对象里面,并通过提供的 API 进行调用和查询,同时,对象与对象之间也可以关联,比如将一个对象的地址作为另一个对象"键值对"中的值,这两个对象便关联了起来,比如将一个文件与一个简单对象关联起来。下面,来看看项目中的代码吧,主要实现的功能有两个:一个是登录、注册时发送数据验证请示,另一个是上传图片和查看历史数据时发送数据添加、查询请示。
// 安装和引入库
yarn add leancloud-storage
import AV from "leancloud-storage"
// 初始化
AV.init({
appId: "itWl2eh5wy3fdbGo6i8RFSMe-MdYXbMMI",
appKey: "4hzHzkjpIokCLH6wxcPTbc4y",
serverURL: "https://itwl2eh5.api.lncldglobal.com",
});
// 注册、登录:数据验证
const Auth = {
register(username, password) {
const user = new AV.User();
user.setUsername(username);
user.setPassword(password);
return new Promise((resolve, reject) =>
user.signUp().then(
(user) => resolve(user),
(error) => reject(error) // 注册失败返回的原因一般是用户名已存在
)
);
},
login(username, password) {
return new Promise((resolve, reject) =>
AV.User.logIn(username, password).then(
(user) => resolve(user),
(error) => reject(error)
)
);
},
logout() {
AV.User.logOut();
},
getCurrentUser() {
return AV.User.current();
},
};
// 历史数据:数据添加、查询
const Uploader = {
add(file, filename) {
const item = new AV.Object("Image");
const avFile = new AV.File(filename, file);
item.set("owner", AV.User.current());
item.set("filename", filename);
item.set("url", avFile); // 将普通对象与文件关联
return new Promise((resolve, reject) => {
item.save().then(
(serverFile) => {
resolve(serverFile);
},
(error) => {
reject(error);
}
);
});
},
find() {
const query = new AV.Query("Image");
query.include("owner");
query.equalTo("owner", AV.User.current());
return new Promise((resolve, reject) => {
query
.find()
.then((results) => {
resolve(results);
})
.catch((error) => reject(error));
});
},
};
// 导出模块
export { Auth, Uploader };
二、使用 mobx 对状态进行管理
在 react 中,当数据需要变更时,我们一般通过调用 setState() 方法更改数据,并重新渲染页面,但是,除此之外,我们也可以使用一些第三方库对数据进行动态观察,使 react 组件变成响应式组件,当数据发生变化时便可以直接重新渲染页面或者执行一些其它操作。而现在,比较流行的状态管理库有 redux 和 mobx,本项目使用的是 mobx,redux 以后有机会再使用。
// 安装和引入 mobx、mobx-react
yarn add mobx
yarn add mobx-react
import { makeAutoObservable, runInAction } from "mobx"
import { observer } from "mobx-react"
// 文件:stores.js
class Stores {
constructor() {
makeAutoObservable(this) // 自动观察模式
}
isUpLoading = false
serverFile = null
uploadImg(file, filename) {
runInAction(() => {this.isUpLoading = true}) // 严格模式下,在异步操作中更改数据需在 action 中更改。
this.serverFile = null
return new Promise((resolve, reject) => {
Uploader.add(file, filename)
.then((serverFile) => {
runInAction(() => {this.serverFile = serverFile;});
resolve(serverFile)
})
.catch((err) => {
reject(err)
})
.finally(() => {
runInAction(() => {this.isUpLoading = false})
})
})
}
}
export default new Stores()
// 文件:Component.js
const Component = observer(()=>{
...some code
}) // 使 react 组件变成响应式组件
三、使用 styled-component
写 css 样式时,一般有三种方法,最简单的就是直接在 HTML 标签上添加 style 属性,或者引入 css 文件,而如果想要在 js 中写 css 的话,就可以引入和使用第三方库 styled-component。下面介绍一下 styled-component 的常用语法。
// 1、基本用法
const Div = styled.div`
font-size:16px;
line-height: 1.2
`
// 2、基于 props 定制主题
const Div = styled.div`
color : ${props=>props.color}
background: ${props => props.primary ? 'palevioletred' : 'white'}
`
<Div color = {color} > HTML 示例 </Div>
// 3、兼容其它组件
import Component from "componentName"
// 相当于直接在该组件的 className 中添加样式
const StyledComponent = styled(Component)`
font-size:16px;
line-height: 1.2
`
四、在 react-router-dom 中使用懒加载
正常来说,每次打开网页,都会调用所有引用的数据。当数据量小时,没什么问题;但当数据量大时,便会影响到网页的性能,此时,使用懒加载的方式就显得尤为重要。它的原理是:当打开网页时,它只会调用当前网页的数据,只有点击另一个链接/路由时,该链接/路由才会调用它自身所需的数据。
// 文件:index.js
const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(<Router><App /></Router>)
// 文件:APP.js
import { Routes, Route } from "react-router-dom"
import { lazy, Suspense } from "react"
import Loading from "./components/Loading"
// 懒加载,import() 动态引入
const Home = lazy(() => import("./pages/Home"))
const History = lazy(() => import("./pages/History"))
const About = lazy(() => import("./pages/About"))
function App() {
return (
<main className="main">
<Suspense fallback={<Loading />}> // 网页加载期间,展示 Loading 组件
<Routes>
<Route path="/" element={<Home />} exact />
<Route path="/home" element={<Home />} />
<Route path="/history" element={<History />} />
<Route path="/about" element={<About />} />
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
</Routes>
</Suspense>
</main>
)
}
五、使用第三方 UI 组件库 Ant Design
Ant Design 是一个很好用的 UI 组件库,在开发的时候,有时候不想将过多的时候用在 UI 组件的样式和功能设计上,那么直接导入封装好的 UI 组件,不失为一种好的方法。当然,自己也要知道 UI 组件的具体实现原理,我针对此也专门做过一个项目,点击 我的 wu-ui-react 项目 可以详细了解。话不多说,本项目主要引入和使用了 Ant Design 的 Form 表单和 List 列表两个组件,而具体代码由于过长,就不在这里展示,感兴趣的可以直接 Ant Design 官网查看或者直接到文末的原代码链接中查看。
六、总结
这是一个基于 React 框架实现的图片上传项目,通过该项目,可以将数据上传并存储于 leancloud,并且在需要的时候,可以通过 imgURL 地址引用该图片,同时,也可以在该网页轻松查询到自己上传图片的历史数据,而不会丢失。另外,在做项目的过程中,通过使用第三方库来设计 UI、管理组件状态等,节省了很多时间,极大程度地提高了开发效率。
GitHub 源码链接:wgbcode/react-imgURL (github.com)
Gitee imgURL 网页预览:imgURL 图床 (gitee.io)