在Vue里模拟Umi的useRequest

585 阅读1分钟

废话不多说直接上代码

import Vue from 'vue';

function useRequest(func) {
  let xhr = void 0;

  const state = Vue.observable({
    data: void 0,
    loading: false,
    error: void 0,
  });

  const actions = {
    run (...args) {
      state.loading = true;
      xhr = func(...args)
        .then((res) => state.data = res)
        .catch((error) => state.error = error)
        .finally(() =>  state.loading = false);
    },
    cancel () {
      if (xhr && xhr.abort) {
        xhr.abort();
      }
    }
  };

  return [state, actions];
}

// 假设是一个异步请求并返回 xhr
function fetch (params) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve([{id: 1, name: 'xxx-1'}, {id: 2, name: 'xxx-2'}]);
    }, 3000);
  });
}

const [state, actions] = useRequest(fetch);

export default {
  name: 'Dev',

  mounted() {
    actions.run();
    this.$once('hook:beforeDestroy', () => actions.cancel());
  },

  render () {
    if (state.loading) {
      return <div>loading...</div>
    } else if (state.error){
      return <div>{state.error}</div>
    } else if (Array.isArray(state.data)){
      return (
        <div>
          {state.data.map((row, key) => {
            const {id, name} = row || {};
            return <div key={key}>{`ID:${id} Name:${name}`}</div>;
          })}
        </div>
      );
    }
  }
}