логотип PurpleSchool
логотип PurpleSchool

Управление property и функциями во Vue.js

Автор

Олег Марков

Введение

Управление свойствами (property) и функциями — одна из основ разработки на Vue.js. Правильно организованная работа с данными и логикой компонентов позволяет строить эффективные и поддерживаемые SPA-приложения. Если вы только осваиваете Vue.js, изучение принципов реактивности, работы с props, data, computed, методов и слежением (watch) поможет глубже понять, как компоненты взаимодействуют с данными и друг с другом, и правильно структурировать код.

Давайте разберёмся, как взаимодействовать с данными и функциями внутри компонентов Vue, какие возможности предоставляет сам фреймворк и к каким инструментам прибегать в зависимости от задачи: передача данных между компонентами, вычисляемые свойства, методы, слежение за изменениями состояний и работа со свойствами.

Свойства компонента: data и props

data: локальные состояния компонента

В Vue.js свойство data — это то место, где хранятся внутренние данные вашего компонента. Эти данные реактивны: при изменении значений компонента Vue обновляет связанную с этими данными разметку. Вот простой пример:

export default {
  data() {
    return {
      count: 0, // Счетчик
      message: "Привет, Vue!" // Приветственное сообщение
    }
  }
}

Переменные из data доступны в шаблоне:

<template>
  <div>
    <p>{{ message }}</p>       <!-- Выведет "Привет, Vue!" -->
    <button @click="count++">Вы нажали {{ count }} раз</button>
  </div>
</template>

Особенности data

  • data должно быть функцией, возвращающей объект (особенно в компонентах). Это нужно для изолированности состояния каждого экземпляра компонента.
  • Все поля из data становятся реактивными. Vue следит за их изменением и обновляет DOM.

props: входные параметры компонента

props позволяют передавать данные в дочерний компонент от родителя. Пример использования:

export default {
  props: {
    title: String, // Ждем строку в качестве заголовка
    count: {
      type: Number,
      default: 0  // Значение по умолчанию
    }
  }
}

Использование во вёрстке:

<MyCounter title="Счетчик" :count="currentCount" />

В шаблоне дочернего компонента:

<h2>{{ title }}</h2>
<p>Current: {{ count }}</p>

Особенности props

  • Типизация prop помогает передавать и валидировать данные.
  • Props односторонние: изменять их напрямую внутри дочернего компонента нельзя, иначе Vue выдаст предупреждение.
  • Если надо изменить prop — эмитируйте событие наверх и измените значение на уровне родителя.

Методы: объявление бизнес-логики

Для обработки событий и разного рода действий используйте секцию methods. В методы можно обращаться как из шаблона, так и програмно:

export default {
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increment() {
      this.count++ // Увеличиваем счетчик по клику
    }
  }
}

Использование метода в шаблоне:

<button @click="increment">+1</button>

Особенности методов

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

computed: вычисляемые свойства

computed-свойства в Vue особенно полезны для вычислений на основе реактивных данных. Ключевое отличие — Vue кэширует результат computed-свойства, пока не изменятся входные данные. По сути, computed — это свойства с getter'ом (и опционально setter'ом).

export default {
  data() {
    return {
      items: [1, 2, 3, 4]
    }
  },
  computed: {
    itemsCount() {
      return this.items.length // Посчитает количество элементов
    }
  }
}

Применение в шаблоне:

<p>Всего элементов: {{ itemsCount }}</p>

computed vs methods

  • Используйте computed, если результат основывается только на реактивных данных, и нужно, чтобы это вычисление кэшировалось.
  • Используйте methods, когда требуется каждый раз получать актуальный результат, независимо от палитры входных данных.
computed: {
  doubled() {
    return this.count * 2 // Посчитает count*2 — и закеширует до тех пор, пока не изменится count
  }
}
methods: {
  doubled() {
    return this.count * 2 // Каждое обращение — пересчет
  }
}

watch: слежение за изменениями

Если вам нужно выполнить побочное действие при изменении какой-либо переменной, используется опция watch. Она помогает реагировать на изменения состояния и запускать код: отправить запрос, изменить другие переменные, синхронизировать данные и так далее.

export default {
  data() {
    return {
      name: ''
    }
  },
  watch: {
    name(newValue, oldValue) {
      // Каждый раз, когда name меняется, вызывается эта функция
      console.log(`name изменилось: ${oldValue} → ${newValue}`)
    }
  }
}

Применение deep и immediate

Если следить нужно за вложенными объектами или массивами — используйте deep:

watch: {
  user: {
    handler(newValue) {
      // Реакция на изменение любого поля объекта user
    },
    deep: true
  }
}

Чтобы вызвать watcher сразу после монтирования компонента — immediate:

watch: {
  name: {
    handler(newValue) {
      // Этот обработчик сработает и при инициализации компонента
    },
    immediate: true
  }
}

Работа со свойствами через setup() (Composition API)

В Vue 3 добавился новый способ — Composition API. Вместо объектов с опциями (data, methods, computed) вы описываете всю логику внутри функции setup() с использованием реактивных утилит Vue.

import { ref, computed, watch } from 'vue'

export default {
  setup(props) {
    const count = ref(0) // реактивное число
    const doubled = computed(() => count.value * 2) // вычисляемое свойство

    function increment() {
      count.value++
    }

    watch(count, (newValue) => {
      // Следим за count
      console.log('Изменилась count:', newValue)
    })

    // Всё, что возвращаете — становится доступно в шаблоне
    return { count, doubled, increment }
  }
}

Передача props в setup

В функцию setup первым аргументом попадает объект props:

setup(props, context) {
  console.log(props.title) // title был передан в компонент
}

Если нужно сделать prop реактивным:

import { toRefs } from 'vue'

setup(props) {
  const { title, count } = toRefs(props)
  // Теперь title и count — реактивные ссылки
}

Работа с emit и событиями

Через второй аргумент контекста доступны emit и другие утилиты:

setup(props, { emit }) {
  function onClick() {
    emit('clicked') // Эмитируем событие наверх
  }
  return { onClick }
}

Примеры объединения property и функций

Давайте рассмотрим, как можно объединять работу со свойствами и функциями для создания интерактивных компонентов.

Пример: Интерактивный счетчик с родительским управлением

App.vue (родитель):

<template>
  <ChildCounter :start="5" @update="handleUpdate" />
  <p>Значение в родителе: {{ counterValue }}</p>
</template>

<script>
import ChildCounter from './ChildCounter.vue'

export default {
  components: { ChildCounter },
  data() {
    return {
      counterValue: 5
    }
  },
  methods: {
    handleUpdate(newValue) {
      this.counterValue = newValue
    }
  }
}
</script>

ChildCounter.vue (дочерний):

<template>
  <button @click="increment">+</button>
  <span>{{ current }}</span>
</template>

<script>
export default {
  props: ['start'],
  data() {
    return {
      current: this.start
    }
  },
  methods: {
    increment() {
      this.current++
      this.$emit('update', this.current) // Сообщаем родителю
    }
  }
}
</script>

Здесь объединены props (приём данных), data (локальное состояние), methods (логика), emit (обратная связь).

Пример: Вычисления на основе props и data

export default {
  props: {
    price: Number,
    count: Number
  },
  computed: {
    total() {
      // Используем и props, и data (если нужно)
      return this.price * this.count
    }
  }
}

В шаблоне:

<p>Общая стоимость: {{ total }}</p>

Лучшие практики и нюансы управления property и функциями

Следите за реактивностью

Vue отслеживает только те поля, которые объявлены в момент инициализации компонента. Если объект был создан без поля, добавленного динамически, оно не станет реактивным без специальных методов (Vue.set в Vue 2, reactive/ref — во Vue 3).

Не мутируйте props в дочерних компонентах

Если вам нужно изменить данные, пришедшие в виде prop, создайте локальную копию:

props: ['value'],
data() {
  return {
    localValue: this.value
  }
},
watch: {
  value(newVal) {
    this.localValue = newVal // если value поменялось в родителе — синхронизируем
  }
}

Используйте методы для действий, computed — для derived-данных

Такой подход улучшает читаемость и производительность компонентов.

В Composition API старайтесь использовать ref и computed

Используйте ref для скалярных значений, reactive — для объектов/массивов, и computed — для вычисляемых данных.

Расширяйте возможности watcher

Watcher можно использовать и для нескольких переменных сразу (если обернуть массивом):

watch([count, price], ([newCount, newPrice]) => {
  // этот watcher сработает, если меняется count или price
})

Заключение

Управление свойствами, методами и реактивностью — фундамент приложения на Vue.js. Используйте props для передачи данных, data — для локального состояния, computed — для производных сведений, methods — для бизнес-логики действий, watch — для слежения за изменениями. В Vue 3 активно применяйте Composition API, чтобы собирать всю связанную логику в одном месте через setup с ref/computed/watch.

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

Частозадаваемые технические вопросы по теме и ответы

Как отслеживать изменения в массиве или объекте, чтобы они были реактивными во Vue 2?

Vue 2 не отслеживает добавление новых свойств в объект или элементов в массив после инициализации. Чтобы гарантировать реактивность, используйте Vue.set(obj, key, value) для динамически добавляемых свойств или элементов. Например, чтобы добавить новый ключ в объект: Vue.set(user, 'age', 25). Для массивов: Vue.set(items, index, newValue).

Как пробросить функцию из родителя в дочерний компонент через props?

Передавать функцию через props можно как обычное значение: <Child :handler="onAction" />, где onAction — функция из родителя. В дочернем компоненте объявите prop (handler: Function) и вызывайте её при необходимости (this.handler(arg)). В Composition API аналогично — обращайтесь к props.handler().

Как использовать методы жизненного цикла внутри setup() во Vue 3?

В Composition API методы жизненного цикла реализуются через одноимённые функции: onMounted, onUpdated, onUnmounted и т.д. Импортируйте их из vue: import { onMounted } from 'vue'. Затем внутри setup вызывайте: onMounted(() => { /* код при монтировании */ }).

Как организовать повторное использование методов и свойств между несколькими компонентами?

Во Vue 2 используйте mixins: создайте объект с нужными свойствами, импортируйте его и добавьте в массив mixins: [myMixin]. Во Vue 3 рекомендуется использовать composables — обычные JS-функции, возвращающие набор реактивных свойств/функций. Импортируйте и вызывайте их в нужных компонентах внутри setup().

Как обновить значение prop в дочернем компоненте (например, для реализации v-model)?

Для двусторонней привязки во Vue используйте паттерн v-model: родитель передает значение через prop, а дочерний компонент эмитирует событие (this.$emit('update:modelValue', новоеЗначение)). В родителе это связывается с переменной: <Child v-model="value" />. В Vue 3 v-model по умолчанию работает с prop modelValue и событием update:modelValue.

Стрелочка влевоПередача данных между компонентами с помощью props в Vue jsОсновы работы с объектами в VueСтрелочка вправо

Все гайды по Vue

Работа с пользовательскими интерфейсами и UI библиотеками во VueОрганизация и структура исходных файлов в проектах VueОбзор популярных шаблонов и стартовых проектов на VueКак организовать страницы и маршруты в проекте на VueСоздание серверных приложений на Vue с помощью Nuxt jsРабота со стилями и CSS в Vue js для красивых интерфейсовСоздание и структурирование Vue.js приложенияНастройка и сборка проектов Vue с использованием современных инструментов
Управление переменными и реактивными свойствами во VueИспользование v for и slot в VueТипизация и использование TypeScript в VuejsИспользование шаблонов в Vue js для построения интерфейсовПередача данных между компонентами с помощью props в Vue jsУправление property и функциями во Vue.jsОсновы работы с объектами в VueПонимание жизненного цикла компонента Vue js на примере mountedИспользование метода map в Vue для обработки массивовОбработка пользовательского ввода в Vue.jsОрганизация файлов и структура проекта Vue.jsКомпоненты Vue создание передача данных события и emitИспользование директив и их особенности на Vue с помощью defineСоздание и использование компонентов в Vue JSОбработка кликов и пользовательских событий в Vue
Открыть базу знаний