前端人员选择组件封装

功能:

  • 人员选择,返回人员参数,以及人员参数id数组
  • 支持单选,多选人员
  • 支持重新选择回显上次选中人员
    <!-- 弹窗 -->
    <a-modal v-model="modalVisible" :footer="null" :bodyStyle="{ padding: 0 }" :width="800" :closable="true"
      :centered="true" :destroyOnClose="true">
      <!-- 角色 -->
      <template v-if="type === 'role'">
        <choose-role @chooseRole="commonChoose" :single="single" :pSelectIds="selectIds" :pSelectList="selectList"
          :modalTitle="modalTitle ? modalTitle : '选择角色'" />
      </template>
      <!-- 其他类似组件... -->
    </a-modal>
<template>
  <div class="common-modal-container">
    <div class="title-container">
      <p class="title">{{ modalTitle }}</p>
    </div>
    <div class="choose-content-container">
      <div class="choose-content-left-container">
        <div class="left-container">
          <p class="title">选择:</p>
        </div>
        <div class="common-content-container">
          <div style="margin:12px 0 16px">
            <a-input v-model="searchParams.name" placeholder="搜索" @change="search" class="common-modal-input"
              allowClear>
              <img slot="prefix"
                src="https://hs-pro-server.oss-cn-hangzhou.aliyuncs.com/saas/saaspc/assets/images/icon_search.png"
                style="width:14px" />
            </a-input>
          </div>
          <div class="scroll-container">
            <template v-if="loading">
              <a-spin />
            </template>
            <vuescroll :ops="ops" ref="vs" @handle-scroll="handleScroll">
              <template v-if="single === 1">
                <a-radio :style="radioStyle" :checked="item.checked" :value="item.id" v-for="item, index in choiceList"
                  :key="index" @click="onChange(item, 1)">
                  <span>{{ item.roleName }}</span>
                </a-radio>
              </template>
              <template v-else>
                <a-checkbox :style="radioStyle" :checked="item.checked" :value="item.id"
                  v-for="item, index in choiceList" :key="index" @click="onChange(item, 1)">
                  <span>{{ item.roleName }}</span>
                </a-checkbox>
              </template>
              <div v-if="!loading && choiceList.length === 0" class="no-data-modal-container">
                <img slot="prefix"
                  src="https://hs-pro-server.oss-cn-hangzhou.aliyuncs.com/saas/saaspc/assets/images/train/icon_no_data_modal.png"
                  style="width:86px" />
                <p>暂无数据~</p>
              </div>
            </vuescroll>
          </div>
        </div>
      </div>
      <div class="choose-content-left-container">
        <div class="left-container" style="margin-bottom:8px">
          <p class="title">已选:</p>
        </div>
        <div class="common-content-container">
          <vuescroll :ops="ops">
            <div class="content-list-container">
              <div class="content-container" v-for="item, index in selectList" :key="index">
                <span v-text="item.roleName"></span>
                <i class="iconfont icon-quxiao" @click.stop="onChange(item, 2)" />
              </div>
            </div>
          </vuescroll>
        </div>
      </div>
    </div>
    <div class="choose-footer-container">
      <a-button class="reset-btn" @click="submit(1)">取消</a-button>
      <a-button class="submit-btn" type="primary" @click="submit(2)">确定</a-button>
    </div>
  </div>
</template>
<script>
import vuescroll from "vuescroll";
import { getRoleList } from "@/api/member/member";
import _ from "lodash";
import moment from "moment";
export default {
  name: "chooseRole",
  components: {
    vuescroll,
  },
  props: {
    pSelectIds: {
      type: Array,
      default: () => [],
    },
    pSelectList: {
      type: Array,
      default: () => [],
    },
    modalTitle: {
      type: String,
      default: '请选择人员',
    },
    single: Number, //1-单选 2-多选
  },
  data () {
    return {
      ops: {
        bar: {
          background: "#2E5BFF",
        },
      },
      searchParams: {
        current: 1,
        size: 10,
        name: "",
      },
      choiceList: [],
      loading: true,
      searchContent: "",
      selectList: [],
      selectIds: [],
      radioStyle: {
        margin: "0",
        padding: "6px 20px",
        display: "block",
        lineHeight: "20px",
        position: "relative",
      },
    };
  },
  created () {
    this.selectList = this.pSelectList;
    this.selectIds = this.pSelectIds;
    this.getList();
  },
  mounted () { },
  computed: {},
  methods: {
    getList () {
      // 获取用户
      let params = this.searchParams;
      this.loading = true;
      this.searchTime = moment().valueOf();
      params.searchTime = this.searchTime;
      getRoleList(params).then((res) => {
        const { searchTime } = res.config.params;
        const { records, current, total } = res.data.data;
        if (this.searchTime === searchTime) {
          this.loading = false;
          let selectIds = this.selectIds;
          if (params.current == 1) this.choiceList = []; //如果是第一页需手动制空列表
          this.choiceList = this.choiceList.concat(
            records.map((a) => {
              a.checked = selectIds.indexOf(a.id) > -1;
              return a;
            })
          ); //追加新数据
          this.finish = records.length < params.size;
        }
      });
    },
    handleSubmit () {
      this.searchParams.current = 1;
      this.getList();
    },
    handleScroll (vertical, horizontal, nativeEvent) {
      console.log(vertical, horizontal, nativeEvent);
      const { v, h } = this.$refs["vs"].getScrollProcess();
      console.log(v, h);
      if (v >= 0.9) {
        if (!this.loading && !this.finish) {
          this.searchParams.current++;
          this.getList();
        }
      }
    },
    search: _.throttle(function() {
      this.handleSubmit();
    }, 100),
    onChange (item, type) {
      if (this.single === 1) {
        if (type === 1) {
          this.choiceList = this.choiceList.map((a) => {
            if (a.id === item.id) {
              a.checked = true;
            } else {
              a.checked = false;
            }
            return a;
          });
        } else {
          this.choiceList = this.choiceList.map((a) => {
            a.checked = false;
            return a;
          });
        }
        this.selectList = this.choiceList.filter((a) => a.checked);
      } else {
        this.choiceList = this.choiceList.map((a) => {
          if (a.id === item.id) {
            a.checked = !a.checked;
          }
          return a;
        });
        if (type === 1) {
          let selectList = this.selectList.filter((a) => a.id === item.id);
          if (selectList.length > 0) {
            this.selectList = this.selectList.filter((a) => a.id !== item.id);
          } else {
            this.selectList = this.selectList.concat(
              this.choiceList.filter((a) => a.id === item.id)
            );
          }
          console.log(item.id);
        } else if (type === 2) {
          this.selectList = this.selectList.filter((a) => a.id !== item.id);
        }
      }
      this.selectIds = this.selectList.map((a) => a.id);
    },

    submit (type) {
      if (type === 1) {
        this.$emit("chooseRole", type);
      } else if (type === 2) {
        this.$emit("chooseRole", type, this.selectList, this.selectIds);
      }
    },
  },
  watch: {},
};
</script>

<style lang="less" scoped>
.common-modal-container {
  display: flex;
  flex-direction: column;
  align-items: center;

  .title-container {
    width: 100%;
    height: 60px;
    border-bottom: 1px solid rgba(153, 153, 153, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;

    .title {
      font-size: 16px;
      color: #1a1a1a;
      font-weight: 500;
    }
  }
}
</style>




  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值