Значения сложим в объект (это если надо оставить человекопонятные имена) или массив:
data: () => ({
maxSum: 1000,
values: {
v1: 69,
v2: 187,
v3: 666,
v4: -100,
},
},
Сделаем пару вычисляемых свойств - копию значений и их сумму:
computed: {
valuesCopy() {
return { ...this.values };
},
sum() {
return Object.values(this.values).reduce((acc, n) => acc + n, 0);
},
},
Установим наблюдение за копией, где, в случае некорректности суммы, предыдущая копия будет устанавливаться в качестве актуальных значений:
watch: {
valuesCopy(newVal, oldVal) {
if (!Number.isFinite(this.sum) || this.sum > this.maxSum) {
this.values = oldVal;
}
},
},
https://jsbin.com/suxefokune/edit?html,js,output
Инпуты могут быть в разных компонентах, связаны через Vuex
Данные уносим в хранилище.
Создаём мутацию для обновления данных. Внутри вычисляем новую сумму, если она не превышает максимально допустимую, то сохраняем значение. В противном случае заменяем значения их копией (да, значения в хранилище всё ещё корректны, но вот в компоненте в input'е мусор, надо обновить):
mutations: {
setValue(state, [ key, val ]) {
const sum = Object
.entries(state.values)
.reduce((acc, n) => acc + (n[0] === key ? val : n[1]), 0);
if (sum <= state.maxSum) {
state.values[key] = val;
} else {
state.values = Object.assign({}, state.values);
}
},
},
Собственно компонент для редактирования значений - принимает ключ, по которому вытягивает значение из хранилища, и дёргает мутацию для сохранения нового значения:
Vue.component('v-input', {
props: [ 'storeKey' ],
template: `
<input
:value="$store.state.values[storeKey]"
@input="$store.commit('setValue', [ storeKey, +$event.target.value ])"
>`,
});
Создаём столько экземпляров, сколько потребуется:
<div v-for="(v, k) in $store.state.values">
{{ k }}: <v-input :store-key="k"></v-input>
</div>
<div>
ещё раз v3: <v-input store-key="v3"></v-input>
</div>
<div>
и v2 тоже: <v-input store-key="v2"></v-input>
</div>
https://jsbin.com/zinenazitu/edit?html,js,output