# Объект для чтения
Такой же принцип, как и для примитива.
Пока я готовила пример, я обнаружила одну любопытную особенность. Даже с Proxy
, запрещающим по идее любые изменения, если добавить новое поле в компоненте таким образом
this.$set(this.obj, 'newField', 'Got ya!')
То это сработает, новое поле добавится. Если новое поле попытаться добавить из компонента классическим способом, то есть
this.obj.newField = 'Nah';
То вот так не сработает. А через $set
работает. Изменение существующих полей даже через $set
не проходит, так что думаю уровень защищенности достаточный, но про такую особенность стоит знать.
# Класс
class ReadonlyObject {
_obj = {
field: 'string',
field2: 'anotherString'
}
get obj() {
return new Proxy(this._obj, {
set() {
throw new Error('This property is read-only')
}
})
}
changeField() {
this._obj.field = 'number';
this._obj.field2 = 'anotherNumber';
}
}
const instance = new ReadonlyObject();
export default instance;
# Компонент
<template>
<div class="component-block">
<span class="name">ReadonlyObjectOne</span>
<div><b>Значение obj:</b> {{ obj }}</div>
<button @click="changeField">Изменить поля через метод</button><br />
<button @click="tryToChange">Изменить поля через компонент</button><br />
<div>{{ error }}</div>
</div>
</template>
<script>
import ReadonlyObject from '@example-services/ReadonlyObject';
export default {
data() {
return {
obj: ReadonlyObject.obj,
changeField: ReadonlyObject.changeField.bind(ReadonlyObject),
error: null,
};
},
methods: {
tryToChange() {
try {
this.obj.field = 'fromComponent'; // Ошибка!
} catch(e) {
this.error = e;
}
}
}
}
</script>
# Результат
ReadonlyObjectOne
Значение obj: {
"field": "string",
"field2": "anotherString"
}
ReadonlyObjectTwo
Значение obj: {
"field": "string",
"field2": "anotherString"
}