# Свойства data и методы

# Свойства data

Свойство data компонента должно быть функцией. На этапе создания нового экземпляра компонента Vue будет вызывать эту функцию. Она должна возвращать объект, который Vue затем оборачивает в свою систему реактивности и сохраняет в экземпляре компонента как $data. Для удобства, все свойства объекта первого уровня будут доступны напрямую через экземпляр компонента:

const app = Vue.createApp({
  data() {
    return { count: 4 }
  }
})

const vm = app.mount('#app')

console.log(vm.$data.count) // => 4
console.log(vm.count)       // => 4

// Присвоение значения в vm.count также обновит $data.count
vm.count = 5
console.log(vm.$data.count) // => 5

// ... и наоборот
vm.$data.count = 6
console.log(vm.count) // => 6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

Эти свойства добавляются только при первом создании экземпляра, поэтому убедитесь, что все они присутствуют в объекте, возвращаемом функцией data. При необходимости используйте null, undefined или какое-либо другое значение по умолчанию для свойств, где требуемое значение изначально недоступно.

Конечно есть возможность добавить новое свойство в экземпляр компонента без добавления его в data. Однако, поскольку это свойство не находилось в реактивном объекте $data, оно не будет автоматически отслеживаться системой реактивности Vue.

Vue использует префикс $ для обозначения встроенного API, предоставляемого через экземпляр компонента. Также зарезервирован префикс _ для внутренних свойств. Следует избегать именования свойств data первого уровня, которые начинаются с них.

# Методы

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

const app = Vue.createApp({
  data() {
    return { count: 4 }
  },
  methods: {
    increment() {
      // `this` указывает на экземпляр компонента
      this.count++
    }
  }
})

const vm = app.mount('#app')

console.log(vm.count) // => 4

vm.increment()

console.log(vm.count) // => 5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

Vue автоматически привязывает к методам значение this таким образом, чтобы оно указывало на экземпляр компонента. Это гарантирует, что правильное значение this всегда сохраняется в методе, даже если он используется в качестве обработчика события или коллбэка. Следует избегать использование стрелочных функций при определении methods, так как это не позволяет Vue привязать корректное значение this.

Как и все остальные свойства экземпляра компонента, methods доступны в шаблоне компонента. Наиболее часто они используются в качестве обработчиков событий:

<button @click="increment">Up vote</button>
1

В примере выше, при клике на <button> будет вызываться метод increment.

Также можно вызвать метод непосредственно из шаблона. Как скоро увидим, обычно вместо метода лучше подходит вычисляемое свойство. Однако, использование метода может быть полезно в случаях, когда вычисляемые свойства не являются подходящим вариантом. Вызывать метод можно в любом месте, где шаблон поддерживает выражения JavaScript:

<span :title="toTitleDate(date)">
  {{ formatDate(date) }}
</span>
1
2
3

Если методы toTitleDate или formatDate обращаются к любым реактивным данным, то они будут отслеживаться как зависимости для отрисовки страницы, как если бы они были непосредственно использованы в шаблоне.

Методы, вызываемые из шаблона, не должны иметь побочных эффектов, таких как изменение данных или запуск асинхронных процессов. Если возникнет потребность сделать это, то скорее всего в этом случае лучше подойдёт использование хуков жизненного цикла.

# Реализация debounce и throttle

Vue не предоставляет встроенной поддержки для debounce или throttle, но её легко можно реализовать с помощью сторонних библиотек, таких как Lodash (opens new window).

Когда компонент используется только один раз, можно реализовать debounce непосредственно в самих methods:

<script src="https://unpkg.com/[email protected]/lodash.min.js"></script>
<script>
  Vue.createApp({
    methods: {
      // debounce с помощью Lodash
      click: _.debounce(function() {
        // ... обработка клика ...
      }, 500)
    }
  }).mount('#app')
</script>
1
2
3
4
5
6
7
8
9
10
11

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

app.component('save-button', {
  created() {
    // debounce с помощью Lodash
    this.debouncedClick = _.debounce(this.click, 500)
  },
  unmounted() {
    // Остановка таймера при уничтожении компонента
    this.debouncedClick.cancel()
  },
  methods: {
    click() {
      // ... обработка клика ...
    }
  },
  template: `
    <button @click="debouncedClick">
      Save
    </button>
  `
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Deployed on Netlify.
Последнее обновление: 2020-10-04, 19:13:46 UTC