, ,

React DVA 和 Vue (Pinia)

1. React DVA 示例 在 DVA 中,你需要将状态、同步修改、异步请求严格分离,并使用 Genera…

1. React DVA 示例

在 DVA 中,你需要将状态、同步修改、异步请求严格分离,并使用 Generator 函数处理异步。

Model 定义:

export default {
  namespace: 'user',
  state: {
    userInfo: null,
    loading: false
  },
  reducers: {
    // 同步修改:必须返回新对象(不可变性)
    saveUser(state, { payload }) {
      return { ...state, userInfo: payload, loading: false };
    },
    setLoading(state, { payload }) {
      return { ...state, loading: payload };
    }
  },
  effects: {
    // 异步操作:使用 Generator 函数
    *fetchUser({ payload }, { call, put }) {
      yield put({ type: 'setLoading', payload: true });
      const response = yield call(api.getUserInfo, payload);
      yield put({ type: 'saveUser', payload: response.data });
    }
  }
};

组件使用:

import { connect } from 'dva';

const UserProfile = ({ user, dispatch }) => {
  useEffect(() => {
    // 触发 effects 中的异步操作
    dispatch({ type: 'user/fetchUser', payload: { id: 1 } });
  }, []);

  return <div>{user.loading ? '加载中...' : user.userInfo?.name}</div>;
};

// 通过 connect 映射 state 到组件的 props
export default connect(({ user }) => ({ user }))(UserProfile);

2. Vue (Pinia) 示例

在 Pinia 中,状态修改和异步逻辑可以合并在 actions 中,代码更加直观和紧凑。

Store 定义:

import { defineStore } from 'pinia';

export const useUserStore = defineStore('user', {
  state: () => ({
    userInfo: null,
    loading: false
  }),
  actions: {
    // 异步和同步操作直接写在一起
    async fetchUser(id) {
      this.loading = true; // 直接修改 state(Pinia 底层自动追踪)
      const response = await api.getUserInfo(id);
      this.userInfo = response.data; // 直接赋值
      this.loading = false;
    }
  }
});

组件使用:

<script setup>
import { storeToRefs } from 'pinia';
import { useUserStore } from '@/stores/user';

const userStore = useUserStore();
// 使用 storeToRefs 解构保持响应式
const { loading, userInfo } = storeToRefs(userStore);

// 直接调用 action
userStore.fetchUser(1);
</script>

<template>
  <div>{{ loading ? '加载中...' : userInfo?.name }}</div>
</template>

核心差异总结

  1. 异步语法:DVA 必须使用 *fetchUser (Generator) + yield call + yield put;Vue 只需要普通的 async fetchUser + await
  2. 状态修改:DVA 的 reducers 必须 return { ...state } 返回新对象;Vue 的 Pinia 可以直接 this.loading = true 赋值。
  3. 组件绑定:DVA 需要 connect 包裹组件并手动映射 props;Vue 只需 useUserStore() 引入即可,模板自动响应数据变化。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

About the Author

每个人都有自己得时区,在自己得时区里,一切都是准时的。

BlockSpare — News, Magazine and Blog Addons for (Gutenberg) Block Editor