组合式API的使用
为什么要用组合式API
传统的选项式API,数据定义到data里,方法定义到methods里,不同的东西定义在不同的节点上,当代码量多的时候,代码可读性就变差了。而组合式API可以将一个业务逻辑写在一起,易于阅读与维护。
setup函数
setup()函数是组合式API的核心,它接收两个参数
- props: 一个响应式的props对象,包含了所有传递给组件的属性
- 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>