Skip to content

响应式状态

声明 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 和 watch 的区别?

  • 触发时机
    • computed 是基于依赖的响应式数据变化而自动重新计算。
    • watch 是观察某个响应式数据的变化,并在变化时执行相应的回调函数。
  • 用途定位
    • computed 用于“从状态推导出新状态”(派生数据)。
    • watch 用于“监听状态变化并执行副作用”(如 API 请求、手动 DOM 操作)。
  • 返回值
    • computed 返回一个响应式引用,可以直接在模板中使用。
    • watch 没有返回值,主要用于执行副作用。

computed 需要同步返回

computedgetter 必须是同步的,不能包含异步操作。如果需要处理异步逻辑,应该使用 watchwatchEffect

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')

基于 MIT 许可发布