[TOC]
# Methods
A Vue method is a function associated with the Vue instance. Methods are defined inside the `methods` property. Let's see how they work.
- [What are Vue.js methods](#what-are-vuejs-methods)
- [Pass parameters to Vue.js methods](#pass-parameters-to-vuejs-methods)
- [How to access data from a method](#how-to-access-data-from-a-method)
- - - - - -
## 什么是 Vue.js 的方法
Vue 方法是与 Vue 实例相关联的函数。它们定义在 `methods` 属性中:
```
new Vue({
methods: {
handleClick: function() {
alert('test')
}
}
})
```
单文件组件中:
```
<script>
export default {
methods: {
handleClick: function() {
alert('test')
}
}
}
</script>
```
Methods are especially useful when you need to perform an action and you attach a `v-on` directive on an element to handle **events**. Like this one, which calls `handleClick` when the element is clicked:
```
<template>
<a @click="handleClick">Click me!</a>
</template>
```
## Pass parameters to Vue.js methods
Methods can accept parameters.
In this case, you just pass the parameter in the template, and you
```
<template>
<a @click="handleClick('something')">Click me!</a>
</template>
```
```
new Vue({
methods: {
handleClick: function(text) {
alert(text)
}
}
})
```
or in the case of Single File Components:
```
<script>
export default {
methods: {
handleClick: function(text) {
alert(text)
}
}
}
</script>
```
## You can access any of the data properties of the Vue component by using `this.propertyName`:
```
<template>
<a @click="handleClick()">Click me!</a>
</template>
<script>
export default {
data() {
return {
name: 'Flavio'
}
},
methods: {
handleClick: function() {
console.log(this.name)
}
}
}
</script>
```
We don't have to use `this.data.name`, just `this.name`. Vue does provide a transparent binding for us. Using `this.data.name` will raise an error.
As you saw before in the events description, methods are closely interlinked to events, because they are used as event handlers. Every time an event occurs, that method is called.
# Watchers(监听器)
A Vue watcher allows you to listen to the component data and run whenever a particular property changes
A watcher is a special Vue.js feature that allows you to spy on one property of the component state, and run a function when that property value changes.
Here's an example. We have a component that shows a name, and allows you to change it by clicking a button:
```
<template>
<p>My name is {{name}}</p>
<button @click="changeName()">Change my name!</button>
</template>
<script>
export default {
data() {
return {
name: 'Flavio'
}
},
methods: {
changeName: function() {
this.name = 'Flavius'
}
}
}
</script>
```
When the name changes we want to do something, like printing a console log.
We can do so by adding to the `watch` object a property named as the data property we want to watch over:
```
<script>
export default {
data() {
return {
name: 'Flavio'
}
},
methods: {
changeName: function() {
this.name = 'Flavius'
}
},
watch: {
name: function() {
console.log(this.name)
}
}
}
</script>
```
The function assigned to `watch.name` can optionally accept 2 parameters. The first is the new property value. The second is the old property value:
```
<script>
export default {
/* ... */
watch: {
name: function(newValue, oldValue) {
console.log(newValue, oldValue)
}
}
}
</script>
```
Watchers cannot be looked up from a template as you can with computed properties.
# Computed Properties(计算属性)
## 什么是计算属性
In Vue.js you can output any data value using parentheses:
```
<template>
<p>{{ count }}</p>
</template>
<script>
export default {
data() {
return {
count: 1
}
}
}
</script>
```
This property can host some small computations, for example
```
<template>
{{ count * 10 }}
</template>
```
but you're limited to a single JavaScript *expression*.
In addition to this technical limitation, you also need to consider that templates should only be concerned with displaying data to the user, not perform logic computations.
To do something more a single expression, and to have more declarative templates, that you use a **computed property**.
Computed properties are defined in the `computed` property of the Vue component:
```
<script>
export default {
computed: {
}
}
</script>
```
## 计算属性示例
Here's an example code that uses a computed property `count` to calculate the output. Notice:
I didn't have to call
```
{{ count() }}
```
Also, I used a regular function (not an arrow function) to define the `count` computed property because I need to be able to access the component instance through `this`.
```
<template>
<p>{{ count }}</p>
</template>
<script>
export default {
data() {
return {
items: [1, 2, 3]
}
},
computed: {
count: function() {
return 'The count is ' + this.items.length * 10
}
}
}
</script>
```
## Computed properties vs methods
If you already know [Vue methods](../vue-methods), you may wonder what's the difference.
First, methods must be called, not just referenced, so you'd need to do:
```
<template>
<p>{{ count() }}</p>
</template>
<script>
export default {
data() {
return {
items: [1, 2, 3]
}
},
methods: {
count: function() {
return 'The count is ' + this.items.length * 10
}
}
}
</script>
```
But the main difference is that **computed properties are cached**.
The result of the `count` computed property is internally cached until the `items` data property changes.
Important: computed properties are **only updated when a reactive source updates**. Regular JavaScript methods are not reactive, so a common example is to use `Date.now()`:
```
<template>
<p>{{ now }}</p>
</template>
<script>
export default {
computed: {
now: function () {
return Date.now()
}
}
}
</script>
```
It will render once, and then it will not be updated even when the component re-renders. Just on a page refresh, when the Vue component is quit and reinitialized.
In this case a method is better suited for your needs.
# 三者对比
## 何时使用 methods
- To react on some event happening in the DOM
- To call a function when something happens in your component. You can call a methods from computed properties or watchers.
## 何时使用 computed properties
- You need to compose new data from existing data sources
- You have a variable you use in your template that's built from one or more data properties
- You want to reduce a complicated, nested property name to a more readable and easy to use one, yet update it when the original property changes
- You need to reference a value from the template. In this case, creating a computed property is the best thing because it's cached.
- You need to listen to changes of more than one data property
## 何时使用 watchers
- You want to listen when a data property changes, and perform some action
- You want to listen to a prop value change
- You only need to listen to one specific property (you can't watch multiple properties at the same time)
- You want to watch a data property until it reaches some specific value and then do something
- Introduction
- Introduction to Vue
- Vue First App
- DevTools
- Configuring VS Code for Vue Development
- Components
- Single File Components
- Templates
- Styling components using CSS
- Directives
- Events
- Methods vs Watchers vs Computed Properties
- Props
- Slots
- Vue CLI
- 兼容IE
- Vue Router
- Vuex
- 组件设计
- 组件之间的通信
- 预渲染技术
- Vue 中的动画
- FLIP
- lottie
- Unit test
- Vue3 新特性
- Composition API
- Reactivity
- 使用 typescript
- 知识点
- 附录
- 问题
- 源码解析
- 资源