[Vuejs]-Is it impossible to update data without update a component in Vue.js?

0👍

Below is one simple demo on the implemention of drag/drop by Vue.

  1. Create one watch, it will watch this.dragedItem. if changed, it will re-calculate the styles which apply to the dragItems.

  2. When drag start, get current dragging item (dragedItem=current item).

  3. When drag end, reset dragging item (dragedItem={}),

  4. When drop, remove item from dragItems, then push to dropItems.

In above steps, we just need to change the data, then Vue will auto render.

You can check HTML Drag And Drop API for more details.

For the transition effects, you can check Vue Guide: Enter/Leave Transition and Vue Guide: State Transtion.

app = new Vue({
  el: "#app",
  data: {
    dragItems: ['A', 'B', 'C', 'D'],
    dragedItem: {},
    dropItems: [],
    styles: {},
    defaultStyle: {'opacity': '', 'background-color': 'yellow'}
  },
  watch: {
    dragedItem: function () {
      this.styles = this.dragItems.reduce((pre, cur) => {
        pre[cur] = cur === this.dragedItem.item ? {'opacity': 0.5, 'background-color': 'blue'} : {'opacity': '', 'background-color': 'yellow'}
        return pre
      }, {})
    }
  },
  methods: {
    onDragStart: function (ev, item, index) {
      ev.dataTransfer.setData('text/plain',null)
      this.dragedItem = {item, index}
    },
    onDragEnd: function (ev) {
      this.dragedItem = {}
    },
    onDrop: function (ev) {
      this.dropItems.push(this.dragedItem.item)
      this.dragItems.splice(this.dragedItem.index, 1)
    }
  }
})
.dragzone {
  display:flex;
  flex-direction: row;
}

.dragger {
  width: 30px;
  height: 30px;
  text-align: center;
  border: 1px solid gray;
}

.dropzone {
  width: 200px;
  height: 30px;
  background: green;
  padding: 10px;
  display:flex;
  flex-direction: row;
}
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<div id="app">
  <div class="dragzone">
    <div class="dragger" draggable="true" 
    v-for="(item, index) in dragItems" :key="index"
    :style="styles[item] ? styles[item] : defaultStyle"
    @dragstart="onDragStart($event, item, index)" 
    @dragend="onDragEnd($event)"
    >
      {{item}}
    </div>
  </div>
  <div class="dropzone" @drop.prevent="onDrop($event)"
    @dragover.prevent=""
  >
    <div class="dragger" style="background-color:yellow" draggable="true" v-for="(item, index) in dropItems" :key="index">
      {{item}}
    </div>
  </div>
</div>
👤Sphinx

Leave a comment