antd vue中,如何在form表单中的自定义组件使用v-decorator

 更新时间:2023年04月21日 10:43:23   作者:散装java  
antd vue中,在form表单中的自定义组件使用v-decorator问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

antd vue中在form表单中的自定义组件使用v-decorator

问题描述

项目需要,在表单中上传图片,所以要自己定以一个上传图片的组件,直接在form中使用,但是普通的自定义组件无法使用表单的v-decorator。

分析

转自官方的一段话

this.form.getFieldDecorator(id, options) 和 v-decorator="[id, options]"

经过 getFieldDecorator或v-decorator 包装的控件,表单控件会自动添加 value(或 valuePropName 指定的其他属性) onChange(或 trigger 指定的其他属性),数据同步将被 Form 接管,这会导致以下结果:

  • 你不再需要也不应该用 onChange 来做同步,但还是可以继续监听 onChange 等事件。
  • 你不能用控件的 value defaultValue 等属性来设置表单域的值,默认值可以用 getFieldDecorator 或 v-decorator 里的 initialValue。
  • 你不应该用 v-model,可以使用 this.form.setFieldsValue 来动态改变表单值。

大概描述一下就是,一旦在form下使用了v-decorator之后,就不需要使用v-model,其实实现上也有所相同,在自定义组件中需要自己定以model的东西,详细可以查阅官网。

简单说明

通俗来说,想使用v-decorator,就必须要有个value想子组件传递数据。

和一个change方法将子组件的数据变动告诉父组件,下面看部分代码

  model: {
    prop: 'value',
    event: 'change'
  },
  
  props: {
    value: {
      type: String
      // 这个参数是v-decorator给子组件传值用的
      // 这里不要给默认值, 在form下使用会爆警告 Warning: SquareUpload `default value` can not collect,  please use `option.initialValue` to set default value.
    }
  }
   watch: {
    // 监听数据变化,及时提交给父组件
    fileList: {
      deep: true,
      immediate: true,
      handler: function (newV, oldV) {
      // 向父组件更新
        this.$emit('change', temp)
      }
    }
}

注意:value不要给默认值,不然会爆警告default value can not collect, please use option.initialValue to set default value.

例子,封装一个上传图片的组件,在form中使用

子组件

<template>
  <div class="clearfix">
    <a-upload
      :showRemoveIcon="false"
      :action="url"
      list-type="picture-card"
      :file-list="fileList"
      @preview="handlePreview"
      @change="handleChange"
    >
      <div v-if="fileList.length < max && isShow">
        <a-icon type="plus" />
        <div class="ant-upload-text">
          Upload
        </div>
      </div>
    </a-upload>
    <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
      <img alt="example" style="width: 100%" :src="previewImage" />
    </a-modal>
  </div>
</template>
<script>
import config from '@/views/constant/constantConfig'
function getBase64 (file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.readAsDataURL(file)
    reader.onload = () => resolve(reader.result)
    reader.onerror = error => reject(error)
  })
}
export default {
  name: 'SquareUpload',
  model: {
    prop: 'value',
    event: 'change'
  },
  props: {
    value: {
      type: String
      // 这个参数是v-decorator给子组件传值用的
      // 这里不要给默认值, 在form下使用会爆警告 Warning: SquareUpload `default value` can not collect,  please use `option.initialValue` to set default value.
    },
    // 上传地址
    url: {
      type: String,
      default: config.uploadUrl
    },
    isShow: {
      type: Boolean,
      default: true
    },
    // 最多上传数量
    max: {
      type: Number,
      default: 8
    }
  },
  data () {
    return {
      previewVisible: false,
      previewImage: '',
      fileList: []
    }
  },
  methods: {
    handleCancel () {
      this.previewVisible = false
    },
    // 处理预览
    async handlePreview (file) {
      if (!file.url && !file.preview) {
        file.preview = await getBase64(file.originFileObj)
      }
      this.previewImage = file.url || file.preview
      this.previewVisible = true
    },
    handleChange ({ file, fileList }) {
      this.fileList = fileList
    }
  },
  watch: {
    // 监听数据变化,及时提交给父组件
    fileList: {
      deep: true,
      immediate: true,
      handler: function (newV, oldV) {
        if (this.fileList.length === 0) {
          return
        }
        this.fileList = newV
        const temp = this.fileList.filter(item => item.status !== 'uploading').map(item => (item.uid < 0 && item.name) || item.response.data.newFileName).join(',')
        // 向父组件更新
        this.$emit('change', temp)
      }
    },
    // 监听父组件传递过来的图片列表信息
    value: {
      deep: true,
      immediate: true,
      handler: function (newV) {
        // 数据为空的三种情况
        if (newV === null || newV === '' || newV === undefined) {
          this.fileList = []
          return
        }
        let count = -1
        let temp = []
        const tempList = []
        temp = newV.split(',')
        temp.forEach(item => {
          tempList.push({
            uid: count,
            name: item,
            status: 'done',
            url: config.baseImgUrl + item
          })
          count--
        })
        this.fileList = tempList
      }
    }
  }
}
</script>
<style>
  /* you can make up upload button and sample style by using stylesheets */
  .ant-upload-select-picture-card i {
    font-size: 32px;
    color: #999;
  }

  .ant-upload-select-picture-card .ant-upload-text {
    margin-top: 8px;
    color: #666;
  }
</style>

父组件使用

        <a-form-item
          label="上传标题图片"
          :labelCol="labelCol"
          :wrapperCol="wrapperCol">
          <SquareUpload :isShow="!showable" v-decorator="['serveTitleImg', {rules: [{required: true, message: '请选择图片'}]}]"></SquareUpload>
        </a-form-item>

v-decorator antd vue的理解

v-decorator是ant Design的控件验证属性

经过 getFieldDecorator 或 v-decroator 包装的控件,表单控件会自动添加 value onChange 或者 trigger ,数据同步由Form接管,这会导致以下结果

  • 你不在需要也不应该用 onChange 同步,但是可以继续监听 onChange事件
  • 你不能用控件的 value defaultValue等属性来设置表单域的值,默认值可以用 getFieldDecorator 或 v-decorator里的 initialValue
  • 你不应该用 v-model 可以使用 this.form.setFieldsValue 来动态改变表单值

定义form:

<template>
  <div class="main">
    <a-form
      id="formLogin"
      class="user-layout-login"
      ref="formLogin"
      :form="form"
      @submit="handleSubmit"
    >
        <a-form-item>
            <a-input
              size="large"
              type="text"
              placeholder="账户: "
              v-decorator="[
                'username',
                {initialValue:'',rules: [{ required: true, message: '请输入帐户名或邮箱地址' }, { validator: handleUsernameOrEmail }], validateTrigger: 'change'}
              ]"
            >
              <a-icon slot="prefix" type="user" :style="{ color: 'rgba(0,0,0,.25)' }" />
            </a-input>
          </a-form-item>
    </a-form>
 </div>
</template>
 
<script>
...
export default {
  ...
  data () {
    return {
      ...
      form: this.$form.createForm(this),
    }
  },
  created () {
    
  },
  ...
} 
</script>

v-decroator取值

this.form.vaidateFields((err, values) => {
    console.log(values) // {username: ''}
})

v-decroator赋值

this.form.setFieldsValue({
    username: '设置值'
})

清空表单数据

this.form.resetFields()

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 详解如何解决Vue和vue-template-compiler版本之间的问题

    详解如何解决Vue和vue-template-compiler版本之间的问题

    这篇文章主要介绍了详解如何解决Vue和vue-template-compiler版本之间的问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • Vue封装组件利器之$attrs、$listeners的使用

    Vue封装组件利器之$attrs、$listeners的使用

    vue通信手段有很多种,props/emit、vuex、event bus、provide/inject等,还有一种通信方式,那就是$attrs和$listeners,下面这篇文章主要给大家介绍了关于Vue封装组件利器之$attrs、$listeners使用的相关资料,需要的朋友可以参考下
    2021-12-12
  • 深入探讨Vue 3中的组合式函数编程方式

    深入探讨Vue 3中的组合式函数编程方式

    Vue 3中引入了组合式函数编程方式,可以更好地实现代码的复用和可维护性。通过定义可组合的函数,可以将组件的逻辑和状态进行拆分和组合,实现更灵活的代码组织方式。同时,组合式函数也支持响应式数据和生命周期钩子函数,更加贴近Vue开发的实际场景
    2023-05-05
  • Vue Element plus使用方法梳理

    Vue Element plus使用方法梳理

    Element Plus,由饿了么大前端团队开源出品的一套为开发者、设计师和产品经理准备的基于 Vue 3.0 的组件库,Element Plus是基于Vue3面向设计师和开发者的组件库,提供了配套设计资源,帮助你的网站快速成型
    2022-12-12
  • Element Cascader 级联选择器的使用示例

    Element Cascader 级联选择器的使用示例

    这篇文章主要介绍了Element Cascader 级联选择器的使用示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • 在vue项目中封装echarts的步骤

    在vue项目中封装echarts的步骤

    这篇文章主要介绍了在vue项目中封装echarts的步骤,帮助大家更好的理解和使用vue,感兴趣的朋友可以了解下
    2020-12-12
  • Vue的Flux框架之Vuex状态管理器

    Vue的Flux框架之Vuex状态管理器

    本文内容主要参考官方教程,为了方便理解,用更加通俗的文字讲解Vuex,也原文内容做一些重点引用。希望会对你有所帮助。
    2017-07-07
  • ant design Vue 纯前端实现分页问题

    ant design Vue 纯前端实现分页问题

    这篇文章主要介绍了ant design Vue 纯前端实现分页问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • vue格式化element表格中的时间为指定格式

    vue格式化element表格中的时间为指定格式

    这篇文章主要介绍了vue中格式化element表格中的时间为指定格式,需要的朋友可以参考下
    2022-05-05
  • vue移动端模态框(可传参)的实现

    vue移动端模态框(可传参)的实现

    这篇文章主要介绍了vue移动端模态框(可传参)的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11

最新评论