vue-ele-form 支持两种请求方式,通过事件发起请求和请求函数发起请求,二者主要是对错误回显的处理方式不同


事件方式


当发起请求时, 会抛出 $emit('request', data), 需要传递 isLoading 参数,当服务器返回错误时,需要传递 formError 参数


<!-- 伪代码 -->
<template>
  <ele-form
    :isLoading="isLoading"
    :formError="formError"
    :formDesc="formDesc"
    v-model="formData"
    @request="handleRequest"
  ></ele-form>
</template>
<script>
// 伪代码
export default {
  data() {
    return {
      // 请求状态
      isLoading: false,
      // 表单错误消息
      formError: {},
      formData: {},
      formDesc: {
        username: {
          type: 'input',
          label: '姓名'
        }
      }
    }
  },
  methods: {
    // 发起请求, 被注入 data
    async handleRequest(data) {
      if (this.isLoading) return // 判断状态
      try {
        this.isLoading = true // 更改状态
        // 发送请求
        const response = await fetch(
          'https://jsonplaceholder.typicode.com/posts/1',
          { method: 'get', data: data }
        ).then(res => res.json())
        console.log(response)
        // 成功处理
        this.$message.success('添加成功')
        // this.$router.back() // 跳转回上一页
      } catch (error) {
        // 处理错误
        // 为了表单同步显示后端返回的错误, 需要将错误信息传递给表单
        this.formError = { username: '用户名不存在' }
      } finally {
        this.isLoading = false
      }
    }
  }
}
</script>



函数方式

当发起请求时, 需要传递 request-fn 参数, 请求结束后, 会根据状态抛出: $emit('request-success', data) / $emit('request-error', error) / $emit('request-finish')


<!-- 伪代码 -->
<template>
  <ele-form
    :request-fn="handleRequest"
    :formDesc="formDesc"
    v-model="formData"
    @request-success="handleRequestSuccess"
  ></ele-form>
</template>

<script>
// 伪代码
export default {
  data() {
    return {
      formData: {},
      formDesc: {
        username: {
          type: 'input',
          label: '姓名'
        }
      }
    }
  },
  methods: {
    // 如果在异常的处理上,当发生异常时,error.message 就是错误信息的话,可以直接:
    // 直接赋值就行了
    handleRequest(data) {
        return fetch('https://jsonplaceholder.typicode.com/posts/1', {
        method: 'get',
        data: data
      }).then(res => res.json())
    },
    handleRequestSuccess() {
      this.$message.success('添加成功')
      // this.$router.back()
    }
  }
}
</script>


或者


<!-- 伪代码 -->
<template>
  <ele-form
    :request-fn="handleRequest"
    :formDesc="formDesc"
    v-model="formData"
    @request-success="handleRequestSuccess"
  ></ele-form>
</template>

<script>
// 伪代码
export default {
  data() {
    return {
      formData: {},
      formDesc: {
        username: {
          type: 'input',
          label: '姓名'
        }
      }
    }
  },
  methods: {
    // 如果没有做过处理,则需要返回Promise
    handleRequest(data) {
      // 1.必须返回一个Promise对象
      // 2.当出现异常的时候, 返回的错误信息, 必须是以字段为key, 错误原因为 message的对象或者错误:
      // { name: '用户名不存在', password: '密码不正确' } 或者 new Error(JSON.stringify({ name: '用户名不存在', password: '密码不正确' }))
      return new Promise(async (resolve, reject) => {
        try {
          // 发送请求
          const response = await fetch(
            'https://jsonplaceholder.typicode.com/posts/1',
            { method: 'get', data: data }
          ).then(res => res.json())
          console.log(response)
          // 成功处理
          resolve(response)
        } catch (error) {
          // 经过一系列操作
          reject(
            new Error(
              JSON.stringify({ name: '用户名不存在', password: '密码不正确' })
            )
          )
        }
      })
    },
    handleRequestSuccess() {
      this.$message.success('添加成功')
      // this.$router.back()
    }
  }
}
</script>


属性详解

isLoading

含义:提交状态,防止用户多次点击

类型:Boolean

当使用外部提交时,需要手动传入 isLoading 状态,例如:


<ele-form
    :isLoading="true"
><ele-form>


image.png

formError

含义:服务端校检后,返回错误的信息,用于展示到页面上(非前端rules校检)

类型:Object

此参数同上,都是当外部提交时,需要传入的参数,传入后表单会标红,同时会有错误提示,例如:


<template> 
  <ele-form
    :form-error="formError"
    @request="handleRequest"
  ></ele-form>
</template>

<script>
export default {
    data () {
    return {
      formError: {} // 对象类型
    }
  },
  methods: {
    async handleRequest (data) {
      // 伪代码
      try {
        // 发送请求
        // await createArticle(data)
        throw new Error()
      } catch (error) {
        // 经过一系列处理, 拿到错误信息, 并赋值, key 是字段, value 是错误信息
        this.formError =this.formError = { title: '文章标题不得超过5个字', content: '文章内容不能为空' }
      }
    }
  }
}
</script>


image.png


requestFn

含义:两种请求方案中的内部请求方案,需要将一个请求函数传递过去(不是事件,不能v-on或者@),该参数必须返回一个Promise实例,并且当异常时,reject的必须是错误信息对象

类型:Function

如果Promise实例是 resolved 状态,则代表请求成功,否则请求失败,同时无论请求成功或者失败都会报出响应事件,例如:


<template>
  <ele-form
    :request-fn="requestFn"
        @request-success="handleRequestSuccess"
        @request-error="handleRequestError"
  ></ele-form>
</template>

<script>
export default {
  methods: {
    requestFn (data) {
       // 伪代码
      return new Promise(async (resolve, reject) => {
        try {
          const res = await createArticle(data)
          resolve(res)
        } catch (error) {
          // 经过一系列操作
          reject(new Error({ title: '标题不得超过5个字', content: '内容不得为空' }))
        }
      })
    }
    // 成功后的进一步处理
    handleRequestSuccess () {
      this.$message.success('创建成功')
      // this.$router.back() // 回到上一页
    }
    // 失败后的进一步处理(内部已经有提示)
    handleRequestError () {
    }
  }
}
</script>


这里需要注意的是,假如你已经对请求函数做过封装, resolved 时返回响应结果, rejected 时返回异常信息,则可以大大简化 requestFn ,例如


methods: {
    requestFn (data) {
        return createArticle(data)  // 直接返回
    },
        
    // 或者更直接
    requestFn: createArticle
}


这就是为什么会有两种设计了