<div id="app">
  <div class="navigation">
    <ul>
      <li v-for="(link, index) in links">
        <a :href="link.url" :id="index">
          {{ link.text }}
        </a>
        <span class="removeHover">
          <button @click="removeLink(index)">X</button>
        </span>
        <span class="editHover">
          <button @click="showForm(index)">Edit</button>
        </span>
      </li>
    </ul>
  </div>
  <transition name="fade">
    <div class="editMenu" v-show="isEditing">
      <button class="close" @click="hideForm">X</button>
      <h3>Edit Link</h3>
      <label>Link Title</label>
      <input v-model="editLink" @keyup.enter="editLinks" type="text">
      <label>Link URL</label>
      <input v-model="editURL" @keyup.enter="editLinks" type="text">
    </div>
  </transition>
  <div class="navigation--input">
    <label>Link Title</label>
    <input v-model="newLink" type="text">
    <label>Link URL</label>
    <input v-model="newURL" @keyup.enter="addLink" type="text">
    <span class="error" v-if="isEmpty" v-model="error">Error! {{ error }}</span>
    <button @click="addLink">Add to Navigation</button>
  </div>
  <transition name="fade">
    <div class="editBG" v-show="isEditing"></div>
  </transition>
</div>
body {
  padding: 0;
  margin: 0;
}
.navigation {
  background-color: #ddd;
  width: 100%;
  margin: 0;
  
  ul {
    margin: 0;
    padding: 20px 0;
    text-align:center;
  }
  
  li {
    display: inline-block;
    padding: 0 20px;
    position: relative;
    
    a {
      color: #555;
      text-decoration: none;
      
      &:hover {
        border-bottom: 2px solid;
      }
    }
  }
  
  &--input {
    width: 20%;
    text-align: center;
    padding: 40px 0;
    margin: 0 auto;
    
    input {
      margin: 10px auto 0 auto;
      border-radius: 5px;
      border: 1px solid #ddd;
      padding: 5px;
      display: block;
      width: 100%;
    }
    
    button {
      margin-top: 20px;
      background-color: cornflowerblue;
      padding: 10px 24px;
      border-radius: 3px;
      color: #fff;
      transition: all .3s ease-out;
      
      &:hover {
        background-color: navy;
      }
    }
    
    label {
      text-align: left;
      display: block;
      
      &:not(:first-child){
        margin-top: 20px;
      }
    }
  }
}
.removeHover {
  opacity: 0;
  z-index: 2;
  transition: all .3s ease-out;
    
  li:hover & {
    opacity: 1;
  }
  
  button {
    position: absolute;
    text-align: center;
    border-radius: 50%;
    background-color: lightcoral;
    color: #fff;
    font-size: .5em;
    top: 0;
    right: 0;
    margin-top: -11px;
    padding: 5px;
    outline: none;
    &:hover {
      background-color: coral;
    }
  }
}

.editHover {
  position: absolute;
  bottom: -30px;
  left: 0;
  right: 0;
  opacity: 0;
  
  li:hover &{
    opacity: 1;
  }
}

.error {
  width: 100%;
  display: block;
  background-color: #ff000029;
  padding: 10px 5px;
  margin-top: 14px;
  border-radius: 3px;
}

.editMenu {
  max-width: 400px;
  margin: 60px auto;
  position: absolute;
  left: 0;
  right: 0;
  z-index: 4;
  background-color: #fff;
  padding: 30px;
  border-radius: 5px;
  
  .close {
    position: absolute;
    right: 10px;
    top: 10px;
  }

  input {
    display: block;
    width: 100%;
  }

  label:not(:first-child) {
    margin-top: 10px;
    margin-bottom: 5px;
    display: inline-block;
  }
}

.editBG {
    position: fixed;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0,0,0,.2);
}

.fade-enter-active, .fade-leave-active {
  transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;
}
View Compiled
new Vue({
  el: '#app',
  data: {
    isEmpty: false,
    error: '',
    newLink: '',
    newURL: '',
    isEditing: false,
    editingIndex: 0,
    editLink: '',
    editURL: '',
    links: [
      { text: 'Home', url: 'http://google.com' },
      { text: 'Work', url: 'http://dribbble.com'},
      { text: 'Blog', url: 'http://medium.com'},
      { text: 'Test', url: 'ham' }
    ]
  },
  methods: {
    addLink: function() {
      var text = this.newLink.trim()
      var url = this.newURL.trim()
      if ((text !== '') && (url !== '')) {
        this.isEmpty = false
        this.links.push({ text: text, url: url })
        this.newLink = ""
        this.newURL = ""
      } else {
        this.isEmpty = true
        this.error = 'Complete all boxes!'
      }
    },
    removeLink: function(index) {
      this.links.splice(index, 1)
    },
    showForm: function(index) {
      this.isEditing = true
      this.editingIndex = index
      this.editURL = this.links[index].url
      this.editLink = this.links[index].text
      // Thanks to https://codepen.io/RoelN for this solution
    },
    hideForm: function() {
      this.isEditing = false
    },
    editLinks: function(){
      var text = this.editLink.trim()
      var url = this.editURL.trim()
      Vue.set(this.links, this.editingIndex, { text: text, url: url })
      this.isEditing = false
      this.editLink = ""
      this.editURL = ""
    }
  }
})

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js