# Свойство только для чтения

Сделаем запрет на изменение в компоненте, разрешим менять свойство только через метод. Это можно реализовать, получая из компонента не само свойство напрямую, а его геттер, обернутый в Proxy, MDN (opens new window).

# Класс






 
 
 
 
 
 
 









class PrivatePrimitiveProperty {
  _privateString = {
    value: 'I\'m private',
  }

  get privateString() {
    return new Proxy(this._privateString, {
      set() {
        throw new Error('This property is read-only');
      },
    });
  }

  changePrivateString() {
    this._privateString.value = 'My value is changed from method';
  }
}

const instance = new PrivatePrimitiveProperty();

export default instance;

TIP

Необязательно выкидывать exception в set, достаточно просто вернуть false. В таком случае тоже будет ошибка, но без нормального описания.

set() {
  return false;
}

# Компоненты

PrivatePrimitiveOne

Попытка изменения напрямую через компонент вызовет ошибку

























 








<template>
  <div class="component-block">
    <span class="name">PrivatePrimitiveOne</span>

    <span><b>Значение privateString:</b> {{ privateString.value }}</span><br/>
    <button @click="changeValue">Change value</button><br />

    <span v-if="error">{{ error }}</span>
  </div>
</template>

<script>
import PrivatePrimitiveProperty from '@example-services/PrivatePrimitiveProperty';

export default {
  data() {
    return {
      privateString: PrivatePrimitiveProperty.privateString,
      error: '',
    };
  },
  methods: {
    changeValue() {
      try {
        this.privateString.value = 'someAnotherString';
      } catch (e) {
        this.error = e;
      }
    },
  },
}
</script>

PrivatePrimitiveTwo

Попытка изменения, вызванная через метод, отработает корректно






 










 





<template>
  <div class="component-block">
    <span class="name">PrivatePrimitiveTwo</span>

    <span><b>Значение privateString:</b> {{ privateString.value }}</span><br/>
    <button @click="changePrivateString">Change value</button>
  </div>
</template>

<script>
import PrivatePrimitiveProperty from '@example-services/PrivatePrimitiveProperty';

export default {
  data() {
    return {
      privateString: PrivatePrimitiveProperty.privateString,
      changePrivateString: PrivatePrimitiveProperty.changePrivateString.bind(PrivatePrimitiveProperty),
    };
  },
}
</script>

# Результат

PrivatePrimitiveOne Значение privateString: I'm private

PrivatePrimitiveTwo Значение privateString: I'm private
Обновлено: 12/12/2022, 3:53:53 PM