什么是计算属性
概念
计算属性是vue里面为了简化在模板语法中对响应式属性做计算而存在的
什么时候应该使用计算属性
根据现有响应式的值得到一个新的值
计算属性怎么使用
vue3之前是使用选项式 api【Options API】的,vue3之后使用了组合式api【Composition API】
在选项式api中
<script>
export default {
data() {
return {
author: {
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
}
}
},
computed: {
publishedBooksMessage() {
return this.author.books.length > 0 ? 'Yes' : 'No'
}
}
}
</script>
<template>
<p>Has published books:</p>
<span>{{ publishedBooksMessage }}</span>
</template>
在组合式api中
1. 使用setup语法糖
<script setup>
import { reactive, computed } from 'vue'
const author = reactive({
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
})
// a computed ref
const publishedBooksMessage = computed(() => {
return author.books.length > 0 ? 'Yes' : 'No'
})
</script>
<template>
<p>Has published books:</p>
<span>{{ publishedBooksMessage }}</span>
</template>
2. 使用setup方法
和其他的属性一样需要return暴露出来才可以使用
或者直接写在return返回对象中
<script>
import {reactive, computed } from 'vue'
export default {
setup(){
const author = reactive({
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
})
return{
author,
publishedBooksMessage:computed(() => {
return author.books.length > 0 ? 'Yes' : 'No'
})
}
},
mounted() {
console.log(this.count) // 0
}
}
</script>
<template>
<p>Has published books:</p>
<span>{{ publishedBooksMessage }}</span>
</template>
计算属性与xxx的区别
计算属性vs方法
计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值
<script setup>
import { reactive, computed } from 'vue'
const author = reactive({
name: 'Foo Bar',
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
})
// a computed ref
const publishedBooksMessage = computed(() => {
console.log("触发计算属性")
return author.books.length > 0 ? 'Yes' : 'No'
})
function set(){
console.log("触发set方法")
return author.books.length > 0 ? 'Yes' : 'No'
}
function add(){
author.books.push("book")
}
</script>
<template>
<p>Has published books:</p>
<p>
计算属性
</p>
<p>{{ publishedBooksMessage }}</p>
<p>{{ publishedBooksMessage }}</p>
<p>{{ publishedBooksMessage }}</p>
<p>
方法
</p>
<p>{{ set() }}</p>
<p>{{ set() }}</p>
<p>{{ set() }}</p>
<button @click="add">
添加
</button>
</template>
计算属性vs监听器
计算属性可以监听多个属性的变化,选项式api中watch只可以一个一个的监听
watch没有返回值
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
计算属性有哪些特性
- 看起来像一个方法,其实它是一个属性
使用时不能在后面加()
- 必须有返回值
必须有return
- 命名不能与其他属性重复
我怎么知道你要使用哪个
- 计算属性是有缓存的
依赖的值没有改变时就不进行计算,直接返回缓存的值
- 计算属性是基于它们的响应式依赖进行缓存的
不是响应式的就不管
- 不能直接对计算属性进行修改
要使用get,set方法
计算属性的注意事项
不能直接修改计算属性,只能通过改变它所依赖的响应式属性来改变它
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]
}
}
}
<script setup>
import { reactive, computed } from 'vue'
const author = reactive({
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
})
// a computed ref
const publishedBooksMessage = computed(() => {
return author.books.length > 0 ? 'Yes' : 'No'
})
function set(){
publishedBooksMessage.value = "123314" // 计算属性返回的是一个ref所以要改变它需要.value
// 提示 about:srcdoc:160 Write operation failed: computed value is readonly
}
</script>
<template>
<p>Has published books:</p>
<span>{{ publishedBooksMessage }}</span>
<button @click="set">
点击
</button>
</template>
不要在里面修改dom
不要在里面做异步请求
因为有缓存,很多时候的是直接返回缓存的值,从而不执行dom操作和异步请求,这样会导致许多的bug出现