Одна из основных концепций Vue.js - это вычисляемые свойства. С помощью вычисляемых свойств мы можем легко составлять новые данные, полученные из других данных. И эти новые данные будут кэшироваться до тех пор, пока не изменится одна из их зависимостей.

Вот небольшой пример:

data () {
  return {
    firstName: 'Foo',
    lastName: 'Bar'
  }
},

computed: {
  fullName () {
    return `${this.firstName} ${this.lastName}`
  }
}

fullName - это то, что мы называем вычисляемым геттером - мы используем его для получения вычисленного значения. Но что, если мы тоже захотим его установить?

Мы можем определить для этого вычисляемый сеттер, например:

computed: {
  fullName: {
    get () {
      return `${this.firstName} ${this.lastName}`
    },
    set (fullName) {
      this.firstName = fullName.split(' ')[0]
      this.lastName = fullName.split(' ')[1]
    }
  }
}

Теперь, когда вы устанавливаете новое значение на fullname (используя this.fullName = 'Example Name'), firstName и lastName будут обновляться соответственно.

Покажи мне практический пример

Когда ваш компонент использует данные извне - например, данные, передаваемые через реквизиты или из vuex - вы можете упростить способ взаимодействия с этими данными с помощью вычисленных сеттеров.

Давайте возьмем пример, в котором сначала не используются вычисляемые сеттеры, а затем улучшим его, добавив в него вычисляемые сеттеры.

Без вычисляемых сеттеров:

<template>
  <div>
    <input
      :value="text"
      type="text"
      @input="onInput"
    >
    <button @click="convertToUpperCase">ToUpperCase</button>
  </div>
</template>
<script>
export default {
  props: ['text'],
  methods: {
    onInput (e) {
      this.$emit('set-text', e.target.value)
    },
    convertToUpperCase () {
      this.$emit('set-text', this.text.toUpperCase())
    }
  }
}
</script>

С вычисляемыми сеттерами:

<template>
  <div>
    <input
      v-model="textValue"
      type="text"
    >
    <button @click="convertToUpperCase">ToUpperCase</button>
  </div>
</template>
<script>
export default {
  props: ['text'],
  computed: {
    textValue: {
      get () {
        return this.text
      },
      set (value) {
        this.$emit('set-text', value)
      }
    }
  },
  methods: {
    convertToUpperCase () {
      this.textValue = this.textValue.toUpperCase()
    }
  }
}
</script>

Использование вычисленных сеттеров улучшило наш пример двумя способами:

  1. Во-первых, обновление внешних данных кажется намного проще. Теперь мы можем заменить :valueи @input на v-model. Также мы можем изменить значение с помощью простого присваивания - как в методе convertToUpperCase.
  2. Во-вторых, изменение источника внешних данных требует только обновления вычисляемого установщика, а не замены каждого $emit('set-text') в компоненте. Поэтому, если вы решили изменить источник на использование данных из vuex, вам просто нужно изменить метод установки на что-то вроде this.$store.dispatch('SET_TEXT', value).