Vue

by Soviut

HTML

<div id="app">
  <div v-for="section, i in sections">
    <div class="actions">
      <button class="actions__button" @click="insertSection(i)">Insert Section</button>
    </div>

    <div class="section">
      <header class="section__header">
        <button @click="deleteSection(i)">Delete</button>
        <button @click="moveSectionUp(i)" :disabled="i === 0">Move Up</button>
        <button @click="moveSectionDown(i)" :disabled="i === sections.length - 1">Move Down</button>
      </header>
      
      <div class="section__body">
        {{ section.body }}
      </div>
    </div>
  </div>

  <div class="actions">
    <button class="actions__button" @click="addSection()">Add Section</button>
  </div>

</div>

CSS

body {
  background: #FFF;
  padding: 20px;
  font-family: arial, Helvetica, san-serif;
}

.section {
  margin-top: 10px;

  border: solid 1px #CCC;
}

.section__header {
  padding: 10px;
  
  border-bottom: solid 1px #CCC;
}

.section__body {
  padding: 10px;
}

.actions {
  margin-top: 10px;
}

.actions__button {
  display: block;
  width: 100%;
  padding: 10px;
  
  border: 0;
  border-radius: 4px;
  background: #336699;
  color: #FFF;
}

Vue

let arrayMove = (arr, from, to) => arr.splice(to, 0, arr.splice(from, 1)[0])

new Vue({
  el: "#app",
  data: {
    sections: []
  },
  methods: {
    addSection() {
      this.sections.push({ body: Math.random().toString() })
    },
    
    insertSection(i) {
      this.sections.splice(i, 0, { body: Math.random().toString() })
    },
    
    deleteSection(i) {
    	this.sections.splice(i, 1)
    },
    
    moveSectionUp(i) {
    	if (i > 0) {
      	arrayMove(this.sections, i, i - 1)
      }
    },
    
    moveSectionDown(i) {
    	if (i < this.sections.length - 1) {
      	arrayMove(this.sections, i, i + 1)
      }
    }
  }
})