Ну вот надо чтобы до перезагрузки страницы интерфейс "замер".
const appNode = document.querySelector('#app');
appNode.innerHTML = appNode.innerHTML;
<div id="app" data-rows='<?=json_encode($rows)?>'>...</div>
data() {
return { rows: JSON.parse(this.$el.getAttribute('data-rows')) };
}
const api = {
async getData() {
return {name: 'Foo', email: 'foo@bar.com'};
}
}
new Vue({
el:'#app',
template: `<div v-if="current">
<input v-model="current.name" />
<input v-model="current.email" />
<button :disabled="!isChanged">submit</button>
</div>`,
data() {
return {
original: null,
current: null,
}
},
async created() {
const data = await api.getData();
this.original = JSON.stringify(data);
this.current = data;
},
computed: {
isChanged() {
return JSON.stringify(this.current) !== this.original;
}
}
});
<input type="text" v-model="name" @input="name_changed = true">
и будет счастие When they exist on the same node, v-for has a higher priority than v-if. That means the v-if will be run on each iteration of the loop separately.
template
:<template v-if="shouldShowAllTags()">
<a v-for="tag in tags">{{tag}}</a>
</template>
...
<template v-for="tag in tags">
<a v-if="shouldShowThisTag(tag)">{{tag}}</a>
</template>
v-else
, если понадобитсяitem
и active
- плохие названия для переменных, хранящих класс, makeActive
- плохое название метода, его меняющего. Называем все по-людски.data: {
activeClass: 'container'
...
},
methods: {
setActiveClass: function(className) { ... }
}
data: {
activeClass: 'container',
buttons: [
['+', 'container'],
['-', 'container-fluid']
]
}
<button v-for="[label, className] in buttons">...</button>
data
нет необходимости. <button
v-for="[label, className] in buttons"
v-on:click="setActiveClass(className)"
v-bind:class="{ active: className === activeClass }">
{{label}}
</button>