1dialog 表单最基本的封装

<!--  -->
<template>
  <el-dialog
    :visible.sync="defaultConfigDialogAdd.dialogVisible"
    :width="defaultConfigDialogAdd.width"
    :center="defaultConfigDialogAdd.isCenter"
  >
    <!-- 如果t写了插槽,外面使用其实是没必要传title属性。-->
    <div slot="title" class="dialog-title">
      <slot name="title">
        <h2 class="default-title">{{defaultConfigDialogAdd.title}}</h2>
      </slot>
    </div>

    <el-form :model="addUserForm" :rules="rules" ref="addUserForm" label-width="100px">
      <el-form-item label="用户名" prop="username">
        <el-input v-model="addUserForm.username"></el-input>
      </el-form-item>
      <el-form-item label="姓名" prop="truename">
        <el-input v-model="addUserForm.truename"></el-input>
      </el-form-item>
      <el-form-item label="手机号" prop="phone">
        <el-input v-model.number="addUserForm.phone"></el-input>
      </el-form-item>
      <el-form-item label="是否启用" prop="status">
        <el-radio-group v-model="addUserForm.status">
          <el-radio label="禁用"></el-radio>
          <el-radio label="启用"></el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="角色" prop="role">
        <el-checkbox-group v-model="addUserForm.role">
          <el-checkbox label="系统管理员"></el-checkbox>
          <el-checkbox label="信息管理员"></el-checkbox>
          <el-checkbox label="用户管理员"></el-checkbox>
        </el-checkbox-group>
      </el-form-item>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button @click="handleCancel('addUserForm')">取 消</el-button>
      <el-button type="primary" @click="submitForm('addUserForm')">立即创建</el-button>
    </span>
  </el-dialog>
</template>
<script>
import validate from "@/utils/validate";
const { checkAge } = validate;
export default {
  name: "DialogAdd",
  props: {
    configDialogAdd: {
      type: Object,
      required: true
    }
  },
  data() {
    return {
      defaultConfigDialogAdd: {
        dialogVisible: false, //弹框默认不可见
        title: "提示", //默认标题
         "30%", //默认宽度
        isCenter: false //是否对头部和底部采用居中布局
      },
      addUserForm: {
        username: "",
        truename: "",
        phone: "",
        status: "",
        role: []
      },
      rules: {
        username: [
          { required: true, message: "请输入活动名称", trigger: "blur" },
          { min: 2, max: 10, message: "长度在 3 到 5 个字符", trigger: "blur" }
        ],
        truename: [
          { required: true, message: "请输入活动名称", trigger: "blur" },
          { min: 2, max: 19, message: "长度在 2 到 10个字符", trigger: "blur" }
        ],
        phone: [{ required: true, validator: checkAge, trigger: "blur" }],
        status: [
          { required: true, message: "请选择是否启用", trigger: "change" }
        ],
        role: [
          {
            type: "array",
            required: true,
            message: "请至少选择一个角色",
            trigger: "change"
          }
        ]
      }
    };
  },
  methods: {
    initDefaultConfigDialogAdd() {
      this.defaultConfigDialogAdd = {
        ...this.defaultConfigDialogAdd,
        ...this.configDialogAdd
      };
    },
    submitForm(formName) {
      this.$refs[formName].validate(async valid => {
        if (!valid) return this.$message.error("数据验证不通过"); //错误优先
        // 发送网络请求

        if (valid) {
          this.$refs[formName].resetFields();
          this.defaultConfigDialogAdd.dialogVisible = false;
          this.$message.success("增加用户成功");
        }
      });
    },
    handleCancel(formName) {
      // 重置输入框
      this.$refs[formName].resetFields();
      this.defaultConfigDialogAdd.dialogVisible = false;
    }
  },
  created() {
    // 初始化弹框配置项的数据
    this.initDefaultConfigDialogAdd();
  },
  watch: {
    // 外面的值变化,改变里面
    "configDialogAdd.dialogVisible": {
      handler(val) {
        this.defaultConfigDialogAdd.dialogVisible = val;
      }
    },
    // 里面的值发生变化,改变外面
    "defaultConfigDialogAdd.dialogVisible": {
      handler(val) {
        this.configDialogAdd.dialogVisible = val;
      }
    }
  }
};
</script>
<style lang="scss" scoped>
.dialog-title {
  color: #000;
  font-size: 20px;
  font-weight: 700;
}
</style>

使用

 封装

mininx/userAdd.js

/**
 * 表单支持输入框,数字输入框,单选按钮, 多选按钮,下拉选择器 switch开关
 * 每次增加一个数据formItems里面的一个项目。都要配套的增加该项目的rule 验证规则,和watch监听属性,往params网络请求参数里面赋值。
 * formITtems里面的数据项也有可能是经过一次网络请求获取来的, 就需要在此mixins文件中定义methods网络请求方法,去获取formItems数据,这个时候也需要在做另外一件事件:
 * 在DialogAdd.vue中去监听这些网络数据请求回来的数据。
 */

import validate from "@/utils/validate";
const { checkAge } = validate;
export default {
  data() {
    return {
      // 增加用户弹框组件数据选项
      configDialogAdd: {
        dialogVisible: false, //弹框默认不可见
        title: "新增用户", //默认标题 如果写了#title插槽,title可以省略不传
         "40%", //默认宽度
        addUserForm: {
          formName: "addUserForm", //表单名
          labelWidth: '120px',
          labelPosition: 'left',
          formItems: [
            //表单选项
            { label: "用户名", prop: "username", type: "input" }, //type是表单控件类型
            { label: "姓名", prop: "truename", type: "input" },
            { label: "手机号", prop: "phone", type: "numberInput" },
            {
              label: "是否启用",
              prop: "status",
              type: "radio",
              values: ["禁用", "启用"]
            },
            {
              label: "是否启用形式2",
              prop: "status1",
              type: "switch",

            },
            {
              label: "角色",
              prop: "role",
              type: "checkbox",
              values: ["系统管理员", "信息管理员", "用户管理员"]
            },
            {
              label: "角色形式2",
              prop: "role1",
              type: "select",
              options: [{
                value: 'admin',
                label: '系统管理员'
              }, {
                value: 'info',
                label: '信息管理员'
              }, {
                value: 'user',
                label: '用户管理员'
              }],
            },
            {
              label: "Cascader",
              prop: "cascader",
              type: "Cascader",
              options: [{
                value: 'zhinan',
                label: '指南',
                children: [{
                  value: 'shejiyuanze',
                  label: '设计原则'
                }]
              },
              {
                value: 'daohang',
                label: '导航',
                children: [{
                  value: 'cexiangdaohang',
                  label: '侧向导航'
                }, {
                  value: 'dingbudaohang',
                  label: '顶部导航'
                }]
              }
              ],
              handleChange: this.handleChange
            }
          ],
          data: {
            //绑定的数据
            username: "",
            truename: "",
            phone: "",
            status: "",
            status1: false,
            role: [],
            role1: '',
            cascader: [],
          },

          rules: {
            username: [
              { required: true, message: "请输入用户名", trigger: "blur" },
              {
                min: 2,
                max: 10,
                message: "长度在 3 到 5 个字符",
                trigger: "blur"
              }
            ],
            truename: [
              { required: true, message: "请输入名字", trigger: "blur" },
              {
                min: 2,
                max: 19,
                message: "长度在 2 到 10个字符",
                trigger: "blur"
              }
            ],
            phone: [{ required: true, validator: checkAge, trigger: "blur" }],
            status: [
              { required: true, message: "请选择是否启用", trigger: "change" }
            ],
            status1: [
              { required: true, message: "请选择是否启用形式1", trigger: "change" }
            ],
            role: [
              {
                type: "array",
                required: true,
                message: "请至少选择一个角色",
                trigger: "change"
              }
            ],
            role1: [
              { required: true, message: "请至少选择一个角色1", trigger: "change" }],
            cascader: [
              { required: true, message: "请至少选择一个级联选择器", trigger: "change" }],
          },

        },
        requestApi: {
          apiName: "userAdd",
          params: {}
        }
      }
    }

  },
  methods: {
    handleChange(val) {
      console.log(111);
      console.log(val);
    }
  },

  created() { },
  mounted() {

  },


  watch: {
    // 逻辑处理在外部,由用户控制参数
    'configDialogAdd.addUserForm.data.username': {
      handler(newVal) {
        this.configDialogAdd.requestApi.params.username = newVal
      },

    },
    'configDialogAdd.addUserForm.data.truename': {
      handler(newVal) {
        this.configDialogAdd.requestApi.params.truename = newVal
      },

    },
    'configDialogAdd.addUserForm.data.phone': {
      handler(newVal) {
        this.configDialogAdd.requestApi.params.phone = newVal
      },

    },
    'configDialogAdd.addUserForm.data.status': {
      handler(newVal) {
        if (!newVal) this.configDialogAdd.requestApi.params.status = ''
        else this.configDialogAdd.requestApi.params.status = newVal === '禁用' ? '0' : '1'

      },
    },
    'configDialogAdd.addUserForm.data.role': {
      handler(newVal) {
        const obj = { "系统管理员": 'admin', '信息管理员': 'info', '用户管理员': 'user' }
        let resArr = []
        newVal.forEach(item => resArr.push(obj[item]))
        this.configDialogAdd.requestApi.params.role = resArr.join(',')
      },
    },
    'configDialogAdd.addUserForm.data.status1': {
      handler(newVal) {
        this.configDialogAdd.requestApi.params.status1 = newVal
      },

    },
    'configDialogAdd.addUserForm.data.role1': {
      handler(newVal) {
        this.configDialogAdd.requestApi.params.role1 = newVal
      },

    },
    'configDialogAdd.addUserForm.data.cascader': {
      handler(newVal) {
        this.configDialogAdd.requestApi.params.cascader = newVal
      },

    },


  },



}
View Code

 DialogAdd.vue

<!--  -->
<template>
  <el-dialog
    :visible.sync="defaultConfigDialogAdd.dialogVisible"
    :width="defaultConfigDialogAdd.width"
    :center="defaultConfigDialogAdd.isCenter"
  >
    <!-- 如果t写了插槽,外面使用其实是没必要传title属性。-->
    <div slot="title" class="dialog-title">
      <slot name="title">
        <h2 class="default-title">{{defaultConfigDialogAdd.title}}</h2>
      </slot>
    </div>
    <el-form
      :model="defaultConfigDialogAdd.addUserForm.data"
      :rules="defaultConfigDialogAdd.addUserForm.rules"
      :ref="defaultConfigDialogAdd.addUserForm.formName"
      :label-width="defaultConfigDialogAdd.addUserForm.labelWidth||'100px'"
      :label-position="defaultConfigDialogAdd.addUserForm.labelPosition"
    >
      <el-form-item
        v-for="item in defaultConfigDialogAdd.addUserForm.formItems"
        :key="item.prop"
        :label="item.label"
        :prop="item.prop"
      >
        <!-- 输入框 -->
        <template v-if="item.type==='input'">
          <el-input v-model="defaultConfigDialogAdd.addUserForm.data[item.prop]"></el-input>
        </template>
        <template v-else-if="item.type==='numberInput'">
          <el-input v-model.number="defaultConfigDialogAdd.addUserForm.data[item.prop]"></el-input>
        </template>
        <!--  -->
        <template v-else-if="item.type==='radio'">
          <el-radio-group v-model="defaultConfigDialogAdd.addUserForm.data[item.prop]">
            <el-radio v-for="item in item.values" :key="item" :label="item"></el-radio>
          </el-radio-group>
        </template>
        <template v-else-if="item.type==='switch'">
          <el-switch v-model="defaultConfigDialogAdd.addUserForm.data[item.prop]"></el-switch>
        </template>
        <!-- 复选框 -->
        <template v-else-if="item.type==='checkbox'">
          <el-checkbox-group v-model="defaultConfigDialogAdd.addUserForm.data[item.prop]">
            <el-checkbox v-for="(item, index) in item.values" :key="index" :label="item"></el-checkbox>
          </el-checkbox-group>
        </template>
        <!-- 下拉框 -->
        <template v-else-if="item.type==='select'">
          <el-select v-model="defaultConfigDialogAdd.addUserForm.data[item.prop]" placeholder="请选择">
            <el-option
              v-for="item in item.options"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            ></el-option>
          </el-select>
        </template>
        <!-- 级联选择器 -->
        <template v-else-if="item.type==='Cascader'">
          <el-cascader
            v-model="defaultConfigDialogAdd.addUserForm.data[item.prop]"
            :options="item.options"
            @change="handleChange"
          ></el-cascader>
        </template>
      </el-form-item>
    </el-form>

    <span slot="footer" class="dialog-footer">
      <el-button @click="handleCancel(defaultConfigDialogAdd.addUserForm.formName)">取 消</el-button>
      <el-button
        type="primary"
        @click="submitForm(defaultConfigDialogAdd.addUserForm.formName)"
      >立即创建</el-button>
    </span>
  </el-dialog>
</template>
<script>
export default {
  name: "DialogAdd",
  props: {
    configDialogAdd: {
      type: Object,
      required: true
    }
  },
  data() {
    return {
      defaultConfigDialogAdd: {
        dialogVisible: false, //弹框默认不可见
        title: "提示", //默认标题
         "30%", //默认宽度
        isCenter: false, //是否对头部和底部采用居中布局
        addUserForm: {
          formName: "", //表单名
          labelWidth: "", //'100px' 长度
          labelPosition: "right", //label对齐方式 left right top 默认是right
          formItems: [],
          data: {},
          rules: {}
        },
        requestApi: {
          apiName: "",
          params: {}
        }
      }
    };
  },
  methods: {
    async _request() {
      let { apiName, params } = this.defaultConfigDialogAdd.requestApi;
      try {
        return await this.$api[apiName](params);
      } catch (error) {
        throw error; //这里抛出异常,下面catch一定要捕获异常
      }
    },
    initDefaultConfigDialogAdd() {
      this.defaultConfigDialogAdd = {
        ...this.defaultConfigDialogAdd,
        ...this.configDialogAdd
      };
    },
    submitForm(formName) {
      this.$refs[formName].validate(async valid => {
        if (!valid) return this.$message.error("数据验证不通过"); //错误优先
        // 发送网络请求_
        this._request()
          .then(this.submitsuccess)
          .catch(err => err);
      });
    },
    // 增加用户网络行为成功之后的动作
    submitsuccess() {
      //请求成功后的行为
      this.$message.success("增加用户成功");
      this.$refs[formName].resetFields();
      this.defaultConfigDialogAdd.dialogVisible = false;
    },
    handleCancel(formName) {
      // 重置输入框
      this.$refs[formName].resetFields();
      this.defaultConfigDialogAdd.dialogVisible = false;
    },
    // 级联选择器的选择事件 (也可以放在最外面minix里面处理,当作事件参数传进来)
    handleChange(val) {
      console.log(val, 222);
    }
  },
  created() {
    // 初始化弹框配置项的数据
    this.initDefaultConfigDialogAdd();
  },
  watch: {
    // 外面的值变化,改变里面
    "configDialogAdd.dialogVisible": {
      handler(val) {
        this.defaultConfigDialogAdd.dialogVisible = val;
      }
    },
    // 里面的值发生变化,改变外面
    "defaultConfigDialogAdd.dialogVisible": {
      handler(val) {
        this.configDialogAdd.dialogVisible = val;
      }
    }
  }
};
</script>
<style lang="scss" scoped>
.dialog-title {
  color: #000;
  font-size: 20px;
  font-weight: 700;
}
</style>
View Code
原文地址:https://www.cnblogs.com/xiaoliziaaa/p/13340424.html