Vue中使用dragstart和drop實現拖拽



這是我以前項目上做,后來不需要了,放到博客里保存起來,沒事看看
首先想要在dom元素上使用拖拽事件,你需要在標簽上添加draggable="true",像下面這樣:

這樣才可以使用拖拽事件,要不然是無效的呦

下面是HTML5的拖拽事件

dragstart:開始拖元素觸發
dragenter:元素拖進可drop元素(綁定drop事件的元素)時觸發
dragover:當元素拖動到drop元素上時觸發
drop:當元素放下到drop元素觸發
dragleave :當元素離開drop元素時觸發
drag:每次元素被拖動時會觸發
dragend:放開拖動元素時觸發

完成一次拖放的事件過程是: dragstart –> dragenter –> dragover –> drop –> dragend

瀏覽器支持

Internet Explorer 9、Firefox、Opera 12、Chrome 以及 Safari 5 支持拖放。

<template>
    <div class="StaffManagement">
      <div class="stationManagement">
        <div class="stationManagement-tooltip">拖拽人員到相應班別,進行人員綁定</div>
        <FitDiv :text="'崗位管理'">
          <template>
            <div class="stations">
              <div class="stations-one">
                <div class="stations-one_station"><span>工站</span></div>
                <div class="stations-one_day">白班</div>
                <div class="stations-one_night">夜班</div>
              </div>
              <div class="stations-one" v-for="(item, index) of staffData" :key="index">
                <div class="stations-one_station"><span>{{item.station}}</span></div>
                <div class="stations-one_day" @drop="drop(item, 'dayStaff')" @dragover.prevent>
                  <div class="staffs-name">
                    <div style="display: inline-block;margin: 2px;" v-for="(day, _index) of item.dayStaff" :key="_index">{{day}}</div>
                  </div>
<!--                  <div class="addStaff">-->
<!--                    <span class="icon-alijiahao"></span>-->
<!--                  </div>-->
                </div>
              <div class="stations-one_night" @drop="drop(item, 'nightStaff')" @dragover.prevent>
                <div class="staffs-name">
                  <div style="display: inline-block;margin: 2px;" v-for="(night, _index) of item.nightStaff" :key="_index">{{night}}</div>
                </div>
<!--                <div class="addStaff">-->
<!--                  <span class="icon-alijiahao"></span>-->
<!--                </div>-->
              </div>
            </div>
          </div>
        </template>
      </FitDiv>
    </div>
    <div class="staffTable">
      <FitDiv :text="'人員列表'">
        <template>
          <div class="staffTable-table">
            <div v-for="(infos, index) of getPersons" :key="index" class="staffTable-table-tr">
              <div v-for="(info, _index) of infos" :key="_index" class="staffTable-table-tr-td"
                   :style="{backgroundColor: info.isBind?'red':'',color:info.isBind?'#123548':''}"
                   @mouseenter.stop="info.isBind ? mousePosition = `${index}-${_index}`:(void 0)"
                   @mouseleave.stop="info.isBind ? mousePosition = '':(void 0)"
                   @dragstart.stop="info.name ? dragStart({
                    event: $event,
                    line: index,
                    row: _index,
                    info: info
                  }):(void 0)" @dragover.prevent :draggable="(!!info.name && !info.isBind)">
                <span v-show="!(info.isBind && mousePosition === `${index}-${_index}`)">{{info.name}}</span>
                <Button @click.stop="unBind(`${index}-${_index}`),info.isBind = false" type="error" size="small" v-show="info.isBind && mousePosition === `${index}-${_index}`">解綁</Button>
              </div>
            </div>
          </div>
        </template>
      </FitDiv>
    </div>
  </div>
</template>

<script>
import { Button } from 'view-design';
export default {
  name: "StaffManagement",
  components: {
    Button
  },
  computed: {
    getPersons () {
      const persons = [];
      const lineNumber = 9;
      for (let i = 0,total = Math.ceil(this.personsInfo.length / lineNumber);i<total;++i) {
        if (i === (total - 1)) {
          const remainder = this.personsInfo.length % lineNumber;
          if (remainder) {
            persons.push(this.personsInfo.slice(i * lineNumber, (i + 1) * lineNumber).concat(new Array(lineNumber - remainder).fill({name: '', isBind: false})));
          }
        } else {
          persons.push(this.personsInfo.slice(i * lineNumber, (i + 1) * lineNumber));
        }
      }
      return persons;
    }
  },
  data () {
    return {
      // staffData:[
      //   {station: 'A',
      //   dayStaff: ['李飛飛', '趙宇'],
      //   nightStaff: ['陳瑞', '郭將月']},
      //   {station: 'B',
      //     dayStaff: ['李雪倩', '段銳旗'],
      //     nightStaff: ['肖戰', '胡歌']},
      //   {station: 'C',
      //     dayStaff: ['任天', '黃琪'],
      //     nightStaff: ['王星星', '王峰']},
      //   {station: 'D',
      //     dayStaff: ['陳玉', '蔡茂'],
      //     nightStaff: ['李國強', '劉智']},
      //   {station: 'E',
      //     dayStaff: ['董峰', '馮琦'],
      //     nightStaff: ['林平', '吳迪']},
      // ],
      staffData:[
        {station: 'A',
        dayStaff: [],
        nightStaff: []},
        {station: 'B',
          dayStaff: [],
          nightStaff: []},
        {station: 'C',
          dayStaff: [],
          nightStaff: []},
        {station: 'D',
          dayStaff: [],
          nightStaff: []},
        {station: 'E',
          dayStaff: [],
          nightStaff: []},
      ],
      personsInfo: [{name:'李飛飛',isBind: false},{name:'林平',isBind: false}, {name:'吳迪',isBind: false},{name:'董峰',isBind: false},
       {name:'馮琦',isBind: false},{name:'李國強',isBind: false}, {name:'劉智',isBind: false},{name:'陳玉',isBind: false},
       {name:'蔡茂',isBind: false},{name:'王星星',isBind: false}, {name:'王峰',isBind: false},{name:'任天',isBind: false},
       {name:'段銳旗',isBind: false},{name:'肖戰',isBind: false}, {name:'胡歌',isBind: false},{name:'李雪倩',isBind: false},
       {name:'陳瑞',isBind: false},{name:'郭將月',isBind: false}, {name:'趙宇',isBind: false}
      ],
      // 通過hash存儲綁定的值,方便解綁使用
      bindData: {},
      tempStaff: null,
      mousePosition: ''
    }
  },
  created () {
    // new Array(30).fill(1).forEach(() => {
    //   this.personsInfo.push({name:'666',isBind: false});
    // })
  },
  methods: {
    dragStart ({event,line,row,info}) {
        // 火狐進行拖拽事件必須攜帶數據,所以沒有數據也要添加數據
      if (this.$store.state.browerInfo === 'firefox') {
        event.dataTransfer.setData('text', null);
      }
          // IE拖拽不能添加數據,可以在拖拽時把數據放到全局變量進行操作
      this.tempStaff = {info,line,row};
    },
    drop (data, type) {
      if (!this.tempStaff.info.isBind) {
        this.tempStaff.info.isBind = true;
        this.bindData[`${this.tempStaff.line}-${this.tempStaff.row}`] =
          [data.station,type,data[type].push(this.tempStaff.info.name) - 1];
      }
    },
    unBind (key) {
       this.staffData.find(e => this.bindData[key][0] === e.station)[this.bindData[key][1]].splice(this.bindData[key][2], 1);
    }
  }
}
</script>

<style lang="scss" scoped>
@import "../styles/_colors.scss";
.StaffManagement {
  height: 500px;
  width: calc(100% - 20px);
  margin: 5px 10px;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  .stationManagement {
    position: relative;
    background-color: #001529;
    height: 48%;
    width: 100%;
    &-tooltip {
      position: absolute;
      top: 1%;
      right: 2%;
    }
    .stations {
      height: calc(100% - 20px);
      margin: 10px 10px;
      vertical-align: middle;
      &-one {
        vertical-align: middle;
        height: 100%;
        width: 120px;
        display: inline-block;
        margin: 0 1%;
        @mixin stationStyle {
          display: flex;
          justify-content: center;
          align-items: center;
          height: calc(100% / 3);
          overflow: auto;
          flex-wrap:wrap;
        }
          .staffs-name {
            width: 60%;
          }
          .addStaff {
          }
        &_station {
          @include stationStyle();
          background-color: $tableOdd;
        }
        &_day {
          @include stationStyle();
          background-color: $tableEven;
          border-bottom: 0.5px solid $modalHeader;
        }
        &_night {
          @include stationStyle();
          background-color: $tableEven;
          border-top: 0.5px solid $modalHeader;
        }
      }
    }
  }
  .staffTable {
    height: 48%;
    width: 100%;
    background-color: #001529;
    &-table {
      height: calc(100% - 20px);
      width: 96%;
      margin: 10px auto;
      &-tr {
        height: 30px;
        display: flex;
        justify-content: space-around;
        &:nth-child(odd) {
          background-color: $tableOdd;
        }
        &:nth-child(even) {
          background-color: $tableEven;
        }
        &-td {
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
          line-height: 30px;
          width: calc(100% / 10);
          text-align: center;
        }
      }
    }
  }
}
</style>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM