简单粗暴(糙)| 图解 |基于 umi + dva 数据处理以及数据mock

1,276 阅读4分钟

前言🐢

看完你能收获🍕

基于umi + dva 的数据处理

  • 各层级组件的通信
  • 数据mock

的最小最简单最粗糙操作。
本文简单粗暴,就是让你不用看别的,就知道下面这几个东东就能开始整页面。

默认你知道🤔

对react、umi有所了解...基本的函数组件,umi的文件目录能明白是啥,会启动(yarn start)

了解dva😏

dvajs官网

dva 首先是一个基于 reduxredux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-routerfetch,所以也可以理解为一个轻量级的应用框架。

#特性

  • 易学易用,仅有 6 个 api,对 redux 用户尤其友好,配合 umi 使用后更是降低为 0 API
  • elm 概念,通过 reducers, effects 和 subscriptions 组织 model
  • 插件机制,比如 dva-loading 可以自动处理 loading 状态,不用一遍遍地写 showLoading 和 hideLoading
  • 支持 HMR,基于 babel-plugin-dva-hmr 实现 components、routes 和 models 的 HMR

图解dva
就是这东东没有新的概念和api,就是基于redux等东东的封装,所以非常好上手。


快速上手🐱‍🏍

我会想带你配置一下,并且创建几个文件,我再一个个解释,看完你至少能套着我这份最简单最小的demo进行小小的开发。最后也会有一张图解全貌。
umi自带dva,但在配合umi时,要记得在.umirc.js配置中打开 dva 开关。

还用到了umi自带的,也要打开antd

几个文件

先复制了,然后看结合最后的图解看代码注释,可以自己浅画一下各个组件的联系。

src/pages/dva/index.js

import React from 'react'
//两个子组件
import Search from './search'
import Lists from './lists'
import { connect } from 'dva'

const Dva = props => {
  return (
    <div>
    //将父组件的props用展开运算符传入
      <Search {...props} />/
      <Lists {...props} />
    </div>
  )
}

//用connect导出ui组件,并将state中的search作为props传入子组件
export default connect(({ search }) => ({
  search,
}))(Dva)

ui组件用connect导出。
connect的作用是将组件和models结合在一起,将models中的state绑定到组件的props中。
并提供一些额外的功能,譬如dispatch
最后返回一个 React 组件,通常称为容器组件,即原始 UI 组件的容器,即在外面包了一层 State。

connect 方法传入的第一个参数是 mapStateToProps 函数,该函数需要返回一个对象,用于建立 State 到 Props 的映射关系。】

src/pages/search.js

import React, { useState } from 'react'
//本质是封装antd-mobile
import { SearchBar } from 'antd-mobile'

//该组件用来做搜索相关的功能

const Search = props => {
  const [value, setValue] = useState('')
  const handleChange = value => {
    setValue(value)
  }
  

  const handleSubmit = () => {
    //console.log('props', value)
    props.dispatch({
      //dispatch的选择(命名空间/请求方法标志),以及参数,会去到后面的models文件夹中去找
    //type: 'search/getLists',
      type: 'search/getListsAsync',
      payload: value,
    })
  }
  return (
    <div>
      <SearchBar
        autoFocus
        value={value}
        onChange={handleChange}
        onSubmit={handleSubmit}
      />
    </div>
  )
}

export default Search

src/pages/lists.js

import React from 'react'
import { List } from 'antd-mobile'

//简简单单展示一下
const Lists = props => {
  //console.log(props.search)

  //从connect来的search...
  const { text, lists } = props.search
  return (
    <div>
      <h1>text:{text}</h1>
      <List>
        {lists.map((item, i) => (
          <List.Item key={i}>{item}</List.Item>
        ))}
      </List>
    </div>
  )
}

export default Lists

在src文件夹下创建一个新的子文件夹 models —— 用来存放dva相关的代码。
src/models/search.js

//从services(在后面说)中引用调用异步的方法getLists
import { getLists } from '@/services/search'

export default {
  //命名空间
  namespace: 'search',
  //通过connect与ui组件互联的state
  state: {
    text: 'dva',
    lists: [],
  },
  
  //方法
  //同步
  reducers: {
    getLists(state, action) {
      return {
        ...state,
        lists: Array(10).fill(action.payload),
      }
    },
  },
  //异步
  effects: {
    //call 调用异步函数,puts:事件派发
    *getListsAsync({ payload }, { call, put }) {
      const res = yield call(getLists, payload)//这里的getLists是引入的异步方法
      yield put({
        type: 'getLists',
        payload: res.lists,
      })
    },
  },
}

再创建一个services 文件夹——放置http相关异步请求

这是nodejs的部分,即这里面的console.log() 是输出在终端中的 因为封装的是express 所以其中的写法与express框架相似。

src/services/search.js
这其中的api自然是数据mock

// export const getLists = value => {
//   return fetch(`/api/getLists?value=${value}`).then(res =>
//     res.json().catch(err => {
//       console.error(err)
//     }),
//   )
// }
export const getLists = value => {
  return fetch(`/api/getListsAsync?value=${value}`).then(res =>
    res.json().catch(err => {
      console.error(err)
    }),
  )
}

mock/search.js
注意他不是在src中的,这mock文件夹是umi自带的。

export default {
  //value支持函数类型(异步)、json类型(同步)
  'GET /api/getLists': {
    lists: ['a', 'b', 'c'],
  },
  'GET /api/getListsAsync': (req, res) => {
    console.log(req)
    setTimeout(() => {
      res.json({
      //最终显示效果是这里的
        lists: Array(10).fill(req.query.value),
      })
    }, 1000)
  },
}

页面效果

image.png

图解

可以看的出来啊,非常的简陋、非常的丑...先凑合着配合理解吧,刚开始用平板写字还是有不习惯啊,以后一定会更好看的。
!




希望对你有所帮助,有的话点个赞羞辱一下我丑陋的画技吧。
👋