Vue 3 组合式 API 指南:响应式状态管理与跨组件通信

引言

随着 Vue 3 的发布,Vue 引入了一个新的编程范式------组合式 API(Composition API)。这一新特性旨在解决 Options API 在处理复杂逻辑时的一些局限性,并提供了一种更灵活、更可重用的方式来组织和重用代码

组合式 API 基础

setup 函数的概念和作用

在 Vue 组合式 API 中,setup 函数是组件的入口点,它在组件实例被创建时调用,但在任何生命周期钩子之前执行。setup 函数的主要作用是初始化响应式状态、计算属性、方法和侦听器,并将它们暴露给模板和组件的其他部分。

javascript 复制代码
import { ref, reactive, computed, watch } from 'vue';

export default {
  setup() {
    // 初始化响应式状态和功能
    return {
      // 暴露给模板和组件其他部分的响应式状态和功能
    };
  }
};

响应式引用 ref 和响应式对象 reactive 的使用方法

在 Vue 3 中,refreactive 是创建响应式状态的两个主要工具。

  • ref 用于创建单个响应式值,它返回一个响应式的引用对象。当引用的值是基本数据类型时,Vue 会自动将其包装在对象中。
javascript 复制代码
import { ref } from 'vue';

export default {
  setup() {
    const count = ref(0);

    // 通过 .value 访问和修改响应式值
    console.log(count.value); // 输出 0
    count.value++;
    console.log(count.value); // 输出 1

    return {
      count
    };
  }
};
  • reactive 用于创建一个响应式对象。它返回一个响应式的代理对象,该对象的属性访问和修改都是响应式的。(实际上,ref底层就是reactive实现的,实际开发中一般ref用的多)
javascript 复制代码
import { reactive } from 'vue';

export default {
  setup() {
    const state = reactive({ count: 0 });

    // 直接访问和修改响应式对象的属性
    console.log(state.count); // 输出 0
    state.count++;
    console.log(state.count); // 输出 1

    return {
      state
    };
  }
};

使用 computed 和 watch 创建计算属性和侦听器

computedwatch 是 Vue 组合式 API 中用于处理计算属性和侦听器的工具。

  • computed 用于创建计算属性,它接受一个 getter 函数,并返回一个只读的响应式引用。
javascript 复制代码
import { ref, computed } from 'vue';

export default {
  setup() {
    const count = ref(0);
    const doubleCount = computed(() => count.value * 2);

    // 访问计算属性
    console.log(doubleCount.value); // 输出 0

    return {
      count,
      doubleCount
    };
  }
};
  • watch 用于创建侦听器,它监视一个或多个响应式引用的变化,并在变化时执行一个回调函数。
javascript 复制代码
import { ref, watch } from 'vue';

export default {
  setup() {
    const count = ref(0);

    watch(count, (newValue, oldValue) => {
      console.log(`Count changed from ${oldValue} to ${newValue}`);
    });

    return {
      count
    };
  }
};

provide 和 inject

在 Vue.js 中,provideinject 是两个用于实现跨组件依赖注入的 API。它们允许一个祖先组件定义可供其所有子孙组件使用的数据或方法,而无需通过逐层传递 props 或使用事件发射器。

provide

provide 函数允许你在组件内部提供一个值,这个值可以被其所有子孙组件注入。provide 可以在组件的 setup 函数中使用,也可以在组件的 methodscomputedwatch 中使用。

javascript 复制代码
import { provide } from 'vue';

export default {
  setup() {
    // 提供一个响应式对象
    const state = reactive({ count: 0 });

    // 提供一个方法
    const increment = () => {
      state.count++;
    };

    // 使用 provide 函数提供数据
    provide('state', state);
    provide('increment', increment);

    // ...
  }
};

在上面的例子中,stateincrement 方法被提供给所有子孙组件。

inject

inject 函数用于在子孙组件中注入由祖先组件提供的数据或方法。inject 可以在组件的 setup 函数中使用,也可以在组件的 methodscomputedwatch 中使用。

javascript 复制代码
import { inject } from 'vue';

export default {
  setup() {
    // 注入 'state' 和 'increment'
    const state = inject('state');
    const increment = inject('increment');

    // 使用注入的数据和方法
    console.log(state.count); // 输出 0
    increment(); // 增加计数

    // ...
  }
};

在上面的例子中,stateincrement 被注入到子孙组件中,并可以像本地数据一样使用。

注意事项

  • provideinject 是成对使用的,只有当祖先组件提供了某个值,子孙组件才能注入这个值。
  • provideinject 提供的值是响应式的,这意味着如果提供的值发生变化,所有注入了这个值的子孙组件都会自动更新。
  • provideinject 可以在组件的任何生命周期钩子中使用,但通常在 setup 函数中使用,以确保在组件初始化时提供和注入值。

通过使用 provideinject,开发者可以更灵活地管理组件之间的依赖关系,特别是在大型应用中,这有助于减少组件之间的耦合度,提高代码的可维护性。

子孙组件能改动inject注入的值吗

孙组件不能直接修改通过 inject 注入的响应式数据。这是为了保持数据流的清晰和组件之间的独立性,避免潜在的副作用和难以追踪的错误。

然而,如果你确实需要在子孙组件中修改注入的值,你可以通过以下方法实现:

1.使用 refreactive 提供响应式数据

如果你使用 refreactive 提供响应式数据,那么子孙组件可以通过 .value 属性来修改这个值。

javascript 复制代码
// 祖先组件
import { provide, reactive } from 'vue';

export default {
  setup() {
    const state = reactive({ count: 0 });

    provide('state', state);

    // ...
  }
};

// 子孙组件
import { inject } from 'vue';

export default {
  setup() {
    const state = inject('state');

    // 修改注入的响应式数据
    state.count++;

    // ...
  }
};

2.提供一个方法来修改数据

你可以在祖先组件中提供一个方法,该方法可以修改响应式数据。然后,这个方法可以被子孙组件注入并调用。

javascript 复制代码
// 祖先组件
import { provide } from 'vue';

export default {
  setup() {
    const state = reactive({ count: 0 });
    const increment = () => {
      state.count++;
    };

    provide('state', state);
    provide('increment', increment);

    // ...
  }
};

// 子孙组件
import { inject } from 'vue';

export default {
  setup() {
    const increment = inject('increment');

    // 调用注入的方法来修改数据
    increment();

    // ...
  }
};

3.使用 readonly 创建只读引用

如果你不希望子孙组件修改注入的值,可以使用 readonly 创建一个只读引用。

typescript 复制代码
// 祖先组件
import { provide, reactive, readonly } from 'vue';

export default {
  setup() {
    const state = reactive({ count: 0 });

    provide('state', readonly(state));

    // ...
  }
};

// 子孙组件
import { inject } from 'vue';

export default {
  setup() {
    const state = inject('state');

    // 尝试修改注入的值将会失败
    // state.count = 1; // 这将不会工作

    // ...
  }
};

总结

Vue 3 的组合式 API 通过 setup 函数提供响应式状态管理,支持使用 refreactive 创建响应式数据,computedwatch 处理计算属性和侦听器。同时,provideinject 允许跨组件进行依赖注入,实现数据和方法的共享。这些特性提升了代码的组织性、可重用性以及组件间的解耦。

希望这篇文章能帮助到你

相关推荐
麒麟而非淇淋1 分钟前
AJAX 入门 day3
前端·javascript·ajax
茶茶只知道学习14 分钟前
通过鼠标移动来调整两个盒子的宽度(响应式)
前端·javascript·css
蒟蒻的贤16 分钟前
Web APIs 第二天
开发语言·前端·javascript
清灵xmf20 分钟前
揭开 Vue 3 中大量使用 ref 的隐藏危机
前端·javascript·vue.js·ref
蘑菇头爱平底锅22 分钟前
十万条数据渲染到页面上如何优化
前端·javascript·面试
su1ka11126 分钟前
re题(35)BUUCTF-[FlareOn4]IgniteMe
前端
测试界柠檬27 分钟前
面试真题 | web自动化关闭浏览器,quit()和close()的区别
前端·自动化测试·软件测试·功能测试·程序人生·面试·自动化
多多*28 分钟前
OJ在线评测系统 登录页面开发 前端后端联调实现全栈开发
linux·服务器·前端·ubuntu·docker·前端框架
2301_8010741528 分钟前
TypeScript异常处理
前端·javascript·typescript
ᅠᅠᅠ@29 分钟前
异常枚举;
开发语言·javascript·ecmascript