element-ui开发问题记录(二)

项目需求做一个和element中穿梭框一样的效果,但是要求多家一个功能,就是右边的数据要实现拖动排序的效果;没办法,不能用element现成的组件,只能自己封装;代码

<template>
  <div class="customItems">
    <div class="customList">
      <p class="title"><el-checkbox v-model="leftAll" @change="checkAll($event,left,'left')">左边列表</el-checkbox></p>
      <div class="checkboxList">
        <el-checkbox class="checkbox" @change="check('left')" v-model="item.checked" v-for="item in left" :key="item.id">{{item.name}}</el-checkbox>
      </div>
    </div>
    <div class="center">
      <el-button class="btn" size="mini" :disabled="!toRightFlag" @click="toRight" icon="el-icon-d-arrow-right"></el-button>
      <el-button class="btn" size="mini" :disabled="!toLeftFlag" @click="toLeft" icon="el-icon-d-arrow-left"></el-button>
    </div>
    <div class="checkedList">
      <p class="title"><el-checkbox v-model="rightAll"  @change="checkAll($event,right,'right')">已选择</el-checkbox><el-button class="sort" type="text" v-show="right.length>1" @click="sort">{{sortFlag?'保存':'排序'}}</el-button></p>
      <div class="checkboxList">
        <el-checkbox class="checkbox" @change="check('right')" v-model="item.checked" v-for="item in right" v-show="!sortFlag" :key="item.id">{{item.name}}</el-checkbox>
        <p :class="{checkbox:true, dragBox:true,active:active===item.id}" :style="{top:top+'px'}" @mousedown="moveStart($event,item.id,index)" v-for="item,index in right" v-show="sortFlag">{{item.name}}</p>
      </div>
    </div>
  </div>
</template>

<script>
    export default {
        data(){
            return {
              left:[],
              right:[],
              leftAll:false,
              rightAll:false,
              toLeftFlag:false,
              toRightFlag:false,
              sortFlag:false,
              active:"",
              x:0,
              y:0,
              l:0,
              top:0
            }
        },
        computed : {},
        methods : {
        //数据初始化
          dataInit(list){
            for(let i=0,len=this.left.length; i<len; i++){
                if(list.indexOf(this.left[i].id)!==-1){
                  this.right.push(JSON.parse(JSON.stringify(this.left[i])));
                  this.left.splice(i,1);
                  i--;
                  len--;
                }
            }
          },
          //两边的全选事件
          checkAll(val,arr,key){
            arr.forEach(e=>{
              e.checked=val;
            });
            this[key]=JSON.parse(JSON.stringify(this[key]));
            this.check(key)
          },
          //单选事件
          check(key){
            for(let i=0,len=this[key].length; i<len; i++){
                if(this[key][i].checked){
                    key==="left"?this.toRightFlag=true:this.toLeftFlag=true;
                    return;
                }
            }
            key==="left"?this.toRightFlag=false:this.toLeftFlag=false;
          },
          //移动选中项到右边
          toRight(){
            for(let i=0,len=this.left.length; i<len; i++){
              if(this.left[i].checked){
                this.left[i].checked=false;
                this.right.push(JSON.parse(JSON.stringify(this.left[i])));
                this.left.splice(i,1);
                i--;
                len=this.left.length
              }
            }
            this.toRightFlag=this.leftAll=false;
            this.change();
          },
            //移动选中项到左边
          toLeft(){
            for(let i=0,len=this.right.length; i<len; i++){
              if(this.right[i].checked){
                this.right[i].checked=false;
                this.left.push(JSON.parse(JSON.stringify(this.right[i])));
                this.right.splice(i,1);
                i--;
                len=this.right.length
              }
            }
            this.toLeftFlag=this.rightAll=false;
            this.change();
          },
          //右边数据发生变化时,处理数据格式,同时出发change事件;里面的逻辑可以自己编辑
          change(){
            let res=[];
            this.right.forEach(e=>{
              res.push(e.id)
            });
            this.$emit("change",res)
          },
          //排序按钮和保存按钮点击事件
          sort(){
            this.sortFlag=!this.sortFlag;
            if(!this.sortFlag){
                this.change();
            }
          },
          //开始拖动
          moveStart(e,id,index){
            this.x=e.clientX;
            this.y=e.clientY;
            this.index=index;
            this.active=id;
            document.addEventListener("mousemove",this.moveing,false);
            document.addEventListener("mouseup",this.moveEnd,false);
          },
          //拖动中
          moveing(e){
            this.l=e.clientX-this.x;
            this.top=e.clientY-this.y;
            if(this.top>0){//向下
              if(this.index<this.right.length-1){
                if(this.top>=15){
                  this.right[this.index+1]=this.right.splice(this.index,1,this.right[this.index+1])[0];
                  this.index+=1;
                  this.y+=30;
                  this.top-=30;
                }
              }
            }else {//向上
              if(this.index>0){
                if(this.top<=-15){
                  this.right[this.index-1]=this.right.splice(this.index,1,this.right[this.index-1])[0];
                  this.index-=1;
                  this.y-=30;
                  this.top +=30;
                }
              }
            }
          },
          //拖动结束
          moveEnd(e){
            document.removeEventListener("mousemove",this.moveing);//移除鼠标移动事件
            document.removeEventListener("mouseup",this.moveEnd);//移除事件
            this.l=this.top=0;
            this.active="";
            this.index=0;
          }
        },
        mounted(){
          this.left=this.$attrs.data
        }
    }
</script>

<style scoped>
    .customItems{
        display:flex;
    }
  .customList,.checkedList{
    border: 1px solid #ebeef5;
    border-radius: 4px;
    overflow: hidden;
    background: #fff;
    display: inline-block;
    vertical-align: middle;
    width: 240px;
    max-height: 100%;
    box-sizing: border-box;
    position: relative;
  }
  .customList{

  }
  .title{
    height: 40px;
    line-height: 40px;
    background: #f5f7fa;
    margin: 0;
    padding-left: 15px;
    border-bottom: 1px solid #ebeef5;
    box-sizing: border-box;
    color: #000;
  }
    .checkboxList{
      margin: 0;
      padding: 6px 0;
      list-style: none;
      height: 246px;
      overflow: auto;
      box-sizing: border-box;
    }
  .checkbox{
    height: 30px;
    line-height: 30px;
    padding-left: 15px;
    display: block;
    margin:0;
  }
  .sort{
    float:right;
    margin-right:30px;
  }
  .dragBox{
    cursor:pointer;
    -webkit-user-select:none;
    -moz-user-select:none;
    -ms-user-select:none;
    user-select:none;
  }
    .dragBox.active{
      position:relative;
      background-color:rgba(0,0,0,.3);
    }
  .center{
    width:80px;
    display:flex;
    flex-direction:column;
    justify-content:center;
    align-items:center;
  }
    .center .btn{
      padding:0;
      margin:10px;
      width:30px;
      height:30px;
    }
</style>

组件引用

<Transfer ref="transfer " :data="data" @change="change"></Transfer>

data是供选择的数组数据;
change是右边的数据发生变化是的回调事件;方便修改表单中绑定的值,返回参数为右边的数据
如果有初始数据,需要调用组件的dataInit方法进行数据初始化

this.$refs.transfer.dataInit(list)//list传入初始数据

基本能实现需求穿梭框加排序的需求

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Element UI的源码包含了许多文件和文件夹。其中一些主要的文件和文件夹包括: 1. .travis.yml:这是持续集成(CI)的配置文件,用于在代码提交时执行相应的脚本。 2. CHANGELOG:这是更新日志文件,记录Element UI的不同版本的更新内容。 3. components.json:这是配置文件,标注了组件的文件路径,方便在webpack打包时获取组件的文件路径。 4. element_logo.svg:这是Element UI的图标文件,使用了svg格式,使用svg文件可以减小图片大小。 5. FAQ.md:这是Element UI开发者对常见问题的解答。 6. LICENSE:这是开源许可证文件,Element UI使用的是MIT协议,使用Element UI进行开发开发者需要注意该文件。 7. Makefile:这是一个Makefile文件,定义了一系列规则,用于指定文件变异操作,通常用于工程化编译。 除了这些文件外,还有一些文件夹也非常重要: 1. .github:这个文件夹存放了贡献指南以及issue和PR模板,是一个成熟的开源项目必备的文件夹。 2. build:这个文件夹存放了打包工具的配置文件。 3. examples:这个文件夹存放了Element UI组件的示例代码。 4. packages:这个文件夹存放了组件的源码,也是源码分析的主要目标。 5. src:这个文件夹存放了入口文件以及各种辅助文件。 6. test:这个文件夹存放了单元测试文件,合格的单元测试也是一个成熟的开源项目必备的。 7. types:这个文件夹存放了声明文件,方便在引入使用TypeScript编写的项目中使用,需要在package.json中指定typing字段的值为声明的入口文件。 以上是Element UI源码的一些主要文件和文件夹。这些文件和文件夹组成了Element UI的代码库,开发者可以通过研究这些源码来深入理解Element UI的实现原理和架构。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [ElementUI 源码简析——源码结构篇](https://blog.csdn.net/qq_33583069/article/details/108100003)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值