vue2组件写法

例:人员组件

<template>
  <el-dialog append-to-body title="人员选择" v-model="platformBox" draggable>
    <el-container>
      <el-aside v-if="deptView" style="height: 450px;width: 30%;border-right: 1px solid #e8eaec;margin-right:15px">
        <div style="font-size: 13px;color: #3D3D3D;font-weight: bold;margin-bottom: 5px">组织机构列表</div>
        <div style="height: 420px;">
          <el-tree :data="filteredDataSource"
                   :filter-node-method="filterNode"
                   @node-click="nodeClick"
                   class="filter-tree"
                   default-expand-all
                   icon="ArrowRightBold"
                   node-key="id"
                   ref="treeRef">
            <template v-slot="{ data }">
              <span class="treeIcon">{{ data.title }}</span>
            </template>
          </el-tree>
        </div>
      </el-aside>
      <el-main class="avue-crud" style="height: 500px;">
        <el-row v-if="!deptView">
            <span style="padding-bottom: 10px ">
             部门: {{deptsName}}
            </span>
        </el-row>
        <el-row :hidden="!search" class="search-row">
          <!-- 查询模块 -->
          <el-form :inline="true" :model="query">
            <el-form-item label="用户姓名:">
              <el-input placeholder="请输入用户姓名" v-model="query.realName"></el-input>
            </el-form-item>
          </el-form>
          <!-- 查询按钮 -->
          <div>
            <el-button @click="searchChange" icon="el-icon-search" type="primary">搜 索</el-button>
            <el-button @click="searchReset()" icon="el-icon-delete">清 空</el-button>
          </div>
        </el-row>
        <el-row>
          <!-- 列表模块 -->
          <el-table :border="option.border" :data="data"
                    :row-key='getRowKey'
                    @select="selectChange"
                    @select-all="selectAllChange"
                    @row-click="rowClick"
                    height="300px"
                    ref="table"
                    style="width: 100%;overflow: auto;"
                    v-loading="loading">
            <el-table-column
                :reserve-selection="true"
                align="center"
                type="selection"
                width="55"
            />
            <el-table-column align="center" type="expand" v-if="option.expand" width="55"></el-table-column>
            <el-table-column align="center" label="#" type="index" v-if="option.index" width="50">
            </el-table-column>
            <template v-for="(item,index) in option.column">
              <!-- table字段 -->
              <el-table-column :key="index"
                               :label="item.label"
                               :prop="item.prop"
                               :width="item.width"
                               align="center"
                               v-if="item.hide!==true"
                               show-overflow-tooltip>
              </el-table-column>
            </template>
          </el-table>
        </el-row>
        <el-row>
          <div class="avue-crud__pagination" style="width:100%">
            <!-- 分页模块 -->
            <el-pagination :current-page="page.currentPage"
                           :page-size="page.pageSize"
                           :page-sizes="[10, 20, 30, 40, 50, 100]"
                           :total="page.total"
                           @current-change="currentChange"
                           @size-change="sizeChange"
                           align="right"
                           layout="total, sizes, prev, pager, next, jumper">
            </el-pagination>
          </div>
        </el-row>
        <!-- 底部按钮区域 -->
        <div
            style="border-top: 1px solid #DCDFE6;padding: 12px 0 10px;margin:15px auto 0; display:flex;justify-content: center">
          <el-button @click="selectData" type="primary">选择</el-button>
          <el-button @click="platformBox=false">关闭</el-button>
        </div>
      </el-main>
    </el-container>
  </el-dialog>
</template>

<script>
import {getDeptTree} from '@/api/system/dept';
import {getList, getListIds} from '@/api/system/user';
import func from '../../utils/func';

export default {
  props: {
    userIds: {//用于回显’,‘号隔开
      type: String
    },
    type: {//类型 radio.单选,check.多选
      type: String
    },
    deptNames: {//部门名称
      type: String
    },
    deptId: { //用于过滤树节点
      type: String
    }
  },
  data() {
    return {
      height: 0,
      heightPage: 0,
      plusBtnType: true,//默认显示 加号
      platformBox: false,
      // 弹框标题
      title: '',
      // 是否展示弹框
      box: false,
      // 是否显示查询
      search: true,
      // 加载中
      loading: true,
      // 是否为查看模式
      view: false,
      // 查询信息
      query: {},
      // 分页信息
      page: {
        currentPage: 1,
        pageSize: 10,
        total: 40
      },
      // 表单数据
      form: {},
      // 选择行
      selectionList: [],
      // 表单配置
      option: {
        expand: false,
        index: true,
        border: true,
        selection: true,
        column: [
          {
            label: '主键',
            prop: 'id',
            display: false,
            hide: true
          },
          {
            label: '租户ID',
            prop: 'tenantId',
            display: false,
            hide: true
          },
          {
            label: '用户姓名',
            prop: 'realName',
            search: true
          },
          {
            label: '所属角色',
            prop: 'roleName'
          },
          {
            label: '所属部门',
            prop: 'deptName'
          }
        ]
      },
      // 表单列表
      data: [],
      value: '',
      dataSource: [],
      userList: [],
      filteredDataSource: [], // 过滤后的部门树数据
      deptView:false,
      deptsName: ''
    };
  },
  computed: {
    ...mapGetters(['permission']),
    permissionList() {
      return {
        addBtn: this.validData(this.permission.param_add, false),
        viewBtn: this.validData(this.permission.param_view, false),
        delBtn: this.validData(this.permission.param_delete, false),
        editBtn: this.validData(this.permission.param_edit, false)
      };
    },
    ids() {
      let ids = [];
      this.selectionList.forEach(ele => {
        ids.push(ele.id);
      });
      return ids.join(',');
    }
  },
  methods: {
    //打开弹框
    openDialog() {
      if(this.deptId){
        this.deptView=false;
        this.query.deptId = this.deptId;
        this.deptsName=this.deptNames;
      }else{
        this.getListTree();
      }
      this.platformBox = true;
      if (this.userIds !== '' && this.userIds !== undefined) {
        //查询人员列表
        this.getUserList(this.userIds);
      } else {
        this.userList = [];
      };
      this.onLoad(this.page);
    },
    getListTree() {
      getDeptTree().then(data => {
        this.dataSource = data.data.data;
        if (!this.deptId) {
          this.filteredDataSource = this.dataSource; //如果没有传递deptId则显示全部数据
        } else {
          this.filterTreeByDeptId(this.deptId); // 根据传入的deptId进行过滤
        }
      });
    },
    //点击多选
    selectAllChange(selection) {
      if (this.type === 'radio') {//单选
        this.$refs.table.clearSelection();
        // 单选时设置表格复选框
        this.userList = selection.slice(0, 1);
        this.$refs.table.toggleRowSelection(this.userList[0]);
        return;
      } else {//多选
        if (selection.length > 0) {//多选全选
          //不包含的新增
          selection.forEach(res => {
            if (this.userList.map(item => item.id).indexOf(res.id) === -1) {
              this.userList.push(res);
            }
          });
        } else {//多选取消全选
          //删除当前data中的数据
          this.data.forEach(res => {
            this.userList.map((item, index) => {
              if (res.id === item.id) {
                this.userList.splice(index, 1);
              }
            });
          });
        }
      }
    },
    //选择一项
    selectChange(selection, row) {
      if (this.type === 'radio') {//单选
        this.$refs.table.clearSelection();
        if (this.userList.filter(item => item.id === row.id).length === 0) {
          this.userList = [];
          this.userList.push(row);
          this.$refs.table.toggleRowSelection(this.userList[0]);
        }
        return;
      } else {//多选
        if (this.userList.map(item => item.id).indexOf(row.id) !== -1) {
          this.userList.map((item, index) => {
            if (item.id === row.id) {
              this.userList.splice(index, 1);
            }
          });
        } else {
          this.userList.push(row);
        }
      }
    },
    //当某一行被点击时会触发该事件
    rowClick(row) {
      if (this.type === 'radio') {//单选
        if (this.userList.map(item => item.id).indexOf(row.id) !== -1) {
          //清空选中的数据
          this.userList = [];
          this.$refs.table.clearSelection();
        } else {
          this.userList = [];
          this.$refs.table.clearSelection();
          this.userList.push(row);
          this.$refs.table.toggleRowSelection(row);
        }
      } else {
        if (this.userList.map(item => item.id).indexOf(row.id) !== -1) {
          //清空选中的数据
          this.$refs.table.toggleRowSelection(row, false);
          this.userList.map((item, index) => {
            if (item.id === row.id) {
              this.userList.splice(index, 1);
              //取消選擇
            }
          });
        } else {
          this.userList.push(row);
          this.$refs.table.toggleRowSelection(row);
        }
      }
    },
    selectData() {
      if (this.userList.length === 0) {
        this.$message.warning('请先选择人员');
        return;
      }
      this.$emit('userList', this.userList);
      this.platformBox = false;
      this.$refs.table.clearSelection();
    },
    //组件传参
    nodeClick(data) {
      if (this.query.deptId === data.id) {
        this.$refs.treeRef.setCurrentKey(null);
        this.query.deptId = null;
      } else {
        this.query.deptId = data.id;
      }
      this.page.currentPage = 1;
      this.onLoad(this.page);
    },
    filterTreeByDeptId(deptId) {
      // 深拷贝 dataSource,以避免直接修改原始数据
      const clonedData = JSON.parse(JSON.stringify(this.dataSource));
      // 调用递归过滤方法
      this.filteredDataSource = this.filterTree(clonedData, deptId);
    },
    filterTree(data, deptId) {
      // 条件就是节点的title过滤关键字
      let predicate = function (node) {
        if (node.id.includes(deptId)) {
          return true;
        } else {
          return false;
        }
      };

      // 结束递归的条件
      if (!(data && data.length)) {
        return [];
      }
      let newChildren = [];
      for (let node of data) {
        if (predicate(node)) {
          newChildren.push(node);
          node.children = this.filterTree(node.children, deptId);
        } else {
          newChildren.push(...this.filterTree(node.children, deptId));
        }
      }
      return newChildren.length ? newChildren : [];
    },
    //过滤树节点
    filterNode(value, data) {
      if (!value) return true;
      return data.label.includes(value);
    }
    ,
    searchHide() {
      this.search = !this.search;
    }
    ,
    searchChange() {
      this.onLoad(this.page);
    }
    ,
    searchReset() {
      this.query = {};
      this.page.currentPage = 1;
      this.onLoad(this.page);
    }
    ,
    getRowKey(row) {
      return row.id;
    }
    ,
    sizeChange(pageSize) {
      this.page.pageSize = pageSize;
      this.onLoad(this.page);
    }
    ,
    currentChange(currentPage) {
      this.page.currentPage = currentPage;
      this.onLoad(this.page);
    }
    ,
    selectionClear() {
      this.selectionList = [];
      this.$refs.table.clearSelection();
    }
    ,
    //根据ids查询人员列表
    getUserList(ids) {
      getListIds(ids).then(res => {
        this.userList = res.data.data;
      });
    }
    ,
    onLoad(page, params = {}) {
      this.loading = true;
      const {
        code,
        name
      } = this.query;
      getList(page.currentPage, page.pageSize, this.query).then(res => {
            const data = res.data.data;
            this.page.total = data.total;
            const resData = [];
            data.records.forEach(item => {
              if (item.deptId === this.deptId) {
                resData.push(item)
              }
            });
            if (!this.deptId) {
              this.data = data.records;
            } else {
              this.data = resData;
            }
            this.loading = false;
            this.selectionClear();
            this.handleDialogOpen();
          }
      )
      ;
    }
    ,
//已选择的数据回显
    handleDialogOpen() {
      if (this.userList !== undefined) {
        this.data.map(item => {
          this.userList.map(res => {
            if (item.id === res.id) {
              this.$refs.table.toggleRowSelection(item);
            }
          });
        });
      }
    }
  }
}
;
</script>
<style scoped>
.treeIcon {
  width: 150px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
</style>
<style>
.filter-tree .el-tree-node__content {
  height: 30px;
}

.filter-tree .el-tree-node__content:hover {
  background-color: #e3ecff;
}

</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值