В настоящее время я работаю над проектом Vue, в котором я хочу иметь класс модели, который хранит все свои начальные данные в двух свойствах: original
и attributes
. Однако у меня возникают трудности с привязкой свойств к входу через v-model
.
Допустим, у меня есть следующий класс:
class Model
{
constructor () {
return new Proxy(this, {
get: (target, property, receiver) => {
console.log('get');
return target[property];
},
set: (target, property, value, receiver) => {
console.log('set');
target[property] = value + 123;
return true;
}
});
}
}
Этот класс будет регистрировать get
при получении свойства и set
при установке свойства. Также при настройке он добавит 123
в конце значения. Будет выполнено следующее:
let model = new Model();
model.name = 'test'; // Logs: 'set'
console.log(model.name); // Logs: 'get' and 'test123'
Это работает как ожидалось.
Проблемы начинаются, когда я связываю эти свойства со входом через v-model
. Происходит следующее:
Действия выполняются:
<input v-model="model.name" />
...
data () {
return {
model: new Model
};
}
При первом изменении свойство name
будет добавлено к объекту model
. Нет журнала вообще. Без добавления 123
в конце значения. Значение модели изменилось на { model: 't' }
.
Второе изменение будет записывать set
и добавит 123
. Значение модели изменилось на { model: 'te123' }
.
Регистрация аргументов вызова set
во время второго изменения:
Model {__ob__: Observer}, "name", "te", Proxy {__ob__: Observer}
Кто-нибудь имел эту проблему раньше или знает, что здесь происходит?
После ответа @ sphinx
Спасибо за ваш ответ! Это работает!
Чтобы сделать вещи более сложными, я хочу, чтобы свойства, которые находятся в определенном массиве fillable
, были установлены в свойстве под названием attributes
. Однако возвращается то же поведение.
class Model
{
constructor () {
this.attributes = {};
this.fillable = ['name'];
return new Proxy(this, {
get: (target, property, receiver) => {
console.log('get', property);
if (target.fillable.indexOf(property) > -1) { // Check if in fillable
if (!(property in target.attributes)) {
Vue.set(target.attributes, property, null);
}
return target.attributes[property];
}
return target[property];
},
set: (target, property, value, receiver) => {
console.log('set', property, value);
if (target.fillable.indexOf(property) > -1) {
Vue.set(target.attributes, property, value + 123);
} else {
target[property] = value
}
return true;
}
});
}
}
Vue.config.productionTip = false
new Vue({
el: '#app',
data() {
return {
test: new Model
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<span>{{test.name}}</span>
<input v-model="test.name" type="text">
</div>
Во время первого изменения свойство name
устанавливается непосредственно для объекта model
. Но метод set
не вызывается.
Во время второго изменения свойство name
изменяется и вызывается метод set
.
Любые предложения о том, почему это происходит?