若依穿透选人组件

转载自网址

1、先上效果图
在这里插入图片描述

2、选人组件代码

<template>
  <div>
    <el-dialog
      :title="'人员选择' + (type == 'multiple' ? '(多选)' : '(单选)')"
      :visible.sync="open"
      :width="width || '900px'"
      :height="height || '650px'"
      :before-close="handleClose"
      append-to-body
    >
      <div class="selectBox">
        <div class="bottomBox" v-show="showSearch">
          <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px">
            <el-row>
              <el-col :span="8">
                <el-form-item label="用户姓名" prop="nickName">
                  <el-input
                    v-model="queryParams.nickName"
                    placeholder="请输入用户姓名"
                    clearable
                    style="width: 200px"
                    size="mini"
                    @keyup.enter.native="getList"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="手机号码" prop="phonenumber">
                  <el-input
                    v-model="queryParams.phonenumber"
                    placeholder="请输入手机号码"
                    clearable
                    style="width: 200px"
                    size="mini"
                    @keyup.enter.native="getList"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item>
                  <el-button type="primary" icon="el-icon-search" size="mini" @click="getList">搜索</el-button>
                  <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
                </el-form-item>
              </el-col>
            </el-row>

          </el-form>
        </div>
        <div class="topBox">
          <div class="leftBox">
            <div class="contentBox">
              <div class="leftBox_title">组织架构</div>
              <div style="padding: 4px;margin-bottom: 4px;">
                <el-input
                  v-model="deptName"
                  placeholder="请输入部门名称"
                  clearable
                  size="mini"
                  prefix-icon="el-icon-search"
                >
                </el-input>
              </div>
              <div class="treeBox">
                <el-tree
                  :data="deptOptions"
                  :props="defaultProps"
                  :expand-on-click-node="false"
                  :filter-node-method="filterNode"
                  ref="tree"
                  node-key="id"
                  default-expand-all
                  highlight-current
                  @node-click="handleNodeClick"
                />
              </div>
            </div>
          </div>

          <div class="leftBox">
            <div class="contentBox">
              <div class="leftBox_title">
                人员选择
                <!-- <el-checkbox class="leftBox_title_do" style="right: 60px" v-model="userNodeAll" @change="handleCheckedNodeAll($event)">全选</el-checkbox>
                <el-checkbox class="leftBox_title_do" v-model="cancelUserNodeAll" @change="handleCheckedNodeAll($event)">全不选</el-checkbox> -->
                <el-button v-if="type == 'multiple'" class="leftBox_title_do" style="right: 70px" type="text"
                           size="mini" @click="handleCheckedNodeAll(true)">全选
                </el-button>
                <el-button v-if="type == 'multiple'" class="leftBox_title_do" type="text" size="mini"
                           @click="handleCheckedNodeAll(false)">全不选
                </el-button>
              </div>

              <div class="peopleBox">
                <div class="peopleList">
                  <el-checkbox-group ref="peopleCheckBoxes" v-model="checkedUsers" @change="handleCheckedUsersChange"
                                     :max="type == 'single' ? 1 : 2147483647">
                    <el-checkbox
                      v-for="item in userList"
                      :label="item.userName"
                      :key="item.userName"
                      class="peopleCard"
                    >
                      <div class="avatarBox">
                        <!-- <img v-if="item.avatar && item.avatar != ''" :src="item.avatar" class="user-avatar" onerror="οnerrοr=null;if(item) item.avatar = '';"> -->
                        <div style="background: #FFA502;" class="user-avatar">{{ item.nickName.substring(0,1) ||
                          item.userName.substring(0,1) || 'User' }}
                        </div>
                      </div>
                      <div class="peopleInfoBox">
                        <div class="peopleName">{{ item.nickName }}</div>
                        <div class="peopleDept">{{ item.dept.deptName || '' }}</div>
                      </div>
                    </el-checkbox>
                  </el-checkbox-group>

                </div>
              </div>
            </div>
          </div>
          <!-- this.checkedUsers -->
          <div class="leftBox">
            <div class="contentBox">
              <div class="leftBox_title">已选择人员
                <el-button v-if="type == 'multiple'" class="leftBox_title_do" type="text" size="mini" @click="clearAll">
                  全部清空
                </el-button>
              </div>
              <div class="peopleBox">
                <div class="peopleList">
                  <div
                    v-for="item in selectedUserList"
                    class="peopleCard"
                  >
                    <div class="avatarBox">
                      <!-- <img v-if="item.avatar && item.avatar != ''" :src="item.avatar" class="user-avatar" onerror="οnerrοr=null;if(item) item.avatar = '';"> -->
                      <div style="background: #FFA502;" class="user-avatar">{{ item.nickName.substring(0,1) ||
                        item.userName.substring(0,1) || 'User' }}
                      </div>
                    </div>
                    <div class="peopleInfoBox">
                      <div class="peopleName" style="margin-top:4px">{{ item.nickName }}</div>
                      <div class="peopleDept">{{ item.dept.deptName || '' }}</div>
                    </div>

                    <div class="peopleDeleteBtn" @click="deleteUserByUserName(item.userName)"></div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>

      </div>

      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
  </div>

</template>

<script>

  import { listUser, getUser, deptTreeSelect } from '@/api/system/user';
  import { getToken } from '@/utils/auth'
  import Treeselect from '@riophae/vue-treeselect';
  import "@riophae/vue-treeselect/dist/vue-treeselect.css";

  export default {
    name: 'PeopleSelect',
    dicts: ['sys_normal_disable', 'sys_user_sex'],
    components: { Treeselect },
    props: {
      width: {
        type: String,
        default: '900px'
      },
      height: {
        type: String,
        default: '650px'
      },
      type: {
        type: String,
        default: 'single' //single or multiple
      },
      open: {
        type: Boolean,
        default: false
      }
      // value: {
      //     type: Object,
      //     default: {
      //         userName: [],
      //         realName: []
      //     }
      // }
    },
    computed: {},
    data() {
      return {

        loading: false,

        // open: false,
        activeName: 'first',
        defaultProps: {
          children: 'children',
          label: 'label'
        },
        // 部门树选项
        deptOptions: undefined,
        deptName: '',
        showSearch: true,

        userList: [],
        allUserList: [],
        allUserMap: new Map(),
        selectedUserList: [],

        // 查询参数
        queryParams: {
          pageNum: 1,
          pageSize: 2147483647,
          userName: undefined,
          phonenumber: undefined,
          status: '0',
          deptId: undefined
        },

        //已选择的用户信息
        checkedUsers: []

        //   userNodeAll: false,
        //   cancelUserNodeAll: false,

      }
    },
    created() {
      this.getDeptTree()
      this.getAllUserList()
    },
    watch: {
      // 根据名称筛选部门树
      deptName(val) {
        this.$refs.tree.filter(val)
      }
    },
    methods: {
      handleClose(done) {
        this.$confirm('确认关闭?')
          .then(_ => {
            this.cancel()
          })
          .catch(_ => {
          })
      },
      handleClick(tab, event) {
        console.log(tab, event)
      },

      //获取选中的人员昵称列表
      getNickNameList(uns) {
        let result = []

        uns.forEach(item => {
          if (this.allUserMap.has(item)) {
            result.push(this.allUserMap.get(item).nickName || '')
          }
        })

        return result
      },
      //获取选中的人员ID列表
      getUserIdList(uns) {
        let result = []
        console.log(this.allUserMap);
        uns.forEach(item => {
          if (this.allUserMap.has(item)) {
            result.push(this.allUserMap.get(item).userId || '')
          }
        })

        return result
      },

      submitForm() {
        // console.log(this.checkedUsers, this.getNickNameList(this.checkedUsers));
        this.$emit('submit', this.checkedUsers, this.getNickNameList(this.checkedUsers), this.getUserIdList(this.checkedUsers)) //返回username和nickname
      },
      cancel() {
        this.$emit('cancel')
      },
      // 筛选节点
      filterNode(value, data) {
        if (!value) return true
        return data.label.indexOf(value) !== -1
      },
      // 节点单击事件
      handleNodeClick(data) {
        this.queryParams.deptId = data.id
        this.getList()
      },
      /** 查询部门下拉树结构 */
      getDeptTree() {
        deptTreeSelect().then(response => {
          this.deptOptions = response.data
        })
      },

      //第一步要做的 checkedUsers 为数组如['admin','ry'] 在父组件调用此方法并传入要回显的数组可进行复选框回显操作
      getAllUserList(checkedUsers = []) {
        //查出所有的用户,用于根据不同情况筛选显示
        listUser({ pageNum: 1, pageSize: 2147483647, status: '0' }).then(response => {
            this.allUserList = response.rows

            this.allUserMap = new Map()

            this.checkedUsers = checkedUsers

            this.allUserList.forEach(item => {
              this.allUserMap.set(item.userName, item)
            })
            this.updateCheckedUsers()
            //   console.log(this.allUserList, this.allUserMap);
            this.getList()
          }
        )
      },

      /** 查询用户列表 */
      getList() {
        listUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
            this.userList = response.rows
            //   console.log(this.userList);
          }
        )
      },

      /** 重置按钮操作 */
      resetQuery() {
        this.resetForm('queryForm')
        this.queryParams.deptId = undefined
        this.$refs.tree.setCurrentKey(null)
        this.getList()
      },

      handleCheckedUsersChange(val) {
        // console.log(this.$refs.peopleCheckBoxes.value);
        this.updateCheckedUsers()
      },

      updateCheckedUsers() {
        this.selectedUserList = []

        this.checkedUsers.forEach(item => {
          if (this.allUserMap.has(item)) {
            let u = this.allUserMap.get(item)
            this.selectedUserList.push(u)
          }
        })
      },

      deleteUserByUserName(username) {
        for (let i = 0; i < this.checkedUsers.length; i++) {
          if (this.checkedUsers[i].indexOf(username) != -1) {
            this.checkedUsers.splice(i, 1)
            this.updateCheckedUsers()
            break
          }
        }
      },

      handleCheckedNodeAll(val) {
        if (val) { //全选
          this.userList.forEach(item => {
            for (let i = 0; i < this.checkedUsers.length; i++) {
              if (this.checkedUsers[i] == item.userName) { //已存在,跳过
                return
              }
            }
            //不存在,执行添加
            this.checkedUsers.push(item.userName)
          })
        } else { //全不选
          this.userList.forEach(item => {
            for (let i = 0; i < this.checkedUsers.length; i++) {
              if (this.checkedUsers[i] == item.userName) { //已存在,执行删除
                this.checkedUsers.splice(i, 1)
                return
              }
            }
            //不存在,无需操作

          })
        }
        this.updateCheckedUsers()
      },

      clearAll() {
        this.checkedUsers = []
        this.updateCheckedUsers()
      }

    }
  }
</script>

<style lang="scss" scoped>

  .selectBox {
    width: 100%;
    min-width: 900px;
    display: flex;
    flex-direction: column;

    .topBox {
      width: 100%;
      display: flex;
      margin-top: 0px;

      .leftBox {
        width: 280px;
        height: 400px;
        margin-right: 10px;

        -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12), 0 0 6px 0 rgba(0, 0, 0, 0.04);
        box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12), 0 0 6px 0 rgba(0, 0, 0, 0.04);
        display: flex;
        flex-direction: column;

        .leftBox_title {
          width: 100%;
          height: 40px;
          font-size: 16px;
          line-height: 40px;
          padding-left: 10px;
          background-color: #f5f5f5;
          position: relative;

          .leftBox_title_do {
            position: absolute;
            right: 16px;
            top: 8px;
          }
        }

        .contentBox {
          width: 100%;

        }
      }
    }

    .bottomBox {
      margin-top: 15px;
      width: 100%;
      height: 55px;
      // border: 1px solid #DCDFE6;
      // -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12), 0 0 6px 0 rgba(0, 0, 0, 0.04);
      // box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12), 0 0 6px 0 rgba(0, 0, 0, 0.04);
      // overflow-y: auto;

      .selectPeopleList {
        width: 100%;
        display: flex;
        flex-wrap: wrap;

        .selectPeopleCard {
          width: 50px;
          height: 56px;
          display: flex;
          flex-direction: column;
          align-items: center;
          margin: 5px 10px;

          .user-avatar {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            color: #fff;
            background: #FFA502;
            font-size: 14px;
            text-align: center;
            line-height: 40px;
          }

          .userInfo {
            width: 100%;
            display: flex;
            flex-direction: column;
            margin-left: 5px;
            margin-right: 5px;

            div:nth-child(1) {
              font-size: 14px;
              white-space: nowrap;
              overflow: hidden;
              text-overflow: ellipsis;
              width: 100%;
              text-align: center;
            }
          }
        }
      }
    }

  }

  .treeBox {
    width: 100%;
    height: 320px;
    overflow-x: hidden;
    overflow-y: auto;
  }

  .peopleBox {
    width: 100%;
    height: 360px;
    overflow-x: hidden;
    overflow-y: auto;

    .peopleList {
      width: 100%;
      height: auto;


      .peopleCard:hover {
        background-color: #fafafa;
        transition: .2s;

        .peopleName {
          color: #eb6100;
        }
      }

      .peopleCard {
        width: 100%;
        height: 48px;
        border-top: solid #f5f5f5 1px;
        border-bottom: solid #f5f5f5 1px;
        padding-left: 8px;
        display: flex;
        align-items: center;
        cursor: pointer;
        transition: .2s;

        ::v-deep .el-checkbox__label {
          display: flex;
          align-items: center;
        }

        .avatarBox {
          width: 40px;
          height: 40px;

          .user-avatar {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            color: #fff;
            font-size: 16px;
            text-align: center;
            line-height: 40px;
            user-select: none;
          }
        }

        .peopleInfoBox {
          width: 190px;
          height: 100%;
          display: flex;
          flex-direction: column;
          padding-left: 8px;

          .peopleName {
            width: 100%;
            height: 20px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            font-size: 16px;
            line-height: 20px;

          }

          .peopleDept {
            width: 100%;
            height: 20px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            font-size: 14px;
            line-height: 20px;
            color: #999;
          }
        }

        .peopleDeleteBtn {
          width: 20px;
          height: 20px;
          // border-radius: 50%;
          background: url(./delete2.png) no-repeat;
          background-size: 100% 100%;
          transition: .2s;
        }

        .peopleDeleteBtn:hover {
          width: 20px;
          height: 20px;
          // border-radius: 50%;
          background: url(./delete1.png) no-repeat;
          background-size: 100% 100%;
          transition: .2s;
        }
      }
    }
  }

</style>

3、调用页面代码

<div>
      <h2>选人组件2</h2>
      <el-button type="primary" icon="el-icon-search" @click="openPS" size="mini" >打开选人组件</el-button>
      <PeopleSelect ref="peopleSelect" :type="type" :isCheck="true" :open="peopleOpen" @cancel="peopleOpen=false"   @submit="submitPeople"></PeopleSelect>
      <el-input v-model="psUserName" placeholder="请输入fileIds" />
      <el-input v-model="psNickName" placeholder="请输入fileIds" />
      <el-input v-model="psUserId" placeholder="请输入fileIds" />
    </div>
<script>
  import PeopleSelect from "@/components/PeopleSelect/index.vue";
  export default {
    name: 'exam',
    dicts: ['sys_normal_disable'],
    components:{
      PeopleSelect
    },
    data() {
      return {
        type: 'multiple',
        //是否打开选人组件,默认不打开
        peopleOpen:false,
        psUserName: [],
        psNickName: [],
        psUserId: []
      }
    },
    methods: {
      //打开选人弹窗
      openPS(){
        console.log("我被点了");
        this.peopleOpen=true;
      },
      //选择人的确定按钮事件 submitPeople(nikeNamelist)方法传参一个默认接收用户昵称数组   submitPeople(peopleList,nikeNamelist)方法传参两个则是接收用户昵称数组和用户账号数组
      submitPeople(peopleList,nikeNamelist,userIdList){
        this.psUserName=peopleList;
        this.psNickName=nikeNamelist;
        this.psUserId=userIdList;
        this.peopleOpen=false;
      },
    }
  }
</script>

<style>
</style>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vue中,scoped样式是一种给组件的样式添加作用域的方式,让样式在组件内起作用,不会影响到其他组件。然而,有时候我们希望某个组件的样式作用于其子组件或者父组件,这就需要穿透scoped样式。 对于子组件,我们可以通过使用`/deep/`或者`>>>`来穿透scoped样式。例如,在父组件的样式中,可以这样定义: ``` <style scoped> .parent /deep/ .child { color: red; } </style> ``` 在上面的例子中,`.parent`是父组件的样式,而`.child`是子组件的样式。使用`/deep/`可以让`.child`样式作用于子组件。 对于父组件,如果想要穿透scoped样式,可以通过将样式定义在全局样式中,或者使用`>>>`。例如,在子组件中,可以这样定义: ``` <template> <div class="parent"> <div class="child">子组件样式</div> </div> </template> <style scoped> .child { color: red; } .parent >>> .child { color: blue; } </style> ``` 在上面的例子中,`.child`是子组件的样式,`.parent`是父组件的样式。使用`>>>`可以让`.child`样式作用于父组件。 需要注意的是,`/deep/`和`>>>`只在一些支持CSS Modules的构建工具中生效,例如vue-loader。如果在其他环境中使用,可能无法生效。 总结:通过使用`/deep/`或者`>>>`,我们可以穿透Vue的scoped样式,让样式作用于子组件或者父组件。但是需要注意,这种方式只在部分构建工具中生效,不同环境可能会有差异。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值