我的 react-imgURL 项目

303 阅读5分钟

做该项目的初衷是想知道浏览器与数据库交互的过程,而由于现实中没有数据库,所以选用了 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 以后有机会再使用。

image.png
// 安装和引入 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)