深入理解 Vue 3 的 Composition API 与新特性

Composition API

setup

setup函数是Composition API(组合API)的入口。

setup执行时机是在beforeCreate之前执行。

setup函数中定义的变量和方法最后都是需要return出去的,不然无法在模板中使用。

setup里面是不会用到this的。

setup中接收的props是响应式的,当传入新的props时,会及时被更新。由于是响应式的,所以不可以使用ES6解构,解构会消除它的响应式的。setup接收的context中提供了最常用的四个属性:attrsslotemit,分别对应Vue@2.x中的$attr属性、slot插槽、$emit发射事件和expose暴露标记。并且这四个属性都是自动同步最新的值,所以我们每次使用拿到的都是最新值。

expose:在传统的写法中,可以在父组件中,通过ref实例的方式去访问子组件的内容,但在<script setup>中,setup相当于一个闭包,除了内部的template模板,都无法访问内部的数据和方法。如果需要对外暴露setup中的数据和方法,需要使用此属性。

<template>
   <h1>App</h1>
   <h2>{
  
  { age }}</h2>
</template>
<script>
import {
     
      defineComponent, ref } from "vue"
export default defineComponent({
     
     
  name: 'App',
  props: {
     
     
    name: String
  },
  setup(props, context) {
     
     
    let age = ref(18)
    function say() {
     
     
      console.log(`${ 
       age.value}`)
    }
    //返回一个对象
    return {
     
     
      age,
      say
    }
  }
})
</script>

如果上面这种return的写法不喜欢的话,可以用新的语法糖<script setup><script setup>就相当于在编译运行时把代码放到setup函数中运行,然后把导出的变量定义到上下文中,并包含在返回的对象中。

<script setup>中,引入的组件可以直接使用,无需再通过components进行注册,并且无法指定当前组件的名字,它会自动以文件名为主,也就无需再写name属性。

使用props

通过defineProps指定当前props类型,获得上下文的props对象。

使用emits

使用defineEmits定义当前组件含有的事件,并通过返回的上下文去执行emit

使用slotsattrs

<script setup>中使用slotsattrs,分别使用useSlotsuseAttrs帮助函数。

使用expose

使用defineExpose暴露需要对外的数据和方法。

<template>
   <Child />
</template>
<script setup>
import Child from './Child.vue'
import {
     
      ref, defineEmits, defineExpose, defineProps, useSlots, useAttrs } from 'vue'
    
let age = ref(18)
const props = defineProps({
     
     
  name: String
})
const emits = defineEmits(['add', 'delete')
const slots = useSlots()
const attrs = useAttrs()
defineExpose({
     
     
    age,
    say
})
const say = () => {
     
     
  console.log(`${ 
       age.value}`)
}
</script>

Vue@2.6.x开始,Vue 为具名和范围插槽引入了一个全新的语法,即v-slot 指令。目的就是想统一 slotscope-slot 语法,使代码更加规范和清晰。在 vue@3.x中,只能使用v-slot

reactivereftoRefstoRef

vue@3.x使用reactiveref来进行响应式数据定义。

ref

使用ref定义的变量变成了对象,并且还是RefImpl的实例对象。所以在修改的时候要用.value去修改,因为内部是按照getset去修改页面的。但是在template中就不用自己手动添加.value,因为vue@3.x在检测到是ref对象,就自动添加了.value。如果用ref定义对象,则不再是RefImpl实例对象,变成了Proxy实例对象,因为在vue@3.x底层,如果是对象,就变成Proxy实例对象,对于基本数据类型就按照Object.defineProperty里面的getset进行数据劫持然后进行响应式,但是如果是对象类型的话,是用Proxy,就相当于,ref中是对象,自动会调用reactive

reactive

reactive只能定义对象类型的响应式数据,把Object转换为Proxy,进行一个深层次的响应式,也可以进行数组的响应式。

refreactive的区别
  • ref用来定义基本数据类型,也可以定义对象或数组,知识内部自动调用了reactive来转换。
  • ref通过Object.defineProperty()getset来实现响应式(数据劫持)。
  • ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value
  • reactive用来定义:对象或数组类型数据
  • reactive通过使用Proxy来实现响应式(数据代理),并通过Reflect操作源代码内部的数据。
  • reactive定义的数据:操作和读取数据均不需要.value
toRefs

toRefs用于将一个reactiv

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一点一木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值