DVA(Data-Driven Application)是一种由阿里巴巴开源的前端应用框架,它结合了Redux、React-Router和React的组件化思想,旨在解决大型应用中状态管理的问题。本文将带你从实战案例解析到入门指南,助你轻松掌握DVA的经典应用。

一、DVA简介

DVA的设计理念是“数据驱动”,它通过将数据流和组件逻辑分离,使得应用的状态管理更加清晰和高效。DVA的核心组件包括:

  • Model:负责数据管理和业务逻辑。
  • View:负责渲染UI。
  • Action:负责处理用户交互和状态更新。
  • Service:负责与后端API交互。

二、实战案例解析

1. 实战案例一:待办事项列表

在这个案例中,我们将使用DVA创建一个简单的待办事项列表应用。

Model

export default {
  namespace: 'todo',
  state: {
    list: [],
  },
  effects: {
    *fetchList({ payload }, { call, put }) {
      const response = yield call(getTodoList, payload);
      yield put({
        type: 'saveList',
        payload: response.data,
      });
    },
  },
  reducers: {
    saveList(state, { payload }) {
      return { ...state, list: payload };
    },
  },
};

View

import React from 'react';
import { connect } from 'dva';
import { Input, Button, List } from 'antd';

const TodoList = ({ todo, dispatch }) => {
  const { list } = todo;
  const { value, list } = this.state;

  const handleSubmit = () => {
    dispatch({
      type: 'todo/fetchList',
      payload: { value },
    });
  };

  return (
    <div>
      <Input value={value} onChange={(e) => this.setState({ value: e.target.value })} />
      <Button onClick={handleSubmit}>搜索</Button>
      <List
        bordered
        dataSource={list}
        renderItem={item => <List.Item>{item}</List.Item>}
      />
    </div>
  );
};

export default connect(({ todo }) => ({ todo }))(TodoList);

2. 实战案例二:天气查询

在这个案例中,我们将使用DVA创建一个天气查询应用。

Model

export default {
  namespace: 'weather',
  state: {
    city: '',
    weather: '',
  },
  effects: {
    *fetchWeather({ payload }, { call, put }) {
      const response = yield call(getWeather, payload);
      yield put({
        type: 'saveWeather',
        payload: response.data,
      });
    },
  },
  reducers: {
    saveWeather(state, { payload }) {
      return { ...state, weather: payload };
    },
  },
};

View

import React from 'react';
import { connect } from 'dva';
import { Input, Button, Alert } from 'antd';

const Weather = ({ weather, dispatch }) => {
  const { city, weather } = this.state;

  const handleSubmit = () => {
    dispatch({
      type: 'weather/fetchWeather',
      payload: { city },
    });
  };

  return (
    <div>
      <Input value={city} onChange={(e) => this.setState({ city: e.target.value })} />
      <Button onClick={handleSubmit}>查询</Button>
      {weather ? <Alert message={weather} type="info" /> : null}
    </div>
  );
};

export default connect(({ weather }) => ({ weather }))(Weather);

三、入门指南

1. 安装DVA

首先,你需要安装DVA和相关依赖:

npm install dva dva-core dva-loading dva-saga

2. 创建项目

使用DVA脚手架创建项目:

dva new my-dva-project

3. 编写Model

models目录下创建Model文件,例如todo.js

// models/todo.js
export default {
  namespace: 'todo',
  state: {
    list: [],
  },
  effects: {
    *fetchList({ payload }, { call, put }) {
      const response = yield call(getTodoList, payload);
      yield put({
        type: 'saveList',
        payload: response.data,
      });
    },
  },
  reducers: {
    saveList(state, { payload }) {
      return { ...state, list: payload };
    },
  },
};

4. 编写View

views目录下创建View文件,例如todo.js

// views/todo.js
import React from 'react';
import { connect } from 'dva';
import { Input, Button, List } from 'antd';

const TodoList = ({ todo, dispatch }) => {
  const { list } = todo;
  const { value, list } = this.state;

  const handleSubmit = () => {
    dispatch({
      type: 'todo/fetchList',
      payload: { value },
    });
  };

  return (
    <div>
      <Input value={value} onChange={(e) => this.setState({ value: e.target.value })} />
      <Button onClick={handleSubmit}>搜索</Button>
      <List
        bordered
        dataSource={list}
        renderItem={item => <List.Item>{item}</List.Item>}
      />
    </div>
  );
};

export default connect(({ todo }) => ({ todo }))(TodoList);

5. 编写路由

routes目录下创建路由文件,例如index.js

// routes/index.js
import React from 'react';
import { Router, Route, Switch } from 'dva/router';
import TodoList from '../views/todo';

const App = ({ history, dispatch, models }) => {
  return (
    <Router history={history}>
      <Switch>
        <Route path="/" component={TodoList} />
      </Switch>
    </Router>
  );
};

export default App;

6. 启动项目

在项目根目录下运行以下命令启动项目:

npm start

四、总结

通过本文的介绍,相信你已经对DVA技术有了初步的了解。DVA作为一种高效的前端应用框架,可以帮助你更好地管理大型应用的状态。希望本文能帮助你轻松掌握DVA的经典应用。