elementui 树形table 以及选择联动


通过elementui的树形table组件,实现多级联动效果

效果截图

element 版本 element-ui": "2.13.2

主要思想 递归

vue页面 包括数据结构 js

<template>
    <div class="tree-table-wrapper">
        <el-table
            :data="tableData"
            style="width: 100%;margin-bottom: 20px;"
            row-key="id"
            border
            :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
        >
            <el-table-column prop="name" label="页面" width="180">
                <template slot-scope="props">
                    <el-checkbox
                        v-model="props.row.isChecked"
                        :indeterminate="props.row.indeterminate"
                        @change="checkboxChange(props.row)"
                    />
                    {{ props.row.name }}
                    {{ props.row.isChecked }}
                </template>
            </el-table-column>
            <el-table-column prop="authList" label="权限">
                <template slot-scope="props">
                    <div class="auth-checkbox">
                        <div v-for="(item, i) in props.row.authList" :key="i">
                            <el-checkbox
                                v-model="item.isChecked"
                                @change="checkboxChangeRight(props.row, item)"
                            ></el-checkbox>
                            {{item.name}}{{item.isChecked}}
                        </div>
                    </div>
                </template>
            </el-table-column>
        </el-table>
    </div>
</template>

<script>
export default {
  name: 'TreeTable',
  data() {
    return {
      tableData: [
        {
          id: 1,
          date: '2016-05-02',
          name: '王小虎1',
          address: '上海市普陀区金沙江路 1518 弄',
          isChecked: false,
          indeterminate: false,
          authList: [
            {
              id: 101,
              pid: 1,
              date: '2016-05-02',
              name: '页面1',
              address: '上海市普陀区金沙江路 1518 弄',
              isChecked: false
            },
            {
              id: 102,
              pic: 1,
              date: '2016-05-02',
              name: '页面2',
              address: '上海市普陀区金沙江路 1518 弄',
              isChecked: false
            }
          ]
        },
        {
          id: 2,
          date: '2016-05-04',
          name: '王小虎1',
          address: '上海市普陀区金沙江路 1517 弄',
          isChecked: false,
          indeterminate: false,
          authList: [
            {
              id: 201,
              pid: 2,
              date: '2016-05-02',
              name: '页面1',
              address: '上海市普陀区金沙江路 1518 弄',
              isChecked: false
            },
            {
              id: 201,
              pid: 2,
              date: '2016-05-02',
              name: '页面2',
              address: '上海市普陀区金沙江路 1518 弄',
              isChecked: false
            }
          ]
        },
        {
          id: 3,
          date: '2016-05-01',
          name: '王小虎1',
          address: '上海市普陀区金沙江路 1519 弄',
          isChecked: false,
          indeterminate: false,
          authList: [
            {
              id: 301,
              pid: 3,
              date: '2016-05-02',
              name: '页面1',
              address: '上海市普陀区金沙江路 1518 弄',
              isChecked: false
            },
            {
              id: 302,
              pid: 3,
              date: '2016-05-02',
              name: '页面2',
              address: '上海市普陀区金沙江路 1518 弄',
              isChecked: false
            }
          ],
          children: [
            {
              pid: 3,
              id: 31,
              date: '2016-05-01',
              name: '王小虎2',
              address: '上海市普陀区金沙江路 1519 弄',
              isChecked: false,
              indeterminate: false,
              authList: [
                {
                  id: 3101,
                  pid: 31,
                  date: '2016-05-02',
                  name: '页面1',
                  address: '上海市普陀区金沙江路 1518 弄',
                  isChecked: false
                },
                {
                  id: 3102,
                  pid: 31,
                  date: '2016-05-02',
                  name: '页面2',
                  address: '上海市普陀区金沙江路 1518 弄',
                  isChecked: false
                }
              ]
            },
            {
              pid: 3,
              id: 32,
              date: '2016-05-01',
              name: '王小虎2',
              address: '上海市普陀区金沙江路 1519 弄',
              isChecked: false,
              indeterminate: false,
              authList: [
                {
                  id: 3201,
                  pid: 32,
                  date: '2016-05-02',
                  name: '页面1',
                  address: '上海市普陀区金沙江路 1518 弄',
                  isChecked: false
                },
                {
                  id: 3202,
                  pid: 32,
                  date: '2016-05-02',
                  name: '页面2',
                  address: '上海市普陀区金沙江路 1518 弄',
                  isChecked: false
                }
              ],
              children: [
                {
                  pid: 32,
                  id: 321,
                  date: '2016-05-01',
                  name: '王小虎3',
                  address: '上海市普陀区金沙江路 1519 弄',
                  isChecked: false,
                  indeterminate: false,
                  authList: [
                    {
                      id: 32101,
                      pid: 321,
                      date: '2016-05-02',
                      name: '页面1',
                      address: '上海市普陀区金沙江路 1518 弄',
                      isChecked: false
                    },
                    {
                      id: 32102,
                      pid: 321,
                      date: '2016-05-02',
                      name: '页面2',
                      address: '上海市普陀区金沙江路 1518 弄',
                      isChecked: false
                    }
                  ]
                },
                {
                  pid: 32,
                  id: 322,
                  date: '2016-05-01',
                  name: '王小虎3',
                  address: '上海市普陀区金沙江路 1519 弄',
                  isChecked: false,
                  indeterminate: false,
                  authList: [
                    {
                      id: 1,
                      date: '2016-05-02',
                      name: '页面1',
                      address: '上海市普陀区金沙江路 1518 弄',
                      isChecked: false
                    },
                    {
                      id: 1,
                      date: '2016-05-02',
                      name: '页面2',
                      address: '上海市普陀区金沙江路 1518 弄',
                      isChecked: false
                    }
                  ]
                }
              ]
            }
          ]
        },
        {
          id: 4,
          date: '2016-05-03',
          name: '王小虎1',
          address: '上海市普陀区金沙江路 1516 弄',
          isChecked: false,
          indeterminate: false,
          authList: [
            {
              id: 1,
              date: '2016-05-02',
              name: '页面1',
              address: '上海市普陀区金沙江路 1518 弄',
              isChecked: false
            },
            {
              id: 1,
              date: '2016-05-02',
              name: '页面2',
              address: '上海市普陀区金沙江路 1518 弄',
              isChecked: false
            }
          ]
        }
      ]
    }
  },
  methods: {
    /**
     * 左侧复选框 按钮点击事件
     * @param {row: object} 当前选中的row数据
     * */

    checkboxChange(row) {
      const self = this
      // 当前checkbox状态
      const isChecked = row.isChecked
      /**
       * 父级全选
       * @param {row: object}
       * 点击左侧checkbox 时 子级所有选项选中或取消 -- 包括右侧checkbox
       * */

      changeAll(row)
      function changeAll(rowData) {
        // rowData.indeterminate = false
        // 改变checkbox状态
        rowData.isChecked = isChecked
        // 改变右侧表格中的checkbox
        rowData.authList &&
          rowData.authList.forEach(authItem => {
            authItem.isChecked = isChecked
          })
        if (rowData.children) {
          rowData.children.forEach(element => {
            // element.indeterminate = false
            // element.isChecked = isChecked
            // element.authList.forEach(authItem => {
            //   authItem.isChecked = isChecked
            // })
            // if (element.children) {
            //   changeAll(element)
            // }
            // 递归处理数据
            changeAll(element)
          })
        }
      }

      /**
       * 子级选择
       * @param {row: object}
       * 点击子级选项 选中子级右侧数据 同时递归选中父级以及祖级
       * */

      changeParents(row)
      function changeParents(rowData) {
        // 所有数据
        const allData = self.tableData
        // 当前选择的pid
        const pid = rowData.pid

        findParent(allData, pid)
        // 递归处理
        function findParent(element, pid) {
          element.forEach(item => {
            if (item.id == pid) {
              if (isChecked) {
                // 选中状态为true
                // item.indeterminate = true
                item.isChecked = true
                // 递归处理父级状态
                const pid = item.pid
                findParent(allData, pid)
              } else {
                changeLeftParent(self.tableData, row.pid)
              }
            } else {
              if (item.children) {
                findParent(item.children, pid)
              }
            }
          })
        }
      }

      // 处理左侧取消checkbox状态
      function changeLeftParent(element, pid) {
        element.forEach(item => {
          const checkList = []
          if (item.id == pid) {
            if (item.children) {
              item.children.forEach(citem => {
                checkList.push(citem.isChecked)
                citem.authList.forEach(cauthItem => {
                  checkList.push(cauthItem.isChecked)
                })
              })
            }
            item.authList.forEach(cauthItem => {
              checkList.push(cauthItem.isChecked)
            })

            if (!checkList.includes(true)) {
              item.isChecked = false
              changeLeftParent(self.tableData, item.pid)
            }
          } else {
            if (item.children) {
              changeLeftParent(item.children, pid)
            }
          }
        })
      }
    },
    // checkbox right
    checkboxChangeRight(row, item) {
      const self = this
      // 父级选择
      const isChecked = item.isChecked
      if (isChecked) {
        // 状态为true
        row.isChecked = true
      } else {
        // 状态为false
        // ----------取消父级的选中状态-------------
        const checkList = []
        row.authList.forEach(authItem => {
          checkList.push(authItem.isChecked)
        })
        if (!row.children) {
          // 无子级
          if (!checkList.includes(true)) {
            row.isChecked = false
          }

          //
          changeLeftParent(self.tableData, row.pid)
        } else {
          // 有子级
          if (!checkList.includes(true)) {
            const checkList = []
            row.children.forEach(item => {
              checkList.push(item.isChecked)
            })

            if (!checkList.includes(true)) {
              row.isChecked = false
            }
          }

          changeLeftParent(self.tableData, row.pid)
        }
        // ------------------------------------------
      }

      const allData = self.tableData
      findParent(allData, row.pid)
      // 递归处理
      function findParent(element, pid) {
        element.forEach(item => {
          if (item.id == pid) {
            if (isChecked) {
              // 选中状态为true
              // item.indeterminate = true
              item.isChecked = true
              // 递归处理父级状态
              const pid = item.pid
              findParent(allData, pid)
            }
          } else {
            if (item.children) {
              findParent(item.children, pid)
            }
          }
        })
      }

      // 处理左侧取消checkbox状态
      function changeLeftParent(element, pid) {
        element.forEach(item => {
          const checkList = []
          if (item.id == pid) {
            if (item.children) {
              item.children.forEach(citem => {
                checkList.push(citem.isChecked)
                citem.authList.forEach(cauthItem => {
                  checkList.push(cauthItem.isChecked)
                })
              })
            }
            item.authList.forEach(cauthItem => {
              checkList.push(cauthItem.isChecked)
            })

            if (!checkList.includes(true)) {
              item.isChecked = false
              changeLeftParent(self.tableData, item.pid)
            }
          } else {
            if (item.children) {
              changeLeftParent(item.children, pid)
            }
          }
        })
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.auth-checkbox {
    width: 100%;
    // display: flex;
    // flex-wrap: wrap;
    display: grid;
    grid-template-columns: repeat(10, 1fr);
    div {
        margin-right: 5px;
    }
}
</style>


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM