赞
踩
1. 定义Form表单组件:
- <template>
- <div class="v-form-conatiner">
- <van-cell-group>
- <!-- 自定义cell-group表头 -->
- <template v-if="title" #title>
- <slot name="group-title">
- {{ title }}
- </slot>
- </template>
- <ValidationObserver slim ref="validationObserver">
- <template v-for="item in formModel">
- <!-- 输入框、选择框、日期选择器、文件上传、单选框、复选框等可输入组件渲染 -->
- <ValidationProvider
- v-if="!formModelOptions[item.key + 'Hidden']"
- :key="item.key"
- :name="item.options.label"
- :rules="item.options.rules ? item.options.rules : ''"
- v-slot="{ errors }"
- slim
- >
- <van-cell
- v-if="item.componentType === 'van-cell'"
- :title="item.options.label"
- :value="formData[item.key]"
- />
- <component
- v-else
- :is="item.componentType"
- :ref="`${item.key}`"
- :data="item.options"
- :keyName="item.key"
- v-model="formData[item.key]"
- @changed="changed(item)"
- :error-message="errors[0]"
- />
- </ValidationProvider>
- </template>
- </ValidationObserver>
- </van-cell-group>
- </div>
- </template>
-
- <script>
- import { ValidationProvider } from "vee-validate";
- import formItemBase from "./mixins/FormBase";
- import VantField from "@/components/common/form/VantField.vue";
- import VantPersonal from "@/components/common/form/VantPersonal.vue";
- import VantAgent from "@/components/common/form/VantAgent.vue";
- import VantRadio from "@/components/common/form/VantRadio.vue";
- import VantCheckBox from "@/components/common/form/VantCheckBox.vue";
- import VantMultiPicker from "@/components/common/form/VantMultiPicker.vue";
- import VantDatetimePicker from "@/components/common/form/VantDatetimePicker.vue";
- import VantPicker from "@/components/common/form/VantPicker.vue";
- import VantUploader from "@/components/common/form/VantUploader.vue";
- import VantUploaderImage from "@/components/common/form/VantUploaderImage.vue";
- import VantFormPopup from "@/components/common/form/VantFormPopup.vue";
- import VantCalendar from "@/components/common/form/VantCalendar.vue";
-
- export default {
- name: "VantForm",
- components: {
- ValidationProvider,
- VantField,
- VantPersonal,
- VantAgent,
- VantRadio,
- VantCheckBox,
- VantMultiPicker,
- VantDatetimePicker,
- VantPicker,
- VantUploader,
- VantUploaderImage,
- VantFormPopup,
- VantCalendar,
- },
- mixins: [formItemBase],
- props: {
- formModel: {
- // 表单初始化数据结构
- type: Array,
- default: function () {
- return [];
- },
- },
- value: {
- // 表单的值
- type: Object,
- default: function () {
- return {};
- },
- },
- title: {
- type: String,
- default: function () {
- return "";
- },
- },
- },
- model: {
- prop: "value",
- event: "changed",
- },
- data() {
- return {
- formData: {}, // 表单绑定的数据
- formModelOptions: {}, // form表单字段配置显示隐藏参数配置
- };
- },
- methods: {
- /**
- * 表单提交函数
- */
- onSubmit() {
- this.$refs.validationObserver.validate().then((success) => {
- // success结果返回布尔值
- if (!success) return;
- // 处理请求
- // this.$emit("success", this.formData);
-
- this.$nextTick(() => {
- // 清除验证状态,需注意值不会清除要自己手动清除
- this.$refs.validationObserver.reset();
- });
- });
- },
- /**
- * 表单校验
- */
- validate() {
- return new Promise((resolve) => {
- this.$refs.validationObserver.validate().then((success) => {
- resolve(success);
- // if (success) {
- // this.$nextTick(() => {
- // // 清除验证状态,需注意值不会清除要自己手动清除
- // window.validationObserver = this.$refs.validationObserver;
- // this.$refs.validationObserver.reset();
- // });
- // }
- });
- });
- },
- reset() {
- this.$refs.validationObserver.reset();
- },
- /**
- * 表单值发生改变回调函数
- * item: 表单字段数据模板
- */
- changed(item) {
- this.$emit("formItemChanged", item, this.formData); // 值变更,暴露变化的事件及值,父类中可以处理业务校验等逻辑
- this.$emit("changed", this.formData); // 值变更双向绑定
- },
- /**
- * 动态设置fromData的值,主要用于字段之间的依赖计算
- * name:属性名
- * value: 值
- */
- setFormDataByName(name, value) {
- this.$set(this.formData, name, value);
- },
- /**
- * 动态设置formModelOptions的值,主要用于字段之间联动显示等逻辑控制
- * name + "Hidden" 是动态组装的属性名
- * value对应属性的名字
- */
- setFormModelOptionsByIndex(name, value) {
- this.$set(this.formModelOptions, name + "Hidden", value);
- },
- /**
- * @param {*} fieldName 字段key值
- * @param {*} model form模板
- * @param {*} node form节点
- */
- setFieldToDiabled(fieldName, disabled) {
- let refNode = null;
- if (fieldName) {
- refNode = this.getFieldNode(fieldName);
- if (refNode && refNode.setDisabled) {
- refNode.setDisabled(disabled);
- }
- }
- },
- /**
- * 初始化数据
- */
- initData() {
- let isEdit = false;
- if (!this.$utils.isEmpty(this.value)) {
- isEdit = true;
- }
- // model带{{i18nKey}}资源国家化
- this.handleI18n(this.formModel);
- // 动态给属性form data添加属性,后期作为field控件的v-model的变量
- for (let i = 0; i < this.formModel.length; i++) {
- if (isEdit) {
- // 编辑数据复制
- this.formModel[i].value = this.value[this.formModel[i].key];
- }
- // 组装表格绑定的model
- this.$set(
- this.formData,
- this.formModel[i].key,
- this.formModel[i].value
- );
- /**
- * 字段的配置属性集合
- * 可以配置多个,根据需要进行扩展
- **/
- let formModelItem = this.formModel[i];
-
- // 字段显示控制字段,命名规则:[key]+Hidden
- this.$set(
- this.formModelOptions,
- formModelItem.key + "Hidden",
- formModelItem.options.hidden ? true : false
- );
- }
- },
- /**
- * 返回表单字段的ref引用
- */
- getFieldRefNode(keyName) {
- return this.$refs[keyName];
- },
- /**
- * 返回表单字段的ref引用
- */
- getFieldNode(keyName) {
- let refsNode = this.$refs[keyName];
- return refsNode && refsNode.length ? refsNode[0] : null;
- },
- },
- created() {
- this.initData();
- },
- watch: {
- formModel() {
- this.initData();
- },
- value(newVal, oldVal) {
- console.info(oldVal);
- // 编辑数据,处理数据回填
- if (newVal.isEdit) {
- this.formData = newVal;
- }
- // 数据回填,把编辑状态重置成非编辑状态,必备表单改变,重复处理数据
- this.isEdit = false;
- },
- },
- };
- </script>
- <style scoped lang="less">
- .v-form-conatiner {
- font-size: 14px;
- color: #646566;
- text-align: left;
- }
- .required {
- .van-cell-group__title:before {
- position: absolute;
- left: 2.133333vw;
- color: #ee0a24;
- font-size: 3.733333vw;
- content: "*";
- }
- }
- .v-cell-title {
- margin: 0;
- padding: 16px 16px 16px;
- color: rgba(69, 90, 100, 0.6);
- font-weight: normal;
- font-size: 14px;
- line-height: 16px;
- background-color: #f7f8fa;
- }
- </style>
2.form表单子组件:
- <script>
- import { ValidationProvider } from "vee-validate";
- import formItemBase from "./mixins/FormBase";
- // 表单子组件
- import VantField from "@/components/common/form/VantField.vue";
- import VantPersonal from "@/components/common/form/VantPersonal.vue";
- import VantAgent from "@/components/common/form/VantAgent.vue";
- import VantRadio from "@/components/common/form/VantRadio.vue";
- import VantCheckBox from "@/components/common/form/VantCheckBox.vue";
- import VantMultiPicker from "@/components/common/form/VantMultiPicker.vue";
- import VantDatetimePicker from "@/components/common/form/VantDatetimePicker.vue";
- import VantPicker from "@/components/common/form/VantPicker.vue";
- import VantUploader from "@/components/common/form/VantUploader.vue";
- import VantUploaderImage from "@/components/common/form/VantUploaderImage.vue";
- import VantFormPopup from "@/components/common/form/VantFormPopup.vue";
- import VantCalendar from "@/components/common/form/VantCalendar.vue";
3.处理校验逻辑:
使用ValidationObserver和ValidationProvider实现校验逻辑
- <ValidationObserver slim ref="validationObserver">
- <template v-for="item in formModel">
- <!-- 输入框、选择框、日期选择器、文件上传、单选框、复选框等可输入组件渲染 -->
- <ValidationProvider
- v-if="!formModelOptions[item.key + 'Hidden']"
- :key="item.key"
- :name="item.options.label"
- :rules="item.options.rules ? item.options.rules : ''"
- v-slot="{ errors }"
- slim
- >
- <van-cell
- v-if="item.componentType === 'van-cell'"
- :title="item.options.label"
- :value="formData[item.key]"
- />
- <!-- 动态渲染form表单的子组件 -->
- <component
- v-else
- :is="item.componentType"
- :ref="`${item.key}`"
- :data="item.options"
- :keyName="item.key"
- v-model="formData[item.key]"
- @changed="changed(item)"
- :error-message="errors[0]"
- />
- </ValidationProvider>
- </template>
- </ValidationObserver>
4. 定义form表单Json数据模板
CreateContactModel.js
- import {
- getPositionOptions,
- getCustomerPortraitOptions,
- getProjectRoleOptions,
- } from "../../../store/constants";
-
- export const contactInformationModel = [
- {
- key: "contactName", // 联系人姓名
- componentType: "vant-field",
- value: "",
- options: {
- label: "联系人姓名",
- type: "text",
- placeholder: "{{pleaseInput}}",
- rules: "required",
- required: true,
- },
- },
- {
- key: "contactNumber", // 联系人电话
- componentType: "vant-field",
- value: "",
- options: {
- label: "联系人电话",
- type: "tel",
- placeholder: "{{pleaseInput}}",
- rules: "required|phone",
- required: true,
- },
- },
- {
- key: "department", // 所属部门
- componentType: "vant-field",
- value: "",
- options: {
- label: "所属部门",
- type: "text",
- placeholder: "{{pleaseInput}}",
- },
- },
- {
- key: "position", // 职位
- componentType: "vant-radio",
- value: "",
- options: {
- label: "职位",
- data: getPositionOptions(),
- valueType: "single-dict", // 数据类型
- },
- },
- {
- key: "portrait", // 客户画像
- componentType: "vant-picker",
- value: "",
- options: {
- label: "客户画像",
- placeholder: "{{pleaseSelect}}",
- data: getCustomerPortraitOptions(),
- valueType: "single-dict", // 数据类型
- },
- },
- {
- key: "projectRole", // 项目中角色
- componentType: "vant-multi-picker",
- value: "",
- options: {
- label: "项目中角色",
- placeholder: "{{pleaseSelect}}",
- span: 8,
- data: getProjectRoleOptions(),
- valueType: "multi-dict", // 数据类型
- },
- },
- ];
5.动态生成form表单
- <template>
- <div class="create-opportunity">
- <!-- 联系人信息 -->
- <vant-form
- ref="contactInformation"
- title="联系人信息(可添加多个联系人)"
- :formModel="contactInformationModel"
- v-model="contactInformationFormData"
- class="required"
- >
- </vant-form>
- <!-- 机会保存-->
- <van-button
- v-if="!isCreateProject"
- type="info"
- @click="onSubmit"
- block
- round
- >保存</van-button
- >
- </div>
- </template>
-
- <script>
- import VantForm from "@/components/common/VantForm.vue";
- import { contactInformationModel } from "@/components/common/business/CreateContactModel";
-
- export default {
- name: "Test",
- components: {
- VantForm,
- },
- data() {
- return {
- //提交表单数据
- preparerInformationFormData: {}, // 联系人信息form表单
- contactInformationModel, // 联系人信息model
- };
- },
- };
- </script>
效果图:
校验:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。