首页 > 其他分享 >ant design vue a-transfer使用vuedraggable穿梭框拖动效果

ant design vue a-transfer使用vuedraggable穿梭框拖动效果

时间:2024-02-22 15:22:41浏览次数:24  
标签:vue return title transfer dataSourceFields ant key targetKeys const

npm install vuedraggable --save

 vue

<template>
  <a-form layout="vertical">
    <a-form-item
        label="模板"
    >
    
    <a-transfer
        show-search
        :data-source="tableFieldSource"
        :target-keys="targetKeys"
        :list-style="{
        width: 'calc(50% - 30px)',
        height: '300px' }"
        :titles="['未导出的字段','导出的字段']"
        :render="item => item.title || ''"
        :filter-option="(str, {description})=>{
        return description.indexOf(str)>-1 }"
        @change="handleFieldKeyChange"
    >
      <template
          slot="children"
          slot-scope="{
          props: { direction, filteredItems, selectedKeys, disabled: listDisabled },
          on: { itemSelectAll, itemSelect },
        }"
      >
        <div class="container">
          <draggable class="list-group" :list="filteredItems" group="people"
                     dragClass="list-group-select"
                     @update="draggableUpdate($event,direction)" @remove="draggableRemove($event,direction)"
                     @add="draggableAdd($event,direction,filteredItems)">
            <div
                class="list-group-item"
                v-for="(element, index) in filteredItems"
                :key="element.key"
            >
            <span :style="{ pointerEvents: listDisabled ? 'none' : null }">
              <a-checkbox :checked="checkTag(element,selectedKeys)"
                          v-model="element.check"
                          @change="tableFieldSourceChange(element.check,element.key,selectedKeys)"/>
              <span class="list-group-item-span">{{ element.title }}</span>
             <a-icon
                 v-if="direction ==='right' && index!==0"
                 type="vertical-align-top"
                 style="color: #666;float: right;margin-right: 15px"
                 title="置顶"
                 @click="()=>{draggableTop(index,direction)}"
             />
            </span>
            </div>
          </draggable>
        </div>
      </template>
    </a-transfer>


  </a-form>
</template>

<script>
import {RESULT_SUCCESS_CODE} from "@/utils/gobalConstants";
import draggable from 'vuedraggable'

export default {
  name: 'ExportView',
  components: {
    draggable
  },
  props: {
    fields: {
      type: Array, default() {
        return []
      }
    },
    viewList: {
      type: Array,
      default() {
        return []
      }
    },
    moduleName: {
      type: String,
      default: ""
    }
  },
  data() {
    return {
      targetKeys: [],
      tableFieldSource: [],
      conditionFields: [], //过滤字段
      filterListHeight: window.innerHeight - 760, // 过滤条件区域高度
      viewName: '',
      viewId: null,
      dataSourceFields: this.fields,
      cutExportBtn: true,
      delExist: false,
      optionDataSource: [],
    }
  },
  computed: {},
  watch: {},
  mounted() {
    this.init();
  },
  methods: {
    async init() {
      this.tableFieldSource = this.tableFieldSourceGet();
      this.customExportChange();
      await this.fetchExportViewList();
    },
    tableFieldSourceGet() {
      const {dataSourceFields} = this
      if (dataSourceFields && dataSourceFields.length) {
        return dataSourceFields.map(i => {
          return {
            key: i.field,
            title: i.title,
            description: `${i.field}${i.title}`,
          }
        })
      }
      return []
    },
    refreshValue() {
      this.targetKeys = [];
    },
    filterOption(inputValue, option) {
      return option.description.indexOf(inputValue) > -1;
    },
    handleChange(targetKeys, direction, moveKeys) {
      this.targetKeys = targetKeys;
    },
    handleSearch(dir, value) {
    },
    // 筛选值变化
    handleFieldKeyChange(targetKeys) {
      this.targetKeys = targetKeys;
    },
    //自定义导出
    customExportChange() {
      if (this.cutExportBtn) {
        const {dataSourceFields} = this;
        this.targetKeys = dataSourceFields.filter(m => m.visible == true).map(i => {
          return i.field
        });
      } else {
        this.targetKeys = [];
      }
    },
    tableFieldSourceChange(e, key, selectedKeys) {
      if (e) {
        selectedKeys.push(key);
      } else {
        selectedKeys.splice(key, 1);
      }
    },
    checkTag(el, keyArr) {
      el.check = keyArr.includes(el.key);
      return keyArr.includes(el.key)
    },
    draggableUpdate(e, t) {
      if (t === "left") {
        const l = this.targetKeys.length;
        this.swapArrayElements(this.tableFieldSource, e.oldIndex + l, e.newIndex + l);
      } else {
        this.swapArrayElements(this.targetKeys, e.oldIndex, e.newIndex);
      }
    },
    //移动到另外的元素
    draggableRemove(e, t) {
      if (t === "right") {
        this.targetKeys.splice(e.oldIndex, 1);
      }
    },
    draggableAdd(e, t) {
      const targetKeys = _.cloneDeep(this.targetKeys);
      if (t === "right") {
        const element = this.removeRightArr()[e.oldIndex];
        targetKeys.push(element.key);
        this.swapArrayElements(targetKeys, targetKeys.length - 1, e.newIndex);

        this.targetKeys = targetKeys;
      }
    },
    draggableTop(index) {
      this.swapArrayElements(this.targetKeys, index, 0)
    },
    swapArrayElements(arr, indexA, indexB) {
      arr.splice(indexB, 0, arr.splice(indexA, 1)[0]);
    },
    removeRightArr() {
      const source = _.cloneDeep(this.tableFieldSource);
      const targetKeys = this.targetKeys;
      for (let targetKey of targetKeys) {
        const number = source.findIndex(m => m.key === targetKey);
        if (number !== -1) {
          source.splice(number, 1);
        }
      }
      return source;
    }
  }
}
</script>

<style lang="less" scoped>
.ghost {
  opacity: 0.5;
  background: #c8ebfb;
}

.list-group {
  display: flex;
  flex-direction: column;
  padding-left: 0;
  margin-bottom: 0;
  width: 300px;

  .list-group-item {
    cursor: move;
    position: relative;
    display: block;
    background-color: #fff;
    line-height: 24px
  }

  .list-group-item-span {
    padding-left: 12px
  }
}

.list-group-select {

}

.container {
  height: 200px;
  overflow: auto;
  overflow-x: hidden;
}
</style>

  

 

标签:vue,return,title,transfer,dataSourceFields,ant,key,targetKeys,const
From: https://www.cnblogs.com/keenonwt/p/18027421

相关文章

  • Vue学习笔记9--Object.defineProperty()
    Object.defineProperty()语法说明Object.defineProperty()的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性obj需要定义属性的当前对象Object.defineProperty(obj,prop,desc)==》obj需要定义属性的当前对象prop当前需要定义的属性名desc属性描述......
  • 使用Vue实现数据的模糊匹配
    采用方法v-model自定义属性computedv-for实现思路首先使用v-model获取用户输入的关键字;采用Vue中的自定义属性,返回符合条件的数据;最后使用v-for指令,展示结果。实例展示<divid="app"><inputtype="text"v-model="keyword"placeholder="请输入年龄">......
  • 使用delete和Vue.delete删除数组元素的区别
    JavaScript中的delete运算符可以删除对象的属性,但是它不适用于数组。如果你试图使用delete运算符删除数组中的元素,你会发现该元素的值变为undefined,而数组的长度并没有改变。Vue.js提供了一个名为Vue.delete的方法,它可以帮助我们在删除数组元素时触发响应式更新。与原生JavaScrip......
  • Vue中的mixins和extends是什么,有什么联系和区别?
    在Vue.js中,mixin和extends都是用来处理组件复用和组件之间共享逻辑的方式,但它们有不同的特点和应用场景。Mixin(混入)Mixin是一种可以包含可复用Vue组件选项的对象。通过使用mixin,我们可以将一些公共的选项和逻辑提取出来,然后混入到多个组件中。这样做可以有效地避免重复......
  • Vue学习笔记8--MVVM
     总结:MVVMM:模型Model,对应data种的数据V:视图View,模版     VM:视图模型ViewModel,Vue实例对象观察发现:data种所有的属性,最后都出现在vm身上。vm身上所有的属性及Vue原型上所有属性,在Vue模版种都可以直接使用。示例如下所示:<!DOCTYPEhtml><htmllan......
  • vue中filters和computed有什么区别
    在Vue.js中,filters和computed都是用来处理模板中的数据的方式,但它们有不同的应用场景和使用方式。filters是一种简单的函数,可以在模板中对数据进行格式化。它们可以用于在显示数据之前对其进行处理,例如对日期格式进行转换、将文本转换为大写或小写字母等。filters没有缓存......
  • Vue学习笔记7--el和data的两种写法
    方式一:eldata  //方式一:eldata//constone=newVue({//el:'#root',//data:{//name:'vue',//mydata://{//oneAtt:'我是一个嵌套对象的属性哦',//......
  • vue中花括号表达式,string类型除以number类型返回NaN值
    bug:数据为0时,el-progress的color还是有颜色,应该是没有颜色的第一步解决:设置动态color<el-progress:show-text="false":percentage="(oilCarOccupationNum/totalNum)*100":color="oilCarOccupationNum?'......
  • Vue学习笔记6--数据绑定
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Vue数据绑定</title>......
  • vue3 ts用正则表达式校验两位小数和校验整数的方法
    <el-col:span="12"><el-form-itemlabel="贷款金额"prop="loanAmount"><el-input-numberv-model="props.loanAmount":min="0"@change="checkIntegerNumber('loanAmount')"controls......