【Vue项目总结】基于饿了么组件封装

vue项目中,组件是项目的基石,每一个页面都是组件来组装起来,我司没有本身的组件库,选用的是ElementUI组件库,在它的基础上再次封装。vue

可编辑表格

因为是后台管理项目,各类单据漫天飞,并且单据列表要可编辑,可验证,基于业务封装了可编辑表格组件node

业务需求:webpack

  1. 每列能够编辑
  2. 每列输入的值须要被验证

每列可编辑,则须要每列的字段须要一个可编辑的属性edit来肯定是否能够编辑,输入的值能够被验证,须要咱们传入验证规则。git

确认须要传入的props

props: {
  // 表格数据
  tableData: {
    type: Array,
    default: () => []
  },
  // 须要验证的列字段
  columns: {
    type: Array,
    default: () => []
  },
  // 是否可编辑
  defaultEdit: {
    type: Boolean,
    default: true
  },
  // 验证集合
  verifyRules: {
    type: Object,
    default: () => {}
  }
}

表格传入数据后,初始化可编辑状态

阅读el-table源码,能够看到,表格组件拥有本身的store,一些须要通讯的状态都是它来维护的,咱们也可建立一个自有的table-store.js来维护编辑状态github

// 初始化数据
this.store = new TableStore({
  list: this.tableData,
  columns: this.columns,
  defaultEdit: this.defaultEdit
});

可编辑列edit-table-cell

利用slot插槽来传递编辑状态和验证规则web

<slot v-else :cellState="cellState" :validateCell="validateCell"></slot>
...
computed: {
  isInput() {
    return this.slotName === 'input';
  },
  rowState() {
    const states = this.editTable.store.states;
    const rowState = states.get(this.row);
    return rowState;
  },
  cellState() {
    const cellState = this.rowState.get(this.prop);
    return cellState;
  }
},
methods: {
  // 验证
  validateCell(cb) {
    this.editTable
      .verifyTableCell(this.row, this.prop, this.cellState)
      .then(errMsg => {
        const valid = !errMsg;
        typeof cb === 'function' && cb(valid);
      });
  }
}

使用组件

// edit-table.vue

<page-edit-table
  ref="editTable"
  v-model="tableData"
  :columns="['categoryName', 'name', 'purchaseDate']"
  :default-edit="true"
  :verify-rules="verifyRules"
>
  <el-table
    ref="table"
    v-loading="loading"
    :data="tableData"
    tooltip-effect="dark"
    highlight-current-row
    border
    stripe
    style="width: 100%"
  >
    <el-table-column align="center" label="序号" width="50">
      <template slot-scope="scope">{{ scope.$index + 1 }}</template>
    </el-table-column>
    <el-table-column label="品目名称" prop="categoryName" show-overflow-tooltip>
      <template slot-scope="{ row }">
        <edit-table-cell :row="row" prop="categoryName">
          <template slot-scope="{ cellState, validateCell }">
            <el-select
              v-if="cellState.edit"
              v-model="row.categoryName"
              clearable
              placeholder="请选择品目"
              @change="validateCell"
            >
              <el-option label="你" value="1"></el-option>
              <el-option label="好" value="2"></el-option>
              <el-option label="呀" value="3"></el-option>
            </el-select>
            <span v-if="!cellState.edit">{{ row.categoryName }}</span>
          </template>
        </edit-table-cell>
      </template>
    </el-table-column>
....

效果以下vue-cli

图片描述

具体代码可查看组件segmentfault

增删改的树组件

el-tree树形组件其实已经支持了自定义节点内容,可是咱们要在它的基础上改变节点内容,这里主要是运用了Vue.set向响应式对象中添加一个属性。app

// 部分代码
append(node, data) {
  const { label } = this.configProps;
  const newChild = {
    id: id++,
    [label]: `三级-${id}`,
    children: [],
    isEdit: false
  };
  if (!data.children) {
    this.$set(data, 'children', []);
  }
  data.children.push(newChild);
  this.$emit('addNode', node, data);
},
edit(node, data) {
  if (!node.isEdit) {
    this.$set(node, 'isEdit', true);
  }
  this.$nextTick(() => {
    this.$refs[`treeInput${node.id}`].focus();
  });
  this.$emit('editNode', node, data);
}

效果以下:优化

图片描述

总结

组件是项目的积木条,公用组件的封装成功与否实际上是对项目的开发效率有直接影响。具体代码可查看vue-template,基于vue-cli3.0搭建的后台模版。

参考:

ElTable

el-table-editabled

相关文章
相关标签/搜索