vue后台管理系统,mixin妙用

1、vue全家桶开发后台管理系统

vue + vue-router + vuex + es6 + scss + webpack

2、vue的mixin使用

后台系统有很多页面都有类似的增删改查操作,使用mixin效果非常好,重复的劳动大大减少。

下面分4步来封装:

2-1、提取增删改查操作函数formFn.js
import { doPost } from "@/tools/request.js";
import { toStringValue } from "@/utils/util.js"
// toStringValue():给对象/对象数组的属性值为数值型的转为字符串型

/** @param {Object} o为表单默认要显示的默认值,如果无,就不填写,可选 */
export function createFn(o = {}) {
  this.$refs.myForm && this.$refs.myForm.resetFields();
  this.dialogForm.formData = Object.assign({}, toStringValue(o));
  this.dialogForm.isEdit = false;
  this.dialogForm.title = "新增";
  this.dialogForm.isVisible = true;
}

export function editFn(row = {}) {
  this.dialogForm.isEdit = true;
  this.dialogForm.title = "编辑";
  this.dialogForm.isVisible = true;
  this.dialogForm.formData = Object.assign({}, toStringValue(row));
}

export function delFn(row, url) {
  this.$confirm("确认删除该数据吗?", "提示", {
    type: "warning"
  }).then(
    () => {
      doPost(url, {
          id: row.id
        })
        .then(res => {
          this.$message.success("删除成功");
          this.getData();
        })
        .catch(e => {
          this.$message.error(e.message);
          catchUrl(e, url)
        });
    }
  ).catch(() => {
    this.$message.info("取消删除");
  });
}

export function delFn2(row, url) {
  this.$confirm("确认删除该数据吗?", "提示", {
    type: "warning"
  }).then(
    () => {
      doPost(url, {
          id: row.id
        })
        .then(res => {
          this.$message.success("删除成功");
          this.getData();
        })
        .catch(e => {
          this.$message.error(e.message);
          catchUrl(e, url)
        });
    }
  ).catch(() => {
    this.$message.info("取消删除");
  });
}

export function submitFn(formName, url, isEdit) {
  const title = isEdit ? '编辑' : '添加';
  this.$refs[formName].validate(valid => {
    if (valid) {
      doPost(url, this.dialogForm.formData)
        .then(() => {
          this.$message.success(`${title}成功`);
          this.getData();
          this.dialogForm.isVisible = false;
        })
        .catch(e => {
          // code=0,成功返回;反之,失败提示
          if (e.code && e.code !== 0) {
            this.$message.error(e.message);
          }
          catchUrl(e, url, `${title}`)
        });
    } else {
      console.error("Error submit ----- Form invalid !");
      return false;
    }
  })
}

export function getDataFn(url, param = {}) {
  this.tableListLoading = true;
  doPost(url, param)
    .then(res => {
      this.tableListLoading = false;
      this.page.total = res.count;
      this.tableList = res.list;
    })
    .catch(e => {
      // code=0,成功返回;反之,失败提示
      if (e.code && e.code !== 0) {
        this.$message.error(e.message);
      }
      catchUrl(e, url)
      this.tableListLoading = false;
    });
}

export function getDataFn2(fn, param = {}) {
  this.tableListLoading = true;
  fn(param)
    .then(res => {
      this.tableListLoading = false;
      this.page.total = res.count;
      this.tableList = res.list;
    })
    .catch(e => {
      catchFn(e, fn)
      this.tableListLoading = false;
    });
}

export function mulDelFn(url) {
  if (!this.mulSels.length) {
    this.$alert("请选择要删除的数据", "提示");
    return;
  }
  const deleIdArr = this.mulSels.map(o => o.id);
  this.$confirm("确认删除该数据吗?", "提示", {
    type: "warning"
  }).then(
    () => {
      doPost(url, {
          ids: deleIdArr
        })
        .then(res => {
          this.$message.success("删除成功");
          this.getData();
        })
        .catch(e => {
          catchUrl(e, url)
          this.$confirm(e.message, "提示", {
            type: "warning"
          }).then(
            () => {
              this.dialogForm.isVisible = false;
            }
          );
        });
    }
  ).catch(() => {
    this.$message.info("取消删除");
  });
}

function catchUrl(e, url, detail) {
  console.group(`Error found in doPost(${url})`)
  if (detail) console.info(`--${detail}--报错!`)
  console.error(e)
  console.groupEnd()
}

function catchFn(e, fn) {
  console.group(`Error found in method (${fn.name})`)
  console.error(e)
  console.groupEnd()
}

复制代码
2-2、mixin-common部分(查询、搜索的数据和方法)commom.js
import TABLE from "@/utils/tableConfig.js";
import * as formFn from "@/utils/formFn.js";
import { debounce, getQueryParam } from "@/utils/util.js";
import ZSelect from "@/components/ZSelect/ZSelect.vue";``
import ZPage from "@/components/ZPage/ZPage.vue";

export default {
  components: { ZPage, ZSelect },
  data() {
    return {
      searchFilters: {},
      tableList: [],
      tableListLoading: false,
      page: {
        size: 10,
        current: 1,
        total: 0
      },
      t: {
        border: TABLE.border,
        size: TABLE.size,
        stripe: TABLE.stripe,
        maxHeight: TABLE.maxHeight
      }
    };
  },
  methods: {
    getData() {
      const param = getQueryParam(this.searchFilters, this.page);
      formFn.getDataFn.apply(this, [this.url.getData, param]);
    },
    dbnSearch() {
      this.DSearchFn();
    },
    doSearch() {
      this.page.current = 1;
      this.getData();
    },
    dbnResetSearch() {
      this.DResetSearchFn();
    },
    doResetSearch() {
      this.searchFilters = {};
      this.page.current = 1;
      this.getData();
    },
    currentPageChange(p) {
      this.page.current = p;
      this.getData();
    },
    pageSizeChange(size) {
      this.page.size = size;
      this.getData();
    },
    indexMethod(idx) {
      return (this.page.current - 1) * this.page.size + (idx + 1);
    }
  },
  mounted() {
    this.getData();
  },
  created() {
    this.DSearchFn = debounce(() => this.doSearch());
    this.DResetSearchFn = debounce(() => this.doResetSearch());
  }
}

复制代码
2-3、mixin中CRUD的cud部分(增删改的数据和方法)cud.js
import * as formFn from "@/utils/formFn.js";
import { debounce } from "@/utils/util.js";
import MulSelect from "@/components/ZSelect/MulSelect.vue";

export default {
  components: { MulSelect },
  data() {
    return {
      dialogForm: {
        isEdit: false,
        isVisible: false,
        title: "",
        formData: {},
        formRule: {}
      },
      mulSels: [] //选中列,主要用于批量删除
    };
  },
  watch: {
    'dialogForm.isVisible': {
      handler(newV) {
        if (newV === false) {
          this.$refs.myForm && this.$refs.myForm.resetFields();
        }
      }
    }
  },
  methods: {
    handleEdit(row, col, idx) {
      formFn.editFn.apply(this, [row]);
    },
    handleDel(row, col, idx) {
      formFn.delFn.apply(this, [row, this.url.delete]);
    },

    // 表单新增/编辑+表单重置 start
    debounceSubmit(formName) {
      this.DSubmitFn(formName);
    },
    doSubmitForm(formName) {
      /* 分别是“修改”和“新增”的url */
      let _url = this.dialogForm.isEdit ? this.url.update : this.url.create;
      formFn.submitFn.apply(this, [formName, _url, this.dialogForm.isEdit]);
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
    handleBeforeClose() {
      this.$refs["myForm"].resetFields();
      this.dialogForm.isVisible = false;
    },
    // 表单新增/编辑+表单重置 end

    // 批量选择-删除start
    handleSelectionChange(val) {
      this.mulSels = val;
    },
    handleMulDel() {
      if (this.url && this.url.mulDel) {
        formFn.mulDelFn.call(this, this.url.mulDel);
      } else {
        console.log('多选删除失败:获取不到删除地址');
      }

    },
    // 批量选择-删除end

    handleCreate() {
      formFn.createFn.apply(this);
    }
  },
  created() {
    this.DSubmitFn = debounce(v => this.doSubmitForm(v));
  }
}

复制代码
2-4、改写vue文件,example.vue



复制代码

可以看到vue文件的逻辑部分被极大地简化了。

3、两点说明

3-1、vue-mixin合并说明


## mixin合并

数据对象合并【data(一层属性深度浅合并)】:多个合并在一起,有冲突的以组件数据优先;
钩子函数合并【created、mounted等】:多个合在一起,先调用mixin的再调用组件本身的;【混为同一个数组,所以都被调用】
对象选项合并【methods、components、directives】:mixin的会被vm实例的对应项覆盖。【混为同一个对象,所以键有冲突时只选一个】

复制代码

3-2、约定通用函数方法名和属性名 例如:

url: {
  getData: "/custPhoneInfoService/list",
  update: "/custPhoneInfoService/update",
  delete: "/custPhoneInfoService/deleteById",
  create: "/custPhoneInfoService/create",
  mulDel: "/custPhoneInfoService/mulDelete" // 注意返回去的是id的数组['asb','sdf']
}
复制代码

例如:

doXXX     // ---- 页面上实实在在触发的函数(如点击提交)
DXXX      // ---- 页面上触发后经过防抖处理的函数
handleXXX // ---- 列表编辑、翻页操作
复制代码

你可能感兴趣的:(javascript,webpack,ViewUI)