# 混入

vue mixins 官方文档 (opens new window),在阅读本文档前,请对该方法的使用有了解。

# 介绍

该混合是对 el-dialog 一些默认数据的复用。
在本项目中,所有涉及到使用 el-dialog 的地方都以组件形式写入一个新文件,并命名为 XxxModal.vue,使用时在父组件中,以 refs 调用 XxxModal.vue 组件中定义的 open 方法,open 方法可接收当前需要编辑的资源数据,以便在编辑的 form 中回显。

# 目录结构

└─ src                          # 项目主文件
   └─ mixins                    # 混入
      └─ modal.js               # el-dialog 组件
export const modal = {
  data() {
    return {
      id: null,             // 将被编辑的资源ID
      loading: false,       // 资源加载
      submitLoading: false, // 保存时动画
      visible: false,       // 是否显示 el-dialog
      isEdit: false,        // 编辑或新增
      form: {}              // 表单
    }
  },

  created() {
    // 获取路由中的 ID 只,与业务强关联
    try {
      this.id = parseInt(this.$route.params.id)
    } catch (err) {

    }
  },

  methods: {
    // 父级调用打开模态框
    open(row) {
      // 如果传入数据则为编辑
      if (row) {
        this.isEdit = true
        // copy 数据,防止编辑时影响父级数据
        this.form = Object.assign(this.form, row)
      }

      // 显示
      this.visible = true

      // 清空表单校验,不然会保留上次时校验结果
      // 需要 el-dialog 显示才可清空,否则无法找到表单会报异常
      this.$nextTick(() => {
        this.$refs['form'] && this.$refs['form'].clearValidate()
      })
    },

    // 关闭前回调,若未处理完成,禁止关闭
    beforeClose(done) {
      if (this.submitLoading) {
        this.$message.warning('请等待操作完成后关闭')
      } else {
        done()
      }
    },

    // 关闭模态框
    close() {
      this.$refs['form'] && this.$refs['form'].resetFields()  // 重置表单
      this.form = this.$options.data().form         // 重置表单默认数据
      this.isEdit = false     
      this.visible = false  // 关闭 el-dialog
    },

    // 保存/更新
    submitForm() {
      if (this.$refs['form']) {
        // 表单校验
        this.$refs['form'].validate((valid) => {
          if (valid) {
            this._submitForm()
          } else {
            return false;
          }
        });
      } else {
        this._submitForm()
      }
    },

    // 提交表单, this.submit 需要在使用的组件中定义,是接口请求
    async _submitForm() {
      this.submitLoading = true;
      let res = await this.submit()
      this.submitLoading = false;

      if (res && res.code === 200) {
        this.$emit("on-success");
        this.visible = false;
      }
    }
  },
}

# 使用示例

<!--  -->
<el-dialog
  :title="isEdit ? '编辑' : '新增'"
  :visible.sync="visible"
  width="600px"
  @close="close"
>
  <!-- ref="form" 在 mixins 中有使用,请勿变更,当然也可以在本组件中重新定义该校验方法 -->
  <el-form
    :model="form"
    :rules="rules"
    ref="form"
    label-width="110px"
    style="padding: 0 20px"
  >
    <el-form-item label="名称:" prop="title">
      <el-input v-model="form.title" placeholder="" />
    </el-form-item>

    <div slot="footer">
      <m-button type="cancel" @click="visible = false" />
      <!-- submitForm() 方法在 mixins 中定义,会做数据校验,校验完成后会调用 submit() 方法 -->
      <!-- submit() 方法需要在组件中定义,用于提交数据 -->
      <m-button type="submit" @click="submitForm()" :loading="submitLoading" />
  </div>
</el-dialog>
// 引入混入
import { modal } from "@/mixins/modal";

export default {
  // 注入混入内容
  mixins: [modal],

  data() {
    return {
      rules: {
        title: [
          {
            required: true,
            message: "请输入标题名称",
            trigger: "blur",
          },
          {
            min: 2,
            max: 16,
            message: "长度在 2 到 16 个字符",
            trigger: "blur",
          },
        ]
      }
    }
  },

  methods: {
    // 页面滚动时会调用 loadMore 方法,getData 方法在上面的 mixins 里面定义了
    async submit() {
      return this.isEdit
        ? await updateGenre(this.form.id, this.form)
        : await createGenre(this.form);
    },
  }
}

# 父组件调用

<genre-modal ref="genreModal" @on-success="getData()"/>
// 引入组件
import GenreModal from "./components/GenreModal";

export default {
  components: {
    GenreModal,
  },

  methods: {
    // 显示弹框新增/编辑组件, open 方法可传入待编辑的数据
    showModal(row) {
      this.$refs["genreModal"].open(row);
    },
  }
}
上次更新: 6/23/2022, 6:29:21 PM