方法 methods
- 每次渲染都会执行一次
- 事件处理函数或普通函数
- 事件处理函数:若把函数写在 method 外,则会报错:[函数] is not defined
- 普通函数:可代替 filters
new Vue({
data() {
return {
n:0,
array: [1, 2, 3, 4]
}
},
template:`
<div>
{{n}}
<button @click="add"> +1 </button>
<br>
{{ filter() }}
</div>
`,
methods: {
add() {
this.n += 1
},
// methods 方法每次渲染都会执行一次,因此点击 +1 button, add 与 filter 方法都会执行
filter() {
return this.array.filter(i => i % 2 === 0)
}
}
})
计算属性 computed
- vue 的计算选项,用于存放计算出来的属性
- 根据依赖是否变化来缓存
- getter/setter 默认不做缓存,Vue 做了特殊处理
实现字符串反转功能:
<div id="app">
<p>
Original message: "{{ message }}"
</p>
<p>
Reversed message: "{{ reverseMessage }}"
</p>
</div>
var vm = new Vue({
el: '#app',
data: {
message: 'Hi'
},
computed: {
// 作用于 vm.reverseMessage 的 getter 函数
reverseMessage: function() {
return this.message.split(''.reverse().join(''))
}
}
})
console.log(vm.reverseMessage) // "iH"
// vm.reverseMessage 的值依赖于 vm.message
// vm.message 发生改变时,vm.reverseMessage才发生变化
vm.message = 'Ha'
console.log(vm.reverseMessage) // "aH"
也可以通过方法实现同样功能:
<p>
{{reverseMessage}}
</p>
methods:{
reverseMessage: function(){
return this.message.split('').reverse().join('')
}
}
计算属性的 setter
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
computed: {
fullName: {
// getter
get: function(){
return this.firstName + ' ' + this.lastName
},
// setter
set: function(newValue){
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
})
vm.fullName = 'John Doe'
console.log(vm.firstName, vm.lastName)
监听属性 watch
- 监听的数据改变就执行回调
- Vue 实例将会在实例化时调用
$watch()
,遍历 watch 对象的每一个 property - 类型:
{ [key: string]: string | Function | Object | Array }
- watch 是异步的
- 默认第一次变化不监听,若要监听,加上
immediate: true
- 监听数据变化:默认只监听栈内存中的数据,若要监听堆内存数据,加上
deep: true
- 不使用箭头函数,箭头函数中得 this 指向全局对象;function 中的 this 默认指向当前 Vue 实例
语法1:
var vm = new Vue({
data: {
a: 1,
b: 2,
c: 3,
d: 4,
e: {
f: {
g: 5
}
}
},
watch: {
a: function (newVal, oldVal) {
console.log('new: %s, old: %s', newVal, oldVal)
},
// 方法名
b: 'someMethod',
// 该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深
c: {
handler: function (val, oldVal) { /* ... */ },
deep: true
},
// 该回调将会在侦听开始之后被立即调用
d: {
handler: 'someMethod',
immediate: true
},
// 你可以传入回调数组,它们会被逐一调用
e: [
'handle1',
function handle2 (val, oldVal) { /* ... */ },
{
handler: function handle3 (val, oldVal) { /* ... */ },
/* ... */
}
],
// watch vm.e.f's value: {g: 5}
'e.f': function (val, oldVal) { /* ... */ }
}
})
vm.a = 2 // => new: 2, old: 1
语法2:vm.$watch('data', fn, {deep: true, immediate: true})
data
可以
new Vue({
data: {
n: 0
}
created(){
this.$watch('n', function(){
console.log('n 变了')
}, {immediate: true})
}
}).$mount("#app")
三者的区别
- computed:计算属性,将计算结果进行缓存,只有在它的响应式依赖改变时才会重新计算,不支持异步
- methods:方法, 在每次触发重新渲染时都会执行函数,开销更大,支持异步
- watch: 监听属性,当监听的 data 改变就执行回调,有两个选项:deep 与 immediate,支持异步