vue3 组合式api速查笔记

响应式声明

ref()

  • 用来声明响应式状态,常用来包裹基础数据类型。也可以包裹层级不深的对象,script中使用时需要.value取值。
    import { ref } from 'vue' //引用
    const count = ref(0) //声明
    console.log(count.value) //在script中使用和修改实际值

reactive()

  • 用于包裹对象类型的数据,与ref不同,不需要.vlaue取值。注意:不能直接对该对象重新赋值(修改引用地址),可以使用Object.assign()方法修改属性值。
  • reactive中引用ref定义的数据时不需要.value获取实际值
    import { ref, reactive } from 'vue' //引用
    const count = ref(1)
    const state = reactive({ count: 0 })//声明
    console.log(state) //直接使用
    Object.assign(state, {count:1, status: 0}) //修改值

setup

  • 使用 <script setup> 语法糖来大幅度地简化代码,
  • 使用vite-plugin-vue-setup-extend插件快速设置组件的namespace
    <script setup name="ComponentName"> // setup + 组件namespace
    import { ref } from 'vue'
    
    const count = ref(0)
    
    function increment() {
      count.value++
    }
    </script>
    
    <template>
      <button @click="increment">
        {{ count }}
      </button>
    </template>

toReftoRefs

  • toRef将值、refs 或 getters 规范化为 refs。改变源属性的值将更新 ref 的值,反之亦然。
  • toRefs将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref。
    import { ref, reactive, toRef, toRefs } from 'vue'
    const state = reactive({ foo: 1, bar: 2 }) 
    // 双向 ref,会与源属性同步 
    const fooRef = toRef(state, 'foo') 
    // 更改该 ref 会更新源属性 
    fooRef.value++ console.log(state.foo) // 2 
    // 更改源属性也会更新该 ref 
    state.foo++ console.log(fooRef.value) // 3
    
    
    const state = reactive({ foo: 1, bar: 2 }) 
    // 可以解构而不会失去响应性 
    const { foo, bar } = toRefs(state)

computed()

  • 接受一个 getter 函数,返回一个只读的响应式 ref 对象。也可以接受一个带有 get 和 set 函数的对象来创建一个可写的 ref 对象。
  • 有缓存,只会在使用和依赖的数据更新时调用一次。
    import {ref, reactive, computed} from 'vue'
    // 只读 
    const count = ref(1)
    const plusOne = computed(() => count.value + 1)
    
    console.log(plusOne.value) // 2
    
    plusOne.value++ // 错误
    
    //可写
    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

watch()

  • 侦听一个或多个响应式数据源,并在数据源变化时调用所给的回调函数。
    1. 第一个参数:被监听的对象,可以传入一个函数或数组。
    2. 第二个参数:监听的回调。
    3. 第三个参数:配置对象(deep:深度监听,immediate:创建时立即触发回调…)。

一、ref定义的【基本类型】的数据。

import {ref, reactive, watch} from 'vue'
let name = ref('tom')
const stopWatch = watch(name, (newValue, oldValue)=>{
	console.log('name数据变化', newValue, oldValue)
	// 停止监视
	if (name == 'jack') {
		stopWatch()
	}
})

二、ref定义的【对象类型】的数据:直接写数据名,监听的是对象的地址值,若想监听对象内部的数据,要手动开启深度监听。

注意
- 若是修改ref定义的对象中的属性值,newValue和oldValue都是新值,因为他们都是同一个对象。
- 若修改整个ref定义的对象,newValue是新值,oldValue是旧值,因为不是同一个对象。

import {ref, reactive, watch} from 'vue'
let person = ref({name: 'tom'})
watch(person, (newValue, oldValue)=>{
	console.log('name数据变化', newValue, oldValue)
}, {deep: true}) //开启深度监听

三、reactive定义的【对象类型】数据,会默认开启深度监听

四、监听响应式对象中的某个树形,且该树形是基本类型,要写成函数式。

  • 监听的要是对象里的树形,最好写成函数式,注意点:若是对象监听的是地址值,需要关注对象内部,需要手动开启深度监听。
    import {ref, reactive, watch} from 'vue'
    let person = reactive({name: 'tom'})
    watch(()=>person.name, (newValue, oldValue)=>{
    	console.log('name数据变化', newValue, oldValue)
    }, {deep: true}) //开启深度监听

五、监视以上多个数据

import {ref, reactive, watch} from 'vue'
let person = ref({name: 'tom'})
let name = ref('tom')
watch([()=>person.name, name], (newValue, oldValue)=>{
	console.log('name数据变化', newValue, oldValue)
}, {deep: true}) //开启深度监听

watchEffect

  • 立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行
  • watch对比watchEffect
    1. 都能监听响应式数据的变化,但是监听数据变化的方式不同。
    2. watch: 要明确指出监听的数据
    3. watchEffect: 不用明确指出监听的数据(函数中用到哪些树形,那就监听哪些树形)。
    import {ref, reactive, watchEffect} from 'vue'
    let person = reactive({name: 'tom'})
    let name = ref('tom')
    watchEffect(()=>{
    	if (person.name===name.value) {
    		console.log('名称相同了')
    	}
    }) //开启深度监听

shallowRef() shallowReactive

  • shallowRef:ref() 的浅层作用形式。
  • shallowReactive:reactive() 的浅层作用形式。