Docs
Vue (读音 /vjuː/,类似于view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。
深入响应性原理
响应性是一种允许我们以声明式的方式去适应变化的一种编程范例
当把一个普通的 JavaScript 对象作为data选项传给应用或组件实例的时候,Vue 会使用带有 getter 和 setter 的处理程序遍历其所有 property 并将其转换为Proxy。这是 ES6 仅有的特性,但是我们在 Vue 3 版本也使用了Object.defineProperty来支持 IE 浏览器。
声明响应式状态
import { reactive } from 'vue'
// 响应式状态
const state = reactive({ count: 0 })
创建独立的响应式值作为 refs
import { ref } from 'vue'
const count = ref(0)
console.log(count.value)
// 0
count.value++ console.log(count.value)
// 1
响应式状态解构
当我们想使用大型响应式对象的一些 property 时,可能很想使用ES6 解构来获取我们想要的 property,遗憾的是,使用解构的两个 property 的响应式都会丢失。对于这种情况,我们需要将我们的响应式对象转换为一组 ref。这些 ref 将保留与源对象的响应式关联:
import { reactive, toRefs } from 'vue'
const book = reactive({
author: 'Vue Team',
year: '2020',
title: 'Vue 3 Guide',
description: 'You are reading this book right now ;)',
price: 'free'
})
let { author, title } = toRefs(book)
title.value = 'Vue 3 Detailed Guide' // 我们需要使用 .value 作为标题,现在是 ref console.log(book.title) // 'Vue 3 Detailed Guide'
使用 readonly 防止更改响应式对象
有时我们想跟踪响应式对象 (ref或reactive) 的变化,但我们也希望防止在应用程序的某个位置更改它。例如,当我们有一个被provide的响应式对象时,我们不想让它在注入的时候被改变。为此,我们可以基于原始对象创建一个只读的 Proxy 对象:
import { reactive, readonly } from 'vue'
const original = reactive({ count: 0 })
const copy = readonly(original) // 在copy上转换original 会触发侦听器依赖
original.count++ // 转换copy 将导失败并导致警告
copy.count++ // 警告: "Set operation on key 'count' failed: target is readonly."
响应式计算和侦听
有时我们需要依赖于其他状态的状态——在 Vue 中,这是用组件计算属性处理的,以直接创建计算值,我们可以使用computed方法:它接受 getter 函数并为 getter 返回的值返回一个不可变的响应式ref对象。
const count = ref(1)
const plusOne = computed(() => count.value++)
console.log(plusOne.value) // 2
plusOne.value++ // error
或者,它可以使用一个带有get和set函数的对象来创建一个可写的 ref 对象。
const count = ref(1)
const plusOne = computed({
get: () => count.value + 1,
set: val => {
count.value = val - 1
}
})
plusOne.value = 1 console.log(count.value) // 0
watchEffect
为了根据反应状态自动应用和重新应用副作用,我们可以使用watchEffect方法。它立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数。
const count = ref(0)
watchEffect(() => console.log(count.value)) // -> logs 0
setTimeout(() => {
count.value++ // -> logs 1
}, 100)
停止监听
当watchEffect在组件的setup()函数或生命周期钩子被调用时,侦听器会被链接到该组件的生命周期,并在组件卸载时自动停止。
在一些情况下,也可以显式调用返回值以停止侦听:
const stop = watchEffect(
() => { /* ... */ }
)
// later
stop()