深入探索Vue3组合式API

时间:2024-10-07 19:26:42

目录

组合式API的好处

Vue3有哪些生命周期?

Vue2.X 和 Vue3.X对比

watch 和 watchEffect 的区别?

1.watch

2.watchEffect

watch和watchEffect的对比

ref 与 reactive 的区别?

定义

主要特点

基本用法

与 

组件定义

生命周期钩子


组合式API的好处

1.更好的逻辑组织:

在选项式API中,组件逻辑是按照data、methods、computed、watch等分块写的,这种分离可能会导致相同功能的代码分散在不同的部分

组合式API 通过将相关的逻辑组合在一起,使代码更加紧凑和清晰,尤其实在复杂组件中,组织代码的方式更加自然。

2.更好的逻辑复用:

在选项式API中,如果要复用逻辑,通常使用mixin,但mixin存在作用域不清晰、命名冲突等问题。

组合式API提供了composable (可组合函数)的概念,运行将逻辑抽取成独立的函数,这样复用性更强、代码更清晰。

3.更好的类型推断支持:

组合式API更好地支持TypeScript,尤其是在函数内部可以更明确地推断出数据和函数的类型,而不需要额外的类型定义。

4.更灵活的响应式系统:

组合式API 提供了更灵活的响应式系统,比如通过ref和reactive可以更直观地控制响应式数据的行为

Vue3有哪些生命周期?

  • setup():开始创建组件,在beforeCreate  和  created 之前进行, 创建的是 data 和 method
  • onBeforeMount():组件挂载到节点上之前执行的函数
  • onMounted():组件挂在完成后执行的函数;
  • onBeforeUpdate():组件更新之前执行的函数;
  • onUpdated():组件更新完成之后执行的函数;
  • onBeforeUnmount():组件卸载之前执行的函数;
  • onUnmounted():组件卸载完成后执行的函数;
  • onActived():被包含在<keep-alive>中的组件, 会多出两个生命周期钩子函数,被激活时执行;
  • onDeactivated():比如 A 组件切换到 B 组件,A组件消失时执行;
  • onErrorCaptured():当捕获一个来自子孙组件的异常时激活钩子函数。

Vue2.X 和 Vue3.X对比

vue2           ------->      vue3
 
beforeCreate   -------->      setup(()=>{})
created        -------->      setup(()=>{})
beforeMount    -------->      onBeforeMount(()=>{})
mounted        -------->      onMounted(()=>{})
beforeUpdate   -------->      onBeforeUpdate(()=>{})
updated        -------->      onUpdated(()=>{})
beforeDestroy  -------->      onBeforeUnmount(()=>{})
destroyed      -------->      onUnmounted(()=>{})
activated      -------->      onActivated(()=>{})
deactivated    -------->      onDeactivated(()=>{})
errorCaptured  -------->      onErrorCaptured(()=>{})

watch 和 watchEffect 的区别?

1.watch

watch用于监听特定响应式数据的变化,并在数据变化时执行回调函数。下面是一个使用watch的例子:

import { ref, watch } from 'vue';
 
const count = ref(0);
 
watch(count, (newValue, oldValue) => {
  console.log(`Count changed from ${oldValue} to ${newValue}`);
  // 执行一些副作用操作,例如发送API请求、更新其他状态等
});
 
// 改变count值会触发watch的回调
count.value++;
  • watch接受两个参数, 第一个参数是要监听的响应式值或计算属性(可以是ref、reactive对象的属性或者是computed的结果),第二个参数是回调函数。
  • 回调函数会在监听的值发生变化时被调用,它会接收到新的值和旧的值作为参数。
  • 如果你要深度监听对象或数组的变化, 可以为watch添加第三个参数,配置对象,如{deep:true}

2.watchEffect

watchEffect则是立即执行并且持续监听其内部依赖变化的函数。每当其依赖的响应式值发生变化时,它都会重新执行。

import { ref, watchEffect } from 'vue';
 
const count = ref(0);
const message = ref('Initial Message');
 
watchEffect(() => {
  console.log(`Count is ${count.value}, and message is ${message.value}`);
  // 根据count和message的值执行一些副作用操作
});
 
// 改变count或message值都会触发watchEffect的再次执行
count.value++;
message.value = 'Updated Message';

详细讲解:

  • watchEffect不需要指定监听的具体值,它会自动追踪其内部表达式所涉及的所有响应式依赖。
  • 当调用watchEffect时,它会立即执行一次,并记录下内部依赖的快照,此后每当依赖项变化时,它会再次执行。
  • 若想停止监听,可以返回一个清理函数,例如在组件卸载时清理副作用。

watch和watchEffect的对比


watch

  • watch显式指定依赖数据,依赖数据更新时执行回调函数
  • 具有一定的惰性lazy 第一次页面展示的时候不会执行,只有数据变化的时候才会执行(设置immediate: true时可以变为非惰性,页面首次加载就会执行)
  • 监视ref定义的响应式数据时可以获取到原值
  • 既要指明监视的属性,也要指明监视的回调


watchEffect

  • watchEffect自动收集依赖数据,依赖数据更新时重新执行自身
  • 立即执行,没有惰性,页面的首次加载就会执行
  • 无法获取到原值,只能得到变化后的值
  • 不用指明监视哪个属性,监视的回调中用到哪个属性就监视哪个属性

ref 与 reactive 的区别?

定义

reactive 和 ref 是 Vue 3 中的两种响应式数据绑定方式,ref 适用于简单的响应式数据,而 reactive 则适用于复杂对象或数组的响应式数据。

ref:用于声明 基本类型 或者单个变量的响应式数据。

ref 的核心在于它包装了一个值,当这个值变化时,依赖它的视图会重新渲染。
注意:ref 返回的是一个对象,其中的值通过 .value 属性访问。

const count = ref(0);
console.log(count.value); // 0
count.value++;


reactive:用于声明 对象 或 数组 的响应式数据。

reactive 更适合处理复杂的数据结构(对象或数组)。它返回的是一个响应式对象,直接操作对象的属性时,视图会自动更新。
 

const state = reactive({
  name: 'Vue',
  age: 3
});
console.log(state.name); // 'Vue'
state.age = 4; // 视图会自动更新

主要区别如下:

1. 数据类型不同:

ref用于包装JavaScript基本类型的数据(如字符串、数字、布尔值等)

reactive可以用于包装JavaScript对象和数组等复杂类型的数据


2. 使用方式不同:

ref需要通过在模板中使用ref指令以及在JavaScript代码中使用ref函数进行创建和使用,而reactive则需要通过调用Vue.js提供的reactive函数进行包装和创建。


3. 访问方式不同:

对于通过ref函数创建的响应式数据,我们可以通过.value属性来访问其实际值;而对于通过reactive函数创建的响应式对象,我们可以直接访问其属性或调用其方法


4. 设计理念不同:

ref主要是为了解决单一元素/数据的响应式问题,而reactive则是为了解决JavaScript对象和数组等复杂数据结构的响应式问题

<script setup>

<script setup> 是 Vue 3 引入的一种新语法糖,它用于使用组合式 API 编写组件。这种语法简化了 Composition API 的使用,使得编写和组织组件逻辑更加简洁和直观。

主要特点

  1. 声明式<script setup> 提供了一种声明式的方式来使用组合式 API,减少了样板代码。
  2. 自动响应:在 <script setup> 中定义的响应式引用(如 ref 和 reactive)和函数自动暴露给模板,无需返回对象。
  3. 生命周期钩子:生命周期钩子(如 onMountedonUpdated 等)可以直接导入和使用,无需定义匿名函数。
  4. 模块作用域:在 <script setup> 中导入的变量和函数自动拥有模块作用域,减少了全局命名冲突。

基本用法

<script setup>
import { ref, computed, onMounted } from 'vue';

const count = ref(0);
const doubledCount = computed(() => count.value * 2);

onMounted(() => {
  console.log('Component is mounted');
});

function increment() {
  count.value++;
}
</script>

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Doubled Count: {{ doubledCount }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

与 <script> 的区别

  • 无需返回对象:在 <script setup> 中,你不需要返回一个对象来暴露响应式状态、计算属性和方法给模板。
  • 更少的代码<script setup> 使得组件的编写更加简洁,减少了样板代码。

组件定义

<script setup> 中,你可以定义组件的响应式状态、计算属性、方法和生命周期钩子,就像在 <script> 标签中使用组合式 API 一样,但是更加简洁。

生命周期钩子

<script setup>
import { onMounted } from 'vue';

onMounted(() => {
  console.log('Component is mounted');
});
</script>