温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

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

发布时间:2023-04-21 15:05:17 来源:亿速云 阅读:79 作者:iii 栏目:开发技术

这篇文章主要介绍了antd vue中怎么在form表单的自定义组件里使用v-decorator的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇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"  :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" : />
                </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()

    关于“antd vue中怎么在form表单的自定义组件里使用v-decorator”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“antd vue中怎么在form表单的自定义组件里使用v-decorator”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注亿速云行业资讯频道。

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI