| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 | <template>  <div>    <el-table :data="formatData" :row-style="showRow" v-bind="$attrs">      <el-table-column v-if="columns.length===0" width="150">        <template slot-scope="scope">          <span v-for="space in scope.row._level" :key="space" class="ms-tree-space" />          <span v-if="iconShow(0,scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)">            <i v-if="!scope.row._expanded" class="el-icon-plus" />            <i v-else class="el-icon-minus" />          </span>          {{ scope.$index }}        </template>      </el-table-column>      <el-table-column v-for="(column, index) in columns" v-else :key="column.value" :label="column.text" :width="column.width">        <template slot-scope="scope">          <span v-for="space in scope.row._level" v-if="index === 0" :key="space" class="ms-tree-space" />          <span v-if="iconShow(index,scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)">            <i v-if="!scope.row._expanded" class="el-icon-plus" />            <i v-else class="el-icon-minus" />          </span>          <el-checkbox-group v-if="Array.isArray(scope.row[column.value])" v-model="scope.row.selectchecked" @change="handleCheckedCitiesChange(scope.$index, scope.row,scope.row[column.option])">            <el-checkbox v-for="(interset) in scope.row[column.value]" :key="interset.id" :label="interset.id">{{ interset.description }}</el-checkbox>          </el-checkbox-group>          <el-checkbox v-else-if="scope.row.type===1" v-model="scope.row.checkAll" :indeterminate="scope.row.isIndeterminate" @change="handleCheckAllChange(scope.$index, scope.row,scope.row[column.option])">{{ scope.row[column.value] }}</el-checkbox>          <span v-else>{{ scope.row[column.value] }}</span>          <el-checkbox v-if="scope.row[column.act]" v-model="scope.row.checkAll" :indeterminate="scope.row.isIndeterminate" @change="handleCheckAllChange1(scope.$index, scope.row,column.option)">{{ scope.row[column.act] }}</el-checkbox>        </template>      </el-table-column>      <slot />    </el-table>    <footer>      <el-button @click="getAuth">确定</el-button>    </footer>  </div></template><script>/**  Auth: Lei.j1ang  Created: 2018/1/19-13:59*/import treeToArray from './eval'export default {  name: 'TreeTable',  props: {    data: {      type: [Array, Object],      required: true    },    columns: {      type: Array,      default: () => []    },    evalFunc: Function,    evalArgs: Array,    expandAll: {      type: Boolean,      default: true    }  },  computed: {    // 格式化数据源    formatData: function() {      let tmp      if (!Array.isArray(this.data)) {        console.log(this.data, 'this.data')        tmp = [this.data]      } else {        console.log(this.data, 'this.data')        tmp = this.data      }      const func = this.evalFunc || treeToArray      const args = this.evalArgs ? Array.concat([tmp, this.expandAll], this.evalArgs) : [tmp, this.expandAll]      return func.apply(null, args)    }  },  created() {    this.defaultSelcet()  },  methods: {    showRow: function(row) {      const show = (row.row.parent ? (row.row.parent._expanded && row.row.parent._show) : true)      row.row._show = show      return show ? 'animation:treeTableShow 1s;-webkit-animation:treeTableShow 1s;' : 'display:none;'    },    // 切换下级是否展开    toggleExpanded: function(trIndex) {      const record = this.formatData[trIndex]      record._expanded = !record._expanded    },    // 图标显示    iconShow(index, record) {      return (index === 0 && record.children && record.children.length > 0)    },    handleCheckAllChange(index, row, opt) {      console.log(index, row, opt)      this.cc()      if (row.selectchecked.length && row.selectchecked.length !== opt.length) {        const arr = []        opt.forEach(element => {          arr.push(element.id)        })        row.selectchecked = arr        row.checkAll = true        row.isIndeterminate = false      } else if (!row.selectchecked.length) {        const arr = []        opt.forEach(element => {          arr.push(element.id)        })        row.selectchecked = arr        row.checkAll = true        row.isIndeterminate = false      } else {        row.selectchecked = []        row.checkAll = false        row.isIndeterminate = false      }    },    handleCheckedCitiesChange(index, row, opt) {      row.checkAll = row.selectchecked.length === opt.length      row.isIndeterminate = row.selectchecked.length > 0 && row.selectchecked.length < opt.length      this.cc()    },    handleCheckAllChange1(index, row, opt) {      if (row.children) {        row.children.forEach(val => {          const arr = []          if (row.checkAll) {            val[opt].forEach(element => {              arr.push(element.id)            })            val.selectchecked = arr            val.checkAll = true            val.isIndeterminate = false          } else {            val.selectchecked = []            val.checkAll = false            val.isIndeterminate = false          }        })      }      this.cc()    },    defaultSelcet() {      this.data.forEach(val => {        if (val.children) {          val.children.forEach(el => {            if (el.selectchecked.length && el.selectchecked.length !== el[this.columns[0].option].length) {              el.isIndeterminate = true              el.checkAll = false            } else if (el.selectchecked.length && el.selectchecked.length === el[this.columns[0].option].length) {              el.isIndeterminate = false              el.checkAll = true            } else {              el.isIndeterminate = false              el.checkAll = false            }          })          this.cc()        }      })    },    cc() {      this.data.forEach(val => {        const checkAllArr = []        const isIndeterminateArr = []        if (val.children) {          val.children.forEach(el => {            checkAllArr.push(el.checkAll)            isIndeterminateArr.push(el.isIndeterminate)          })        }        if (new Set(checkAllArr).size === 1) { // && new Set(isIndeterminateArr).size !== 1          if (checkAllArr[0] && isIndeterminateArr[0] === false) {            val.isIndeterminate = false            val.checkAll = true          } else if (checkAllArr[0] && new Set(isIndeterminateArr).size !== 1) {            val.isIndeterminate = false            val.checkAll = true          } else if (!checkAllArr[0] && new Set(isIndeterminateArr).size !== 1) {            val.isIndeterminate = true            val.checkAll = false          } else if (!checkAllArr[0] && new Set(isIndeterminateArr).size === 1) {            if (!isIndeterminateArr[0]) {              val.isIndeterminate = false              val.checkAll = false            } else {              val.isIndeterminate = true              val.checkAll = false            }          } else {            val.isIndeterminate = false            val.checkAll = false          }        } else {          val.isIndeterminate = true          val.checkAll = false        }      })    },    getAuth() {      this.$emit('getAuth', this.data)    }  }}</script><style rel="stylesheet/css">  @keyframes treeTableShow {    from {opacity: 0;}    to {opacity: 1;}  }  @-webkit-keyframes treeTableShow {    from {opacity: 0;}    to {opacity: 1;}  }  .el-table__body{    text-align: left;  }</style><style lang="scss" rel="stylesheet/scss" scoped>  footer{    display: flex;    justify-content: flex-end;    margin-top: 15px;  }  $color-blue: #2196F3;  $space-width: 18px;  .ms-tree-space {    position: relative;    top: 1px;    display: inline-block;    font-style: normal;    font-weight: 400;    line-height: 1;    width: $space-width;    height: 14px;    &::before {      content: ""    }  }  .processContainer{    width: 100%;    height: 100%;  }  table td {    line-height: 26px;  }  .tree-ctrl{    position: relative;    cursor: pointer;    color: $color-blue;    margin-left: -$space-width;  }</style>
 |