2

封装TreeGrid组件

<template>
  <el-table
    :data="data"
    border
    :row-style="showRow">
    <el-table-column v-for="(column, index) in columns" :width="column.width" :key="column.dataIndex"
      :label="column.text">
      <template slot-scope="scope">
        <span v-if="spaceIconShow(index)" v-for="(space, levelIndex) in scope.row._level" class="ms-tree-space" :key="levelIndex"></span>
        <el-button type="success" plain size="mini" round v-if="toggleIconShow(index,scope.row)" @click="toggle(scope.$index)">
          <i v-if="!scope.row._expanded" class="el-icon-plus" aria-hidden="true"></i>
          <i v-if="scope.row._expanded" class="el-icon-minus" aria-hidden="true"></i>
        </el-button>
        <el-button size="mini" disabled round v-else-if="index===0">
          <i class="el-icon-minus"></i>
        </el-button>
        <span v-else-if="index===0" class="ms-tree-space"></span>
        {{scope.row[column.dataIndex]}}
      </template>
    </el-table-column>
    <el-table-column label="操作" v-if="controls" width="160">
      <template slot-scope="scope">
        <el-button plain title='修改商品分类'  type="primary" size="small" @click="getCateInfoById(scope.row)" icon="el-icon-edit"></el-button>
        <el-button plain title='删除商品分类'  type="danger" size="small" @click="deleteCategory(scope.row)" icon="el-icon-delete"></el-button>
      </template>
    </el-table-column>
  </el-table>
</template>
<script>
export default {
  name: 'tree-grid',
  props: {
    treeStructure: {
      type: Boolean,
      default: false
    },
    columns: {
      type: Array,
      default: function () {
        return []
      }
    },
    // 数据源
    dataSource: {
      type: Array,
      default: function () {
        return []
      }
    },
    // 是否展示操作列
    controls: {
      type: Boolean,
      default: true
    },
    // 是否默认展开所有树
    defaultExpandAll: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {}
  },
  computed: {
    // 格式化数据源
    data: function () {
      let me = this
      if (me.treeStructure) {
        let data = this.handleData(me.dataSource, null, null, me.defaultExpandAll)
        return data
      }
      return me.dataSource
    }
  },
  methods: {
    // 数据转换
    handleData: function (data, parent, level, expandedAll) {
      let _this = this
      let tmp = []
      Array.from(data).forEach(function (record) {
        if (record._expanded === undefined) {
          _this.$set(record, '_expanded', expandedAll)
        }
        if (parent) {
          _this.$set(record, '_parent', parent)
        }
        let _level = 0
        if (level !== undefined && level !== null) {
          _level = level + 1
        }
        _this.$set(record, '_level', _level)
        tmp.push(record)
        if (record.children && record.children.length > 0) {
          let children = _this.handleData(record.children, record, _level, expandedAll)
          tmp = tmp.concat(children)
        }
      })
      return tmp
    },
    // 显示行
    showRow: function ({row, rowIndex}) {
      let show = (row._parent ? (row._parent._expanded && row._parent._show) : true)
      row._show = show
      return show ? '' : 'display:none;'
    },
    // 展开下级
    toggle: function (trIndex) {
      let me = this
      let record = me.data[trIndex]
      record._expanded = !record._expanded
    },
    // 显示层级关系的空格和图标
    spaceIconShow (index) {
      let me = this
      if (me.treeStructure && index === 0) {
        return true
      }
      return false
    },
    // 点击展开和关闭的时候,切换图标
    toggleIconShow (index, record) {
      let me = this
      if (me.treeStructure && index === 0 && record.children && record.children.length > 0) {
        return true
      }
      return false
    },
    getCateInfoById (row) {
      // 根据ID查询分类信息
      this.$emit('editCate', row.cat_id)
    },
    deleteCategory (row) {
      // 删除分类
      this.$emit('deleteCate', row.cat_id)
    }
  }
}
</script>
<style scoped>
  .ms-tree-space{
    display: inline-block;
    width: 28px;
  }
  .el-button--mini, .el-button--mini.is-round {
    padding: 7px;
  }
</style>

READEME

# TreeGrid组件使用说明

## Attributes


| 参数          | 说明           | 类型    | 可选值               | 默认值 |
| ------------- | -------------- | ------- | -------------------- | ------ |
| treeStructure | 是否树形结构   | Boolean | -                    | false  |
| columns       | 列的属性       | Array   | text/dataIndex/width | -      |
| dataSource    | 数据源         | Array   | -                    | []     |
| controls      | 是否显示操作列 | Boolean | -                    | true   |

## Events


| 事件名称 | 说明         | 回调参数   |
| -------- | ------------ | ---------- |
| deleteCate   | 删除商品分类 | 商品分类id |
| editCate     | 编辑商品分类 | 商品分类id |

## 示例
<tree-grid
  :treeStructure="true"
  :columns="columns"
  :data-source="dataSource"
  @deleteCate="deleteCategory"
  @editCate="editCategory"
>
</tree-grid>

data () {
return {

dataSource: [],
columns: [{
  text: '分类名称',
  dataIndex: 'cat_name',
  width: ''
}, {
  text: '是否有效',
  dataIndex: 'cat_deleted',
  width: ''
}, {
  text: '排序',
  dataIndex: 'cat_level',
  width: ''
}]

}
},
methods: {
deleteCategory (cid) {

console.log(cid)

},
editCategory (cid) {

console.log(cid)

}
}

使用

<template>
<div class="category">

<el-row>
  <el-col :span="24">
    <el-breadcrumb separator="/">
    <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
    <el-breadcrumb-item>商品管理</el-breadcrumb-item>
    <el-breadcrumb-item>商品分类</el-breadcrumb-item>
  </el-breadcrumb>
  </el-col>
</el-row>

<el-row>
  <el-col :span="24">
    <el-button type="success" plain @click="addCategory">添加分类</el-button>
  </el-col>
</el-row>
<tree-grid
  :treeStructure="true"
  :columns="columns"
  :data-source="dataSource"
  @deleteCate="deleteCategory"
  @editCate="editCategory"
>
</tree-grid>

<div class="page">
  <el-pagination
    @size-change="handleSizeChange"
    @current-change="handleCurrentChange"
    :current-page="1"
    :page-sizes="[10, 20, 30, 40]"
    :page-size="10"
    layout="total, sizes, prev, pager, next, jumper"
    :total="total">
  </el-pagination>
</div>

<!-- 添加分类对话框 -->
<el-dialog title="添加分类" :visible.sync="addDialogFormVisible">
  <el-form :model="addForm" label-width="80px" :rules="rules" ref="addCateForm">
    <el-form-item label="分类名称" prop="cat_name">
      <el-input v-model="addForm.cat_name" auto-complete="off"></el-input>
    </el-form-item>
    <el-form-item label="父级名称">
      <el-cascader
        :options="options"
        v-model="selectedOptions"
        :props="props"
        @change="handleChange">
      </el-cascader>
    </el-form-item>
  </el-form>
  <div slot="footer" class="dialog-footer">
    <el-button @click="addDialogFormVisible = false">取 消</el-button>
    <el-button type="primary" @click="addCateSubmit('addCateForm')">确 定</el-button>
  </div>
</el-dialog>

</div>
</template>
<script>
import TreeGrid from '@/components/TreeGrid/TreeGrid'
import {getCategories, addCategories} from '@/api'
export default {
data () {

return {
  addForm: {
    cat_name: '',
    cat_pid: 0,
    cat_level: 0
  },
  options: [], // 级联选择器的数据源
  selectedOptions: [], // 级联选择器选中后的数据
  // props表示配置级联选择器展示的数据字段
  props: {
    value: 'cat_id',
    label: 'cat_name'
  },
  addDialogFormVisible: false,
  dataSource:{},
  total: 0,
  pagenum: 1,
  pagesize: 10,
  columns: [{
    text: '分类名称',
    dataIndex: 'cat_name',
    width: ''
  }, {
    text: '是否有效',
    dataIndex: 'cat_deleted',
    width: ''
  }, {
    text: '排序',
    dataIndex: 'cat_level',
    width: ''
  }],
  rules: {
    cat_name: [
      { required: true, message: '请输入分类名称', trigger: 'blur' }
    ]
  }
}

},
components: {

TreeGrid

},
created () {

this.initList()

},
methods: {

deleteCategory (cid) {
  console.log(cid)
},
editCategory (cid) {
  console.log(cid)
},
handleSizeChange (val) {
  console.log(`每页 ${val} 条`)
  this.pagesize = val
  this.initList()
},
handleCurrentChange (val) {
  console.log(`当前页: ${val}`)
  this.pagenum = val
  this.initList()
},
initList () {
  getCategories({type: '3', pagenum: this.pagenum, pagesize: this.pagesize}).then(res => {

    if (res.meta.status === 200) {
      this.total = res.data.total
      this.dataSource = res.data.result
    }
  })
},
handleChange (value) {
  console.log(value)
},
addCategory () {
  this.addDialogFormVisible = true
  getCategories({type: '2'}).then(res => {

    if (res.meta.status === 200) {
      this.options = res.data
    }
  })
},
addCateSubmit (formName) {
  this.$refs[formName].validate(valide => {
    if (valide) {
      if (this.selectedOptions.length === 0) {
        this.addForm.cat_pid = 0
        this.addForm.cat_level = 0
      } else if (this.selectedOptions.length === 1) {
        this.addForm.cat_pid = this.selectedOptions[this.selectedOptions.length - 1]
        this.addForm.cat_level = 1
      } else {
        this.addForm.cat_pid = this.selectedOptions[this.selectedOptions.length - 1]
        this.addForm.cat_level = 2
      }
      addCategories(this.addForm).then(res => {
        if (res.meta.status === 201) {
          this.addDialogFormVisible = false
          this.initList()
          this.$message({
            type: 'success',
            message: res.meta.msg
          })
        }
      })
    }
  })
}

}
}
</script>
<style lang="scss" scoped>
.category {
.page {

padding: 5px 0;
background-color: #D3DCE6;

}
}
</style>


HappyCodingTop
526 声望847 粉丝

Talk is cheap, show the code!!