前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >初识 vue3的Composition API

初识 vue3的Composition API

原创
作者头像
前端车神
发布2024-07-01 20:18:27
1280
发布2024-07-01 20:18:27

什么是 Composition API?

Composition API 也叫组合式API, 是在vue3中新引入的一种API,vue2中已经有option API了,那为什么要新稿这么一套呢,其实主要原因是要解决vue2中的option API的在处理复杂组件逻辑的局限性,例如逻辑分散、代码复用性差、类型推断困难、组件组织混乱、响应式系统限制、模板逻辑复杂性、组件测试困难等问题。为此Composition API通过函数的方式来组织代码,使得逻辑更加模块化和可组合,这就变得很灵活。

核心概念

setup 函数

setup 是使用组合式API的入口函数,用于替代vue2中的data、computed 、methods等选项,setup函数参数为(props, context)props可以理解为vue2中的props属性,用来访问父级传来的参数值。

context 则是一个对象集合包括:

  • attrs:包含了父组件传递给子组件的所有属性(非prop的属性),它们是响应式的,可以动态地绑定到模板中。
  • slots:包含了所有传入的插槽内容,这些内容可以用于渲染作用域插槽。
  • emit:是一个函数,用于向父组件发出自定义事件。它是this.\$emit的替代。
  • expose:是一个函数,用于显式地暴露子组件内部的属性或方法,使得父组件可以通过ref访问到这些属性或方法。

setup声明方式有两种语法方式

第一种

代码语言:javascript
复制
<script>
export default {
  props: {
    msg: String
  },
  setup(props) {
    console.log('setup',props.msg)
  }
}
</script>

第二种 更简洁 官方称为更符合人体工程学

但 props 要更改写法,使用defineProps,放心虽然没有声明,但它将自动在setup 中可用

代码语言:javascript
复制
<script setup>
defineProps({
  msg: String,
})
</script>

核心api

ref

ref 用于创建一个可修改的响应式的基本数据类型或引用(可以对 .value 赋值来进行修改, 如果将一个对象赋值给 ref,那这个对象则通过 reactive 转化为深层次响应式的数据),

如果这个对象中存在ref也会被深层解包,为避免这种深层次的转化,官方建议用 shallowRef替代

使用方法

代码语言:javascript
复制
// .vue
<template>
  <h1>{{age}}</h1>
</template>
<script setup>
import { ref } from 'vue'

let age = ref(18)

age.value = 20
</script>

reactive

reactive 用于创建一个响应式对象。有一点需要注意,当访问到某个响应式数组或 Map 这样的原生集合类型中的 ref 元素时,不会执行 ref 的解包。

只有当你直接访问这个ref内部的值时,比如使用.value属性,Vue才会“解包”这个ref,把它内部的值当作响应式值进行追踪。

这样做的好处是提高了性能,避免了不必要的响应式转换,因为在某些情况下,你可能并不需要数组或Map中的每个ref元素都是响应式的。

所以要避免深层响应式的转换,只想保留对这个对象顶层次访问的响应式,可以用shallowReactive做为替代

代码语言:javascript
复制
import { ref, reactive } from 'vue'
let age = ref(18)
let obj = reactive(['123',age])

// 直接访问数组中的 obj 元素,不会执行解包
console.log(obj[1]);  // 输出是 ref 对象本身,而不是 18

// 要获取 obj 中的值,需要使用.value
console.log(obj[1].value);  // 输出 18

</script>

readonly

readonly和 reacitve 类似,只不过从字面意义上就不难理解,only 它是只读的,而且代理是深层的,所以同理要避免深层层级的转换行为,可以用shallowReadonly 来替代

代码语言:javascript
复制
...
<!--19-->
<div>{{ man.age }}</div> 
<!--19-->
<div>{{ man2.age }}</div>
<!--20-->
<div>{{ man3.age }}</div>
...
import { reactive, ref, readonly, watchEffect } from 'vue'
...
let man = reactive({ age: 18 })

let man2 = readonly(man)

let man3 = readonly({age: 20})
watchEffect(() => {
  // 用来做响应性追踪
  console.log(man.age)
})

// 会触发 watchEffect
man.age++

// 下面man2和man3的操作会执行失败而且会触发警告
// Set operation on key "age" failed: target is readonly.
man2.age++

man3.age++

computed、watch

computed、watch和vue2中的含义相同

computed用法

代码语言:javascript
复制
...
<h1 @click="count ++">{{ addCount }}</h1>
...
import { ref, reactive } from 'vue'
...


let count = ref(1)
const addCount = computed(() => count.value + 1)
// addCount.value++  // 错误写法,因为addCount是只读的 会报错

watch 默认懒监听: 仅在监听源发生变化时才执行回调函数

watch一共三个参数,watch(source,callback,options)

  • source: 这个参数是要侦听的响应式引用或响应式对象的属性,或者是返回响应式值的getter函数。 可以是 ref、reactive 对象、computed 计算属性或者一个自定义的getter函数。
  • callback:当侦听的源发生变化时会被调用的回调函数。这个函数接收三个参数:新值、旧值和onCleanup函数。onCleanup可以用来注册清理回调,在下次侦听器执行前会被调用。
  • options (可选): 包含配置选项json对象
    • immediate: 值为true,会在侦听器创建时立即执行回调。
    • deep: 值为true 会深度监听对象内部的变化。
    • flush: 指定回调函数的执行时机
      • post (默认值): 侦听器回调会在 DOM 更新之后执行。
      • pre: 与post相反,表示侦听器回调会在 DOM更新之前执行 的更新。这个选项适用于需要在 DOM 更新之前访问旧 DOM 的场景。
      • sync: 表示侦听器回调会在数据变化时立即同步执行。这通常会导致更高的性能开销,因为它会阻止其他任务的执行,直到侦听器回调完成。这个选项适用于需要立即响应数据变化,并且变化不频繁的场景。
    • onCleanup: 一个在侦听器停止侦听之前执行的函数(可以用来清除无效的副作用,例如等待中的异步请求。)
    • onTrack: 在依赖项被追踪时触发
    • onTrigger: 在依赖项的值发生变化并触发更新时触发
代码语言:javascript
复制
import { ref, watch } from 'vue';

const data = ref(0);

watch(data, (newValue, oldValue, onCleanup) => {
  let timeoutId;
  onCleanup(() => {
    clearTimeout(timeoutId);
  });

  timeoutId = setTimeout(() => {
    console.log(`数据变化了,新值是 ${newValue}`);
  }, 1000);
}, { 
    immediate: true,
    onTrack: (dep, info) => {
        console.log(`在依赖项被追踪时触发:${dep}`);
     },
    onTrigger: (dep, newValue, oldValue) => {
        console.log(`依赖项触发更新:${dep},新值为 ${newValue},旧值为 ${oldValue}`);
    }
});

watchEffect()

自动追踪依赖:当你需要根据多个响应式数据的变化来执行某些操作时,不需要显式地指定依赖,watchEffect() 会自动追踪

立即执行:watchEffect()在组件初始化时会立即执行一次,确保依赖状态的最新值被正确应用。

无需关心具体响应式属性:当你不需要关心响应式数据具体是哪个属性变化,只是想在其变化时做一些事情时。

代码和效果图如下

代码语言:javascript
复制
...
  <div>
    <input v-model="num1" type="number">
    <input v-model="num2" type="number">
    <h1>结果:{{ result }}</h1>
  </div>
...
...
import { ref, watchEffect } from 'vue'
let result = ref(0)
let num1 = ref(0)
let num2 = ref(0)
watchEffect(() => {
   result.value = num1.value + num2.value
});
...

我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖! 邀请人:iwhao

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是 Composition API?
  • 核心概念
    • setup 函数
    • 核心api
      • ref
        • reactive
          • readonly
            • computed、watch
              • watchEffect()
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档