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 指定的其他屬性),數(shù)據(jù)同步將被 Form 接管,這會導致以下結果:
- 你不再需要也不應該用 onChange 來做同步,但還是可以繼續(xù)監(jiān)聽 onChange 等事件。
- 你不能用控件的 value defaultValue 等屬性來設置表單域的值,默認值可以用 getFieldDecorator 或 v-decorator 里的 initialValue。
- 你不應該用 v-model,可以使用 this.form.setFieldsValue 來動態(tài)改變表單值。
大概描述一下就是,一旦在form下使用了v-decorator之后,就不需要使用v-model,其實實現(xiàn)上也有所相同,在自定義組件中需要自己定以model的東西,詳細可以查閱官網。
簡單說明
通俗來說,想使用v-decorator,就必須要有個value想子組件傳遞數(shù)據(jù)。
和一個change方法將子組件的數(shù)據(jù)變動告訴父組件,下面看部分代碼
? model: { ? ? prop: 'value', ? ? event: 'change' ? }, ?? ? props: { ? ? value: { ? ? ? type: String ? ? ? // 這個參數(shù)是v-decorator給子組件傳值用的 ? ? ? // 這里不要給默認值, 在form下使用會爆警告 Warning: SquareUpload `default value` can not collect, ?please use `option.initialValue` to set default value. ? ? } ? } ? ?watch: { ? ? // 監(jiān)聽數(shù)據(jù)變化,及時提交給父組件 ? ? 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 ? ? ? // 這個參數(shù)是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 ? ? }, ? ? // 最多上傳數(shù)量 ? ? 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: { ? ? // 監(jiān)聽數(shù)據(jù)變化,及時提交給父組件 ? ? 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) ? ? ? } ? ? }, ? ? // 監(jiān)聽父組件傳遞過來的圖片列表信息 ? ? value: { ? ? ? deep: true, ? ? ? immediate: true, ? ? ? handler: function (newV) { ? ? ? ? // 數(shù)據(jù)為空的三種情況 ? ? ? ? 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 ,數(shù)據(jù)同步由Form接管,這會導致以下結果
- 你不在需要也不應該用 onChange 同步,但是可以繼續(xù)監(jiān)聽 onChange事件
- 你不能用控件的 value defaultValue等屬性來設置表單域的值,默認值可以用 getFieldDecorator 或 v-decorator里的 initialValue
- 你不應該用 v-model 可以使用 this.form.setFieldsValue 來動態(tài)改變表單值
定義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: '設置值' })
清空表單數(shù)據(jù)
this.form.resetFields()
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
npm install卡在“sill idealTree buildDeps“問題的兩種解
本文主要介紹了npm install卡在“sill idealTree buildDeps“問題的兩種解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-03-03Vue循環(huán)中多個input綁定指定v-model實例
這篇文章主要介紹了Vue循環(huán)中多個input綁定指定v-model實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08Vue+Openlayer實現(xiàn)圖形的拖動和旋轉變形效果
Openlayer具有自己的擴展插件ol-ext,可以用來實現(xiàn)圖形的拖拽、旋轉、縮放、拉伸、移動等操作,本文將主要介紹通過Openlayer實現(xiàn)圖形的拖動和旋轉,需要的同學可以學習一下2021-11-11vue中生成條形碼(jsbarcode)和二維碼(qrcodejs2)的簡單示例
在vue項目中難免遇到有要生成條形碼或者二維碼的功能需求,下面這篇文章主要給大家介紹了關于vue中生成條形碼(jsbarcode)和二維碼(qrcodejs2)的相關資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下2022-12-12