主题
响应式状态
声明 state
ref()
ref用于创建一个响应式对象,可以是任意类型。- 在 访问/修改 时,需要通过
.value访问/修改其值。不过在模板中可以直接使用,无需.value。
js
import { ref } from 'vue'
// 声明 state
const count = ref(0)
const increment = () => {
// 更新 state
count.value++
}reactive()
reactive用于创建一个响应式对象,通常是对象类型(object、array)。- 在 访问/修改 对象时,直接操作属性即可。
js
import { reactive } from 'vue'
// 声明 state
const state = reactive({
count: 0,
})
const increment = () => {
// 更新 state
state.count++
}shallowRef()
shallowRef用于创建一个浅响应式对象,只有第一层属性是响应式的。
适用于需要避免深层响应式开销的场景。
声明 computed
只读的
js
import { ref, computed } from 'vue'
const count = ref(10)
const doubleCount = computed(() => count.value * 2)可写的
js
import { ref, computed } from 'vue'
const firstName = ref('John')
const lastName = ref('Doe')
const fullName = computed({
// getter
get() {
return firstName.value + ' ' + lastName.value
},
// setter
set(newValue) {
const names = newValue.split(' ')
firstName.value = names[0] || ''
lastName.value = names[1] || ''
},
})获取上一个值 v3.4.0+
js
import { ref, computed } from 'vue'
const count = ref(2)
const alwaysSmall = computed((previous) => {
if (count.value <= 3) {
return count.value
}
return previous
})js
import { ref, computed } from 'vue'
const count = ref(2)
const alwaysSmall = computed({
get(previous) {
if (count.value <= 3) {
return count.value
}
return previous
},
set(newValue) {
count.value = newValue * 2
},
})常见问题
computed 和 methods 的区别?
- 是否缓存
- computed 会基于依赖缓存,只有依赖变更才重新计算。
- methods 不缓存,渲染时每次调用都会重新执行。
- 用途定位
- computed 用于“从状态推导出新状态”(派生数据)。
- methods 用于“做事”(事件处理/命令式操作),也可做计算但不推荐放到模板里当派生数据。
- 是否支持参数
- computed 不接收参数(依赖来自其内部访问的响应式变量)。
- methods 可接收参数。
- 是否适合副作用
- computed 应该是纯函数(无副作用、同步)。
- methods 可包含副作用(例如发请求、修改状态)。
- 模板使用方式
- computed 在模板中当属性使用:
fullName(无括号)。 - methods 在模板中是函数调用:
calcPrice(qty)(有括号)。
- computed 在模板中当属性使用:
computed 和 watch 的区别?
- 触发时机
- computed 是基于依赖的响应式数据变化而自动重新计算。
- watch 是观察某个响应式数据的变化,并在变化时执行相应的回调函数。
- 用途定位
- computed 用于“从状态推导出新状态”(派生数据)。
- watch 用于“监听状态变化并执行副作用”(如 API 请求、手动 DOM 操作)。
- 返回值
- computed 返回一个响应式引用,可以直接在模板中使用。
- watch 没有返回值,主要用于执行副作用。
computed 需要同步返回
computed 的 getter 必须是同步的,不能包含异步操作。如果需要处理异步逻辑,应该使用 watch 或 watchEffect。
computed 支持传参?
计算属性不能直接传参,但是可以通过返回一个函数来进行间接传参。
注意,此时仅会缓存函数本身,而不会缓存函数的返回值。
js
import { ref, computed } from 'vue'
const items = ref(['apple', 'banana', 'avocado'])
const filtered = computed(() => {
return (term) => items.value.filter((i) => i.includes(term))
})
// 使用: filtered.value('a')