组合式API的使用

288 阅读2分钟

组合式API的使用

为什么要用组合式API

传统的选项式API,数据定义到data里,方法定义到methods里,不同的东西定义在不同的节点上,当代码量多的时候,代码可读性就变差了。而组合式API可以将一个业务逻辑写在一起,易于阅读与维护。

setup函数

setup()函数是组合式API的核心,它接收两个参数

  1. props: 一个响应式的props对象,包含了所有传递给组件的属性
  2. context: 包含了当前组件的上下文信息,例如"attrs"、 “slots”、 “emit"等

它其实是vue3里一个新的生命周期钩子函数,执行还要在beforeCreated之

(因此,它不可以调用外面定义的data,methods的),通过返回方法响应式的数据对象,定义对应的数据源和方法。

context解析

const {attrs, slots, emits} = context

attrs 是父组件传递给子组件的,但没有在子组件的props中定义的属性的集合,可以通过attrs.xxx调用

slots是插槽, 可以通过slots.default() 访问父组件通过默认插槽传递的内容

<setup setup></srcipt> 里使用

import {useSlots, useAttrs}  // defineProps和defineEmits不需要导入
const props = defineProps({
    name: String
})
const change = defineEmits(["change","delete"]);
const slots = useSlots()
const attrs = useAttrs()

使用

导入

import { ref, reative, toRefs, toRef, computed, watch, readonly, onCreated, onMounted, onUpdated, nextTick, provide, inject, h}
  • ref():定义响应式的基本数据类型

    let name = ref("大熊");             // ref()对数据进行了一个包装 proxy({ value: "大熊" })
    setTimout(()=>{
        name.value = "橘子"             // 修改name的值,必须通过name.value修改
    }, 2000);
    return { name };
    
  • reative: 定义响应式的复杂数据类型

    // 对象
    let nameObj = reative({ name: "大熊" });  // proxy({name: "大熊"})
    setTimeout(()=>{
        nameObj.name = "橘子";
    }, 2000)
    return { nameObj };
    ​
    //数组: 数组也可以用ref包装的
    let nameArr = reative(["大熊"]);  // proxy(["大熊"])
    setTimeout(()=>{
        nameArr[0] = "橘子";
    }, 2000)
    return { nameArr };
    
  • toRefs,toRef 从对象解构出响应式的数据

    toRefs解构响应式对象;

    toRef除了解构响应式对象,还可以解构普通对象,,不过要指定属性名称。

    const nameObj = reative({ name: "大熊" });
    const { name } = toRefs(nameObj);
    const { name } = toRef(nameObj, "name");
    
  • computed, 定义计算属性

    const count = ref(5);
    const count2 = computed(() => {
      return count.value + 5;
    })
    console.log(count2.value)
    
  • 侦听器的使用

    watch(name,(newVal, oldVal)=>{
        console.log(newVal);
    })
    ​
    // 如果是响应式的对象属性
    watch(()=> nameObj.name, (newVal,oldVal)=>{
        console.log(newVal);    
    })
    // 一次建监听多个数据
    watch([()=> nameObj.name, ()=> nameObj.englishName], ([newVal1,newVal2],[oldVal1, oldVal2])=>{
        console.log(newVal1)
        console.log(oldVal2)
    })
    ​
    // watchEffect 自动监听跟踪的数据,但不能获取之前的值
    watchEffect(() => {
      console.log(count: ${count.value});
    });
    
  • 生命周期函数

    // 传入函数作为生命周期钩子函数
    onBeforeMount(()=>{
        console.log('xxx')
    })
    onMounted(()=>{
        console.log('xxx')
    })
    onBeforeUpdate(()=>{
        console.log('xxx')
    })
    onUpdated(()=>{
        console.log('xxx')
    })
    onBeforeUnmount(()=>{
        console.log('xxx')
    })
    onUnmounted(()=>{
        console.log('xxx')
    })
    
  • provide和inject : 这是vue3新提供的API,可以在多重嵌套的父子组件间传递信息

    // 父组件
    const name = ref("大熊")
    provide("name", readonly(name));  // 如果不希望子组件改变name,可以用readonly
    ​
    ​
    // 子组件
    const name = inject("name")
    
  • ref获取DOM节点

    <template>
        <div ref="hello">hello</div>
    </template><script setup>
        // 属性名和ref值一致,ref传入null,就可以获得DOM节点
        import ref from 'vue'
        const hello = ref(null)               
        return {
            ref
        }
    </script>