JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://unpkg.com/vue"></script>
<div id="app"></div>

<script type="text/x-template" id="phoneList-template">
<div id="app">
<table class="table table-hover" id="vuePhoneList">
  <thead>
    <tr>
      <th width="25%">Телефон</th>
      <th width="50%">Имя
        <th><a href="#" class="glyph pull-right" v-bind:class="{'hover-opacity': phoneListLoaded}" v-on:click.prevent="refreshList"><span class="glyphicon glyphicon-refresh text-success"></span></a></th>
    </tr>
  </thead>
  <tbody v-if="phoneListLoaded">
    <tr v-for="elem in phoneList" key="elem.phone">
      <td>{{ elem.phone }}</td>
      <td>{{ elem.name }}</td>
      <td><a href="#" class="glyph pull-right" v-bind:class="{'hover-opacity': !elem.removing}" v-on:click.prevent="removePhone(elem)"><span class="glyphicon glyphicon-remove-sign text-danger"></span></a></td>
    </tr>
  </tbody>
</table>
<confirm :shown="confirmShown" header="Удалить номер?" :text="confirmText" @confirm="removePhoneConfirm" @close="closeConfirm" ></confirm>
</div>
</script>

<script type="text/x-template" id="confirm-template">

<div class="modal fade" tabindex="-1" role="dialog" id="vueConfirm">
  <div class="modal-dialog modal-sm" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" v-on:click="dismiss" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title">{{ header }}</h4>
      </div>
      <div class="modal-body">
        {{ text }}
      </div>
      <div class="modal-footer">
        <button type="button"...

CSS

.hover-opacity {
			  opacity: 0.2;
			}
			
			.hover-opacity:hover {
			  opacity: 0.5;
			}
			
			.hover-opacity:active {
			  opacity: 1;
			}
			
			.glyph {
			  float: right;
			  font-size: 21px;
			  line-height: 1;
			  text-shadow: 0 1px 0 #fff;
			}

Babel + JSX

const extAPI = {
	phones: [{
            phone: '123456789',
            name: 'Иван'
          }, {
            phone: '234567891',
            name: 'Петр'
          }, {
            phone: '345678912',
            name: 'Сидор'
          }],
	getPhoneList () {
    return new Promise( (resolve, reject) => 
      setTimeout( () => {
        resolve(extAPI.phones)
        }, 200)
      )
  },
	deletePhone (phone) {
    return new Promise ((resolve, reject) => {
      setTimeout( () => {
      	let idx = extAPI.phones.findIndex(elm => elm.phone === phone)
        if (idx !== -1)
        	extAPI.phones.splice(idx, 1)
        resolve(extAPI.phones)
      }, 200)
    })
  }
}

Vue.extAPI = window.extAPI = extAPI
      
let phoneListInstance = new Vue({
  el: '#app',
  template: "#phoneList-template",
  data () {
  	return {
      phoneList: [],
      phoneListLoaded: false,
      phoneListLoading: false,
      currPhone: null,
      confirmShown: false
		}
	},
  beforeMount () {
  	this.refreshList()
  },
  computed: {
  	confirmText () {
    	if (this.currPhone)
    		return `Удалить номер ${this.currPhone.phone}?`
      else
      	return ''
    }
  },
  methods: {
    refreshList () {
      this.phoneListLoaded = false;
      this.phoneListLoading = true;
      extAPI.getPhoneList().then( (r) => {      
        this.phoneList = r
        this.phoneListLoaded = true;
        this.phoneListLoading = false;
      })
    },
    removePhone (elem) {
    	this.currPhone = elem
      Vue.set(this.currPhone, 'removing', true)
      this.showConfirm()
		},
    removePhoneConfirm () {
    	if (this.currPhone) {
        extAPI.deletePhone(this.currPhone.phone)
          .then( (r) => {
            this.phoneList = r
          })
      }
    },
    showConfirm () {
    	this.confirmShown = true
    },
    closeConfirm() {
    	this.confirmShown = false
      if (this.currPhone) {
      	Vue.set(this.currPhone, 'removing', false)
      }
    },
 ...