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>
<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">
<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>
<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">×</span></button>
<h4 class="modal-title">{{ header }}</h4>
</div>
<div class="modal-body">
{{ text }}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" v-on:click="confirm">Да</button>
<button type="button" class="btn btn-default" v-on:click="dismiss">Нет</button>
</div>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
<!-- /.modal -->
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;
}
JavaScript
let phoneListInstance = new Vue({
el: '#vuePhoneList',
data: {
phoneList: [],
phoneListLoaded: false,
phoneListLoading: false
},
methods: {
refreshList: function() {
this.phoneListLoaded = false;
this.phoneListLoading = true;
let that = this;
setTimeout(function() {
that.phoneList = [{
phone: '123456789',
name: 'Иван'
}, {
phone: '234567891',
name: 'Петр'
}, {
phone: '345678912',
name: 'Сидор'
}];
that.phoneListLoaded = true;
that.phoneListLoading = false;
}, 200);
},
removePhone: function(elem) {
Vue.set(elem, 'removing', true);
let that = this;
confirmInstance.show('Удалить номер?', `Удалить номер ${elem.phone}?`, function(res) {
if (res)
that.removePhoneConfirm(elem);
else
elem.removing = false;
});
},
removePhoneConfirm: function(elem) {
let that = this;
setTimeout(function() {
Vue.delete(that.phoneList, that.phoneList.indexOf(elem));
}, 200);
}
}
});
let confirmInstance = new Vue({
el: '#vueConfirm',
data: {
header: '',
text: '',
callback: function() {},
result: false
},
methods: {
show: function(header, text, callback) {
this.header = header;
this.text = text;
this.callback = callback;
this.result = false;
$(this.$el).modal('show');
},
confirm: function() {
this.result = true;
$(this.$el).modal('hide');
},
dismiss: function() {
this.result = false;
$(this.$el).modal('hide');
}
},
mounted: function() {
let that = this;
$(this.$el).on('hide.bs.modal',...