温馨提示×

温馨提示×

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

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

vue ant design封装弹窗表单如何使用

发布时间:2022-06-01 11:00:39 来源:亿速云 阅读:230 作者:iii 栏目:开发技术

本篇内容介绍了“vue ant design封装弹窗表单如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

vue ant design 封装弹窗表单

<template>     <div id="formForm">         <a-modal              :visible="true"              :title='title'              @ok="handleOk('ok')"              @cancel="handleOk('return')"              :centered="true"              :confirmLoading="confirmLoading"             :width="width">             <a-form :form="formState" :label-col="{ span: 5 }" :wrapper-col="{ span: 17 }">                 <div v-for="itme in formData" :key="itme.value" >                     <!-- 输入款 -->                     <a-form-item                          :label="itme.label"                          v-if="itme.type === 'input'"                          :label-col="{ span: itme.labelCol ? itme.labelCol : 5 }"                          :wrapper-col="{ span: itme.wrapper ? itme.wrapper : 17 }">                         <a-input                              v-decorator="[itme.value, { rules: [{                                                          required: itme.required?itme.required:false,                                                          message: itme.message?itme.message:' ' },                                                          {validator: itme.validator}]}]"                             :placeholder="!itme.placeholder ? itme.label : itme.label"                              allowClear>                             <!-- 插入输入框的下拉框选择器 -->                             <a-select                                 v-if="itme.select && itme.select.length>0"                                 slot="addonBefore"                                 v-decorator="[ itme.header ]"                                 >                                 <a-select-option v-for="select in itme.select" :key="select.value">                                     {{select.label}}                                 </a-select-option>                             </a-select>                         </a-input>                     </a-form-item>                     <!-- 开始结束时间选择 -->                     <a-form-item :label="itme.label" v-if="itme.type === 'rangePicker'">                         <a-range-picker                             :placeholder="!itme.placeholder ? itme.label : itme.placeholder"                             showTime                             :                             v-decorator="[itme.value, { rules: [{ required: itme.required?itme.required:false, message: itme.message?itme.message:' ' }]}]" />                     </a-form-item>                     <!-- 单个时间选择 -->                     <a-form-item                          :label="itme.label" v-if="itme.type === 'datePicker'">                         <a-date-picker                              :                             v-decorator="[ itme.value, { rules: [{ required: itme.required?itme.required:false, message: itme.message?itme.message:' ' }]}]"                             showTime                             :placeholder="!itme.placeholder ? itme.label : itme.placeholder" />                     </a-form-item>                     <!-- 选择框 -->                     <a-form-item                          :label="itme.label"                          v-if="itme.type === 'select'"                         :label-col="{ span: itme.labelCol ? itme.labelCol : 5 }"                          :wrapper-col="{ span: itme.wrapper ? itme.wrapper : 8 }">                         <a-select                             allowClear                             v-decorator="[ itme.value, { rules: [{                                                           required: itme.required?itme.required:false,                                                           message: itme.message?itme.message:' ' }]}]"                             :placeholder="!itme.placeholder ? itme.label : itme.placeholder">                             <a-select-option v-for="optionItme in itme.option" :key="optionItme.value">                                 {{optionItme.label}}                             </a-select-option>                         </a-select>                     </a-form-item>                                          <!-- 单选框 -->                     <a-form-item :label="itme.label" v-if="itme.type === 'radio'">                         <a-radio-group                              v-decorator="[ itme.value, { rules: [{ required: itme.required?itme.required:false, message: itme.message?itme.message:' ' }]}]">                             <a-radio v-for="radioItme in itme.radio" :key="radioItme.value" :value="radioItme.value">                                 {{radioItme.label}}                             </a-radio>                         </a-radio-group>                     </a-form-item>                     <!-- 开关按钮 -->                     <a-form-item :label="itme.label"  v-if="itme.type === 'switch'">                         <a-switch v-decorator="[ itme.value, { valuePropName: 'checked' }]" />                     </a-form-item>                     <!-- 图片上传 -->                     <a-form-item                          :label="itme.label"                          v-if="itme.type === 'upload'"                         :label-col="{ span: itme.labelCol ? itme.labelCol : 5 }"                          :wrapper-col="{ span: itme.wrapper ? itme.wrapper : 20 }">                         <a-upload                             v-decorator="[ itme.value, { valuePropName: 'fileList', getValueFromEvent: normFile, }]"                             :action="itme.action?itme.action:'https://www.mocky.io/v2/5cc8019d300000980a055e76'"                             listType="picture-card"                             @preview="handlePreview">                             <div v-if="itme.value.length < 8">                                 <a-icon type="plus" />                                 <div class="ant-upload-text">点击上传图片</div>                             </div>                         </a-upload>                         <a-modal :visible="previewVisible" :footer="null" @cancel="previewVisible = false">                             <img alt="example"  :src="previewImage" />                         </a-modal>                     </a-form-item>                 </div>             </a-form>         </a-modal>     </div> </template>
<script lang='ts'> import { Component, Vue, Prop, Emit, Watch } from 'vue-property-decorator'; import Moment from 'moment' 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);     });   } @Component({     data() {         return {             formState: this.$form.createForm(this),             previewVisible: false,             previewImage: ''         };     }, }) export default class FormForm extends Vue {     [x: string]: any;     // 弹出框宽度     @Prop({type: String, default: '500px'}) width!: string;     // 接收表单渲染内容数据     @Prop({type: Object, default: () => {console.log()}}) form!: {};          // 接收弹窗窗口标题     @Prop({type: String, default: '操作窗口'}) title!: string;     // 接收表单渲染内容格式     @Prop({type: Array, default: () => []}) formData!: [];     // 返出取消和确定按钮     @Emit('handleOk')     handleOk(e) {          if (e === 'return') {             return 'true';         } else if (e === 'ok') {             let stateType: object | boolean = false;             this.formState.validateFields((err, value) => {                 if (!err) {                     this.confirmLoading = true;                     stateType = value;                 }             })             return stateType;         }     }          // 监听表单渲染内容数据接入 + 转换多余传入问题     @Watch('form', {immediate: true, deep: false})     onForm(e) {         let obj: object = {};         Object.keys(e).forEach(key => {             Array.from(this.formData).forEach((res: any | object) => {                 if (key === res.value || key === res.header) {                     if (res.type === 'rangePicker' && e[key].length > 0) {                         e[key] = [ Moment(e[key][0]), Moment(e[key][1]) ]                     }                     if (res.type === 'datePicker' && e[key]) {                         e[key] = Moment(e[key])                     }                     obj[key] = e[key]                 }             })         })         this.$nextTick(() => {             this.formState.setFieldsValue(obj)         })     }     // 监听是否弹窗属性     public visibleOff: boolean = false;     // 确定按钮loading     public confirmLoading: boolean = false; // --------- methods ------------     async handlePreview(file) {         if (!file.url && !file.preview) {             file.preview = await getBase64(file.originFileObj);         }         this.previewImage = file.url || file.preview;         this.previewVisible = true;     }     normFile(e) {       if (Array.isArray(e)) {         return e;       }       return e && e.fileList;     } } </script>
<style lang='scss' scpoed>     .ant-form-item-label{         white-space: pre-wrap;         line-height: 25px;     }     .ant-row{         display: flex;         align-items: center;     }     .ant-form{         max-height: 60vh;         overflow: auto;         &::-webkit-scrollbar {             display: none;;         }     }     .ant-form-item{         margin-bottom: 10px;     }     .ant-form-item-control{         left: 10px;         max-height: 225px;         overflow: auto;         &::-webkit-scrollbar{             display: none;         }     }     .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>

部分效果图:

vue ant design封装弹窗表单如何使用

使用ant-design-vue的Form表单

使用脚手架新建项目

vue create antd-demo

vue ant design封装弹窗表单如何使用

所以,得到了这么一个项目,如下

vue ant design封装弹窗表单如何使用

安装并导入ant-design-vue,使用Form组件

npm install --save ant-design-vue@next

修改main.ts 

import { createApp } from 'vue'; import App from './App.vue'; import Antd from "ant-design-vue"; import "ant-design-vue/dist/antd.css"; createApp(App).use(Antd).mount('#app');

修改App.vue

<template>   <HelloWorld/> </template>
<script lang="ts"> import { defineComponent } from 'vue'; import HelloWorld from './components/HelloWorld.vue'; export default defineComponent({   name: 'App',   components: {     HelloWorld   } }); </script>
<style> #app {   font-family: Avenir, Helvetica, Arial, sans-serif;   -webkit-font-smoothing: antialiased;   -moz-osx-font-smoothing: grayscale;   text-align: center;   color: #2c3e50;   margin-top: 60px; } </style>

修改HelloWorld.vue

<template>   <a-form     layout="inline"     :model="formState"     @finish="handleFinish"     @finishFailed="handleFinishFailed"   >     <a-form-item>       <a-input v-model:value="formState.user" placeholder="Username">         <template #prefix><UserOutlined  /></template>       </a-input>     </a-form-item>     <a-form-item>       <a-input v-model:value="formState.password" type="password" placeholder="Password">         <template #prefix><LockOutlined  /></template>       </a-input>     </a-form-item>     <a-form-item>       <a-button         type="primary"         html-type="submit"         :disabled="formState.user === '' || formState.password === ''"       >         Log in       </a-button>     </a-form-item>   </a-form> </template>
<script lang="ts"> import { UserOutlined, LockOutlined } from '@ant-design/icons-vue'; import { ValidateErrorEntity } from 'ant-design-vue/es/form/interface'; import { defineComponent, reactive, UnwrapRef } from 'vue'; interface FormState {   user: string;   password: string; } export default defineComponent({   setup() {     const formState: UnwrapRef<FormState> = reactive({       user: '',       password: '',     });     const handleFinish = (values: FormState) => {       console.log(values, formState);     };     const handleFinishFailed = (errors: ValidateErrorEntity<FormState>) => {       console.log(errors);     };     return {       formState,       handleFinish,       handleFinishFailed,     };   },   components: {     UserOutlined,     LockOutlined,   }, }); </script>

启动应用,测试验证

npm run serve启动应用,效果如下

vue ant design封装弹窗表单如何使用

好了,应用就暂时介绍到这里。其实,我更想说说我的疑惑:

Hello.vue中,Username输入框的前面有个图片前缀,Password输入框的前面也有一个图片前缀,都是通过<template #prefix></template>实现的,一眼看去,应该就是通过插槽实现的,但是具体的实现过程是怎样的,尚不清楚。

简单调试了一下,如下图所示。

vue ant design封装弹窗表单如何使用

ant-design-vue的Form组件的FormItem.js的部分源码如下,

vue ant design封装弹窗表单如何使用

“vue ant design封装弹窗表单如何使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

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

AI