项目里的一个小需求,需要在穿梭框的右侧增加一个排序功能,坑很多,比如确实不太理解为什么iView的穿梭框组件里的foot里居然不区分左右,还有更改序列的时候必须还要重新读取一遍整体数据,就很神奇。

实现DEMO如下:

<template>
  <div>
    <Transfer class="rightFooter" :data="testData" :target-keys="testTargetKeys" @on-selected-change="testSelect" @on-change="testTransferChange">
      <div :style="{float: 'right', margin: '5px'}">
        <!-- 增加排序按钮 -->
        <div class="footer-btn">
          <Button size="small" @click="testSort(1)">上移</Button>
          <Button size="small" @click="testSort(2)">下移</Button>
        </div>
      </div>
    </Transfer>
  </div>
</template>

JS方法列表,需要的地方我都加上注释了,应该能看得懂。

<script>
export default {
  data () {
    return {
      testData: [], // 穿梭框数据
      testTargetKeys: [], // 穿梭框已选数据
      testSelectKey: [] // 目前勾选的数据
    }
  },
  mounted: function () {
    this.testInit()
  },
  methods: {
    // 数据加载
    testInit: function () {
      // 获取数据
      this.testData = [{
        key: 1,
        label: 'Test1',
        description: '',
        disabled: false
      }, {
        key: 2,
        label: 'Test2',
        description: '',
        disabled: false
      }, {
        key: 3,
        label: 'Test3',
        description: '',
        disabled: false
      }, {
        key: 4,
        label: 'Test4',
        description: '',
        disabled: false
      }, {
        key: 5,
        label: 'Test5',
        description: '',
        disabled: false
      }]
    },
    // 穿梭框左侧到右侧的方法
    testTransferChange: function (newTargetKeys, direction, moveKeys) {
      this.testTargetKeys = newTargetKeys
    },
    // 获取当前选中的值
    testSelect: function (sourceSelectedKeys, targetSelectedKeys) {
      this.testSelectKey = targetSelectedKeys
    },
    // 排序方法
    testSort: function (sortType) {
      // 判断当前选择的数据是否为1个
      if (this.testSelectKey.length > 1) {
        this.$Message.warning('排序商品只能为1个')
      } else {
        // 上移
        if (sortType === 1) {
          let arrIndex = this.testTargetKeys.indexOf(this.testSelectKey[0])
          if (arrIndex === 0) {
            this.$Message.warning('已经是顶部了')
          } else {
            // 交换数组序列
            let up = this.testTargetKeys[arrIndex - 1]
            let now = this.testTargetKeys[arrIndex]
            this.testTargetKeys[arrIndex] = up
            this.testTargetKeys[arrIndex - 1] = now
            // 这里需要重新执行一遍加载数据的方法, 否则排序不生效
            this.testInit()
          }
        }
        // 下移
        if (sortType === 2) {
          let arrIndex = this.testTargetKeys.indexOf(this.testSelectKey[0])
          if (arrIndex === this.testTargetKeys.length - 1) {
            this.$Message.warning('已经是底部了')
          } else {
            // 交换数组序列
            let up = this.testTargetKeys[arrIndex + 1]
            let now = this.testTargetKeys[arrIndex]
            this.testTargetKeys[arrIndex] = up
            this.testTargetKeys[arrIndex + 1] = now
            // 这里需要重新执行一遍加载数据的方法, 否则排序不生效
            this.testInit()
          }
        }
      }
    }
  }
}
</script>

这个时候你就会发现他左边居然还有一个[上移]和[下移],更神奇的是组件内部居然没有区分,也没给提供方法来区分。更好玩的是连样式居然也一模一样的。所以没办法只能用css的伪类来消除左侧的框,我这里用的是Sass,代码如下:

.rightFooter{
  .ivu-transfer-list:first-child{
    .ivu-transfer-list-footer{
      .footer-btn{
          height: 23px;
          Button{
              display: none;
          }
      }
    }
  }
}

补充提示,这段代码放在下面也没用,最好引用到外部css里才行。