metheds
先上一段代码,这段代码里有两个变量 counter和name,分别使用按钮和输入框改变他们,通过插值表达式显示它们。
<div id="app">
<button v-on:click="add">add</button>
<p>{{ counter }}</p>
<input v-model="name">
<p>{{ getFullname() }}</p>
</div>
<script>
const app = Vue.createApp({
data() {
return {
name: '',
counter: 0
}
},
methods: {
getFullname() {
console.log('getFullname...')
if (this.name) {
return this.name + 'WU'
}
return ''
},
add() {
this.counter ++
}
}
})
app.mount('#app')
</script>
在使用name的时候使用了方法拼接一个字符串用于显示,可以起到我们输入的同时改变显示的内容。 但是当我们点击按钮改变counter的时候,控制台依旧在输出 getFullname...
总结一下:
当在data中定义且在页面中使用了的变量发生改变时,这个页面上的非事件绑定的渲染相关方法都会被重新调用。
因为vue不知道这些方法的内部有没有用到改变的data,都会去执行一遍,所以一些需要动态计算的值使用metheds会影响性能。
computed
当我们使用computed时,就可以避一些性能消耗了,当我们再次点击按钮改变counter的时候,不会再执行fullname这个计算属性,因为vue会找到这个计算属性的依赖值,在这个例子中是name,只有name的值发生改变的时候,才会重新执行fullname。
<div id="app">
...
<p>{{ fullname }}</p>
</div>
<script>
const app = Vue.createApp({
data() {
...
},
computed: {
fullname() {
console.log('fullname...')
if (this.name) {
return this.name + 'WU'
}
return ''
},
},
methods: {
...
}
})
app.mount('#app')
</script>
watch
上述使用computed实现的效果利用watch也可以做到:
<div id="app">
...
<p>{{ fullname }}</p>
</div>
<script>
const app = Vue.createApp({
data() {
return {
name: '',
counter: 0,
fullname: ''
}
},
watch: {
// 将data或computed中的数据作为watch方法的名称
// 每次当name改变时,这个watch都会被重新执行
// watch方法接收两个参数,第一个参数是依赖项的最新值,第二个参数是依赖项先前的值
name(value, oldValue) {
console.log('name...')
// 参数value就是this.name的最新值
if (value) {
this.fullname = value + 'WU'
}
}
},
methods: {
...
}
})
app.mount('#app')
</script>
当一个值的改变依赖多个data时,使用watch就需要多个方法,分别监听不同的数据。
虽然一个功能使用了三种写法,但是上面的案例,最好的用法还是使用computed。
比较一下~
methods可以被使用在模板中绑定数据也可以用于事件绑定。但是当methods被使用在模板中绑定数据时,任意用于页面的data的改变,都会触发methods的重新执行。
computed只用于数据绑定,适合生成基于其他数据的数据,它们只会在依赖项改变时重新执行。
watch不直接使用在模板中,用于响应一些更改数据的代码,比如发生请求/设置定时器/本地存储...,所以应该使用watch做一些非数据更新的事情。