文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2023-06-30 17:46

关注

本篇内容介绍了“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封装弹窗表单如何使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯