Vue

HTML

<div id="app">
  <button @click="changePosition">
    Change Position Of items
  </button>
  <list @item-position-changed="changeList" :list="list">
    <template slot-scope={list}>
      <list-item ref="item" v-for="item in list" :id="item.id" :key="item.id" :name="item.name">
      </list-item>
    </template>
  </list>
</div>

CSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}

Vue

Vue.component('list', {
	template: '<div> changePositionQueue: {{changePositionQueue}} <br><br> <slot v-bind:list="sortedList"></slot></div>',
  props: ['list'],
  data() {
  	return {
    	changePositionQueue: [],
      positionChangingProcess: false
    }
  },
 	watch: {
  	changePositionQueue(val) {
    	if (val) {
      	if (!this.positionChangingProcess)
      		this.startChangingPosition()
      }
    }
  },
  computed: {
  	sortedList() {
    	return this.list.sort( (item1, item2) => {return item1.position - item2.position} )
    }
  },
  created() {
  	eventBus.$on('changePosition', this.pushToQueue);
  },
  methods: {
    startChangingPosition() {
    	this.positionChangingProcess = true;
    	if (this.changePositionQueue.length === 0) {
      	this.positionChangingProcess = false;
      	return;
      }
      
      const item = this.changePositionQueue[0];
      
      this.changePositionOfItem(item.id, item.position).then( ({list}) => {
      	this.$emit('item-position-changed', {list: list, callback: () => {
        	  console.log('taking from queue')
          	this.changePositionQueue.shift();
          	this.startChangingPosition();
        }})
      })
    },
  	pushToQueue(id, position) {
    	console.log('pushing to queue')
    	this.changePositionQueue.push({id: id, position: position});
    },
    changePositionOfItem(id, position) {
    	return new Promise((resolve) => {
      	let newList = JSON.parse(JSON.stringify(this.list));
        const index = newList.findIndex( item => item.id === id);
        newList[index].position = position;
        
        resolve({list: newList})
      })
    }
  }
})

Vue.component('list-item', {
	template: '<div>{{name}}</div>',
  props: ['id', 'name'],
  methods: {
  	changePosition() {
    	eventBus.$emit('changePosition', this.id, Math.floor(Math.random() * 6) + 1 );
    }
  }
})

const eventBus = new Vue();

new Vue({
  el: "#app",
  data: {
    list: [
      { id: 1, name: "first", position: 3 },
     ...