问题描述:

element-ui 穿梭框无分页功能,正好有几个功能要用到穿梭框,介于数据量太大,需要分页,vue新手入坑,记录一下


需要用到:父页面index.vue及子穿梭框组件school.vue,点击’心仪学校‘ 时出现穿梭框,可条件搜索,可分页查询,选择确认后展示所选学校

图片预览

父级代码
   <el-form :rules="rules" :model="temp" label-position="right" label-width="80px">
	<el-form-item label="心仪学校" class="want-list" >
        <div class="radio-style" prop="intentSchoolIds">
          <el-input v-model="temp.intentSchoolIds" placeholder="心仪学校" style="width: 150px;" class="filter-item" @focus="dialogSchoolVisible = true"/>
        </div>
        <div class="addList">
          <el-tag v-for="tag in schoolInfoDTOList" :key="tag.id" :disable-transitions="false" closable @close="deleteSchool(tag)">{{ tag.schoolName }}</el-tag>
        </div>
      </el-form-item>
	</el-form>
	
	 <el-dialog :visible.sync="dialogSchoolVisible" title="心仪学校">
      <select-school @showSchoolSelected="showSchoolSelected" @clearSchoolSelected="clearSchoolSelected" />
    </el-dialog>
    
import SelectInstitute from '@/components/selectInstitute'
export default {
  name: 'Company',
  components: {
    'select-school': SelectSchool,
  },
  data() {
    return {
        dialogSchoolVisible: false,
        schoolInfoDTOList: []

    }
  }
  method: {
  // 响应子级事件,接受数据渲染
      showSchoolSelected(arr) {
          this.dialogSchoolVisible = false
          const schoolInfoDTOList = this.schoolInfoDTOList || []
          for (let i = 0; i < arr.length; i++) {
            let key = 0
            schoolInfoDTOList.forEach((val) => {
              if (val.id === arr[i].id) {
                key++
              }
            })
            if (key === 0) {
              this.schoolInfoDTOList.push(arr[i])
            }
      }
    },
     clearSchoolSelected() {
      this.dialogSchoolVisible = false
    }
  }
  
}
子组件SelectSchool代码
 <template>
  <div class="old-job-container">
    <el-transfer
      v-model="value4"
      :titles="['学校', '已选']"
      :button-texts="['到左边', '到右边']"
      :format="{
        noChecked: '${total}',
        hasChecked: '${checked}/${total}'
      }"
      :render-content="renderFunc"
      :data="jobList"
      style="text-align: left; display: inline-block"
      @change="handleChange">
      <span slot-scope="{ option }">{{ option.label }}</span>
      <div slot="left-footer">
        <el-input v-model="jobQuery.schoolName" placeholder="请输入学校名称" class="filter-item" @keyup.enter.native="handleFilterJob"/>
        <el-pagination
          slot="left-footer"
          :current-page="jobQuery.pageIndex"
          :page-size="jobQuery.pageSize"
          :total="totalJob"
          class="transfer-footer"
          size="small"
          background
          layout="total, prev, next"
          @size-change="handleJobSizeChange"
          @current-change="handleJobCurrentChange"/> </div>

      <el-button class="transfer-footer" size="small">操作</el-button>
    </el-transfer>

    <div slot="footer" class="post-footer">
      <el-button @click="clearJobSelected"> </el-button>
      <el-button type="primary" @click="showJobSelected"> </el-button>
    </div>
  </div>
</template>

<script>
import { querySchool } from '@/api/user/school'

export default {
  name: 'SelectSchool',
  data() {
    return {
     // 渲染列表格式
      renderFunc(h, option) {
        return <span> { option.label }</span>
      },
      jobQuery: {
        schoolName: null,
        pageIndex: 1,
        pageSize: 10
      },
      value4: [], //右侧选中id
      jobSelectedList: [],
      jobList: [],
      totalJob: null

    }
  },
  beforeMount() {
    this.showJobList()
  },
  methods: {
  /* 点击‘到左边’,‘到右边‘触发handleChange,穿梭框渲染格式{key:'',label:''},首先需要转换器得到所需格式,以备父级渲染,jobList为分页数据,jobSelectedList为已选中
数据,movedKeys表示操作的id数组,借助movedKeysjobList数组更新jobSelectedList */
    handleChange(value, direction, movedKeys) {
      const jobList = this.jobList.map((val, key) => {
        return {
          id: val.key,
          schoolName: val.label
        }
      })
      for (let i = 0; i < movedKeys.length; i++) {
        jobList.forEach((val) => {
          if (val.id === movedKeys[i]) {
            if (direction === 'right') {
              this.jobSelectedList.push(val)
            } else if (direction === 'left') {
              const jobSelectedList = this.jobSelectedList
              this.jobSelectedList = jobSelectedList.filter((ele) => {
                if (ele.id !== movedKeys[i]) {
                  return true
                }
              })
            }
          }
        })
      }
    },
    /* 分页查询列表 */
    showJobList() {
      querySchool(this.jobQuery).then((res) => {
        this.jobList = res.result.map((val, key) => {
          return {
            key: val.id,
            label: val.schoolName
          }
        })
        this.totalJob = res.pageInfo.totalCount
      })
    },
    clearJobSelected() {
      this.$emit('clearSchoolSelected')
      this.value4 = []
    },
    /* 确认选择触发父级事件,传入选择数据 */
    showJobSelected() {
      this.$emit('showSchoolSelected', this.jobSelectedList)
      this.value4 = []
    },
    // input模糊查询
    handleFilterJob() {
      this.jobQuery.pageIndex = 1
      this.showJobList()
    },
    // 分页
    handleJobSizeChange(val) {
      this.jobQuery.pageSize = val
      this.showJobList()
    },
    handleJobCurrentChange(val) {
      this.jobQuery.pageIndex = val
      this.showJobList()
    }
  }
}
</script>

<style  rel="stylesheet/scss" lang="scss">
  .post-footer{
    margin-top:20px;
    text-align: center;
  }
  .old-job-container{
    .el-transfer{
      width:90vw;
      padding-left:14vw
    }
    .el-transfer-panel .el-transfer-panel__footer{
      height:85px !important;
    }
    .el-transfer-panel{
      text-align: left;
    }
    .el-input__inner
    {
      height: 32px;
      border-radius: 20px;
      width: 90%;
    }
  }
</style>

凡心所向,素履所往