在element穿梭框中使用左侧搜索框触发远程搜索的方法

1,857 阅读1分钟

`

<template>
  <el-drawer title="使用用户设置" :visible.sync="visible" size="1000px" :before-close="handleClose" :wrapperClosable="false">
    <el-transfer
      ref="ofsTransfer"
      v-loading="treeLoading"
      filterable
      :titles="['用户列表', '已选用户']"
      filter-placeholder="请输入用户名/项目名称"
      v-model="value"
      :data="leftData"
      :props="{
        key: 'id',
        label: 'name'
      }"
      :filter-method="filterMethod"
    ></el-transfer>
    <template slot="footer">
      <el-button @click="handleClose">取消</el-button>
      <el-button type="primary" @click="saveFn">保存</el-button>
    </template>
  </el-drawer>
</template>

<script>

export default {
  data() {
    return {
      visible: false,
      // 源数据(不可修改)
      allData: [],
      // 穿梭框元数据(读取源数据)
      leftData: [],
      // 选中的id数组
      value: [],
      treeLoading: false,
      notTimeOut: [],
      filterKey: '',
      searchKey: ''
    }
  },
  methods: {
    async popup(id) {
      await this.getUsersFn(id)
      this.getList('')
      this.visible = true
    },
    // 获取已经选择的用户
    async getUsersFn() {
      // API请求
      await getUsers(请求入参).then(({ data }) => {
        // data.users是数组{id,name,project_name}
        data.users.forEach(item => {
          this.value.push(item.id)
          this.allData.push({ name: `${item.name}${item.project_name ? '(' + item.project_name + ')' : ''}`, id: item.id })
        })
        this.leftData = JSON.parse(JSON.stringify(this.allData))
      })
    },
    // 获取未选择的用户
    getList(key) {
      this.searchKey = key
      this.treeLoading = true
      getUnSetUsers({ key }).then(({ data }) => {
        data.forEach(item => {
          if (!this.allData.find(it => it.id === item.id)) {
            this.allData.unshift({ id: item.id, name: `${item.name}${item.project_name ? '(' + item.project_name + ')' : ''}` })
          }
        })
        this.treeLoading = false
        if (data && data[0]) {
          this.leftData = JSON.parse(JSON.stringify(that.allData))
        }
      })
    },
    filterMethod(key, item) {
      // console.log(key, item)
      if (key) {
        // 判断穿梭框两边js运行
        // 若选中的id不在当前item的返回内,则运行左边穿梭框的方法
        if (!this.value.find(it => it === item.id)) {
          // filterKey判断当前搜索的值是否有变化
          if (this.filterKey !== key) {
            this.notTimeOut = []
            this.filterKey = key
          }
          if (item.name.indexOf(key) > -1) {
            this.notTimeOut.push(true)
            return true
          } else {
            this.notTimeOut.push(false)
          }
          // notTimeOut记录循环是否结束,防止多次请求远程
          // 若notTimeOut中没有true值,则表示搜索的数据不在源数据中,则要请求远程
          if (
            this.notTimeOut.length + this.value.length === this.allData.length &&
            !this.notTimeOut.find(item => item === true)
          ) {
            // 若进来,则清空notTimeOut,防止再次请求远程
            this.notTimeOut = []
            clearTimeout(this.timeOut)
            this.timeOut = setTimeout(() => {
              // searchKey判断是否已经请求过远程,因filterMethod方法是计算属性,会使请求重复,则需要searchKey判断
              if (this.searchKey !== key) {
                this.getList(key)
              }
            }, 1000)
          }
        } else {
          if (item.name.indexOf(key) > -1) {
            return true
          }
        }
      } else {
        return true
      }
    },
    saveFn() {},
    handleClose() {
      let that = this
      this.treeLoading = false
      this.leftData = []
      this.allData = []
      this.value = []
      this.notTimeOut = []
      this.filterKey = ''
      this.searchKey = ''
      this.$refs.ofsTransfer.clearQuery('left')
      this.$refs.ofsTransfer.clearQuery('right')
      this.visible = false
    }
  }
}
</script>

<style lang="scss"></style>

`