2-体验组合式 API


体验组合式 API

1、知识点

  • setup
  • reactive
  • computed
  • toRefs
  • watch
  • watchEffect
  • readonly

2、简单例子

组合 API 是 Vue3 中最常用特色语法。这是一种全新的逻辑重用和代码组织方法。

我们使用所谓的选项式 API 构建组件。如 datamethodscomputed 等这种方法缺点已成事实,因为这些 JavaScript 代码本身不起作用。需要确切地知道模板中可以访问哪些属性以及 this 关键字的动作。Vue 编译器需要将此属性转换为工作代码。因此,我们无法从自动建议或类型检查中受益。

组合式 API 旨在通过将组件属性中当前可用的机制公开为 JavaScript 函数来解决此问题。Vue 核心团队将组合式 API 描述为“一组基于功能的附加 API,它们允许灵活地组成组件逻辑”。用组合式 API 编写的代码更具可读性,这使它更易于阅读和学习。

来看一个使用新的组合式 API 理解其工作原理的组件的简单示例。

新建 src/components/counter/Counter.vue

<template>
  <button @click="increment">
    Count is: {{ count }}, double is: {{ double }} Name is: {{ reonly.name }}
  </button>
</template>

<script>
import { reactive, computed, toRefs, watch, watchEffect, readonly } from "vue";

export default {
  setup() {
    const state = reactive({
      count: 0,
      double: computed(() => state.count * 2),
    });

    const reonly = readonly({
      name: "InfinityX7",
    });

    function increment() {
      state.count++;
    }

    watch(
      () => state.count,
      (newVal, oldVal) => {
        console.log("Counter is change ===>", oldVal, newVal);
      }
    );

    watchEffect(() => {
      console.log("watchEffect");
      reonly.name = "开到荼蘼";
    });

    return {
      ...toRefs(state),
      reonly,
      increment,
    };
  },
};
</script>

src/components/counter/index.js 导出组件:

import Counter from "./src/Counter.vue";
export default Counter;

新建src/views/TestCounter.vue

<template>
  <div class="test-counter">
    <Counter />
  </div>
</template>

<script>
import Counter from "../components/couter/Couter.vue";
import { defineComponent } from "vue";
export default defineComponent({
  name: "TestCounter",
  components: {
    Counter,
  },
});
</script>

src/router/index.js 配置路由

{
   path: "/counter",
   name: "Counter",
   component: () => import("../views/TestCounter.vue"),
},

App.vue增加/counter导航跳转,运行效果

GIF描述

3、setup

简而言之,它只是一个将属性和函数返回到模板使用的入口。

我们在这里声明所有响应式属性,计算属性,观察者和生命周期挂钩,然后将它们返回,以便可以在模板中使用它们。

所以没有从 setup 函数返回的内容将在模板中不可用

export default defineComponent({
  setup() {},
});

4、reactive 普通对象响应式代理

setup 函数里面, reactive 它主要是处理你的对象,让它经过 Proxy 的加工变为一个响应式的对象,类似于 Vue2.0 版本的 data 属性。

需要注意的是加工后的对象跟原对象是不相等的,并且加工后的对象属于深度克隆的对象。响应式转换是“深层的”:会影响对象内部所有嵌套的属性。基于 ES2015 的 Proxy 实现,返回的代理对象不等于原始对象。建议仅使用代理对象而避免依赖原始对象。

const state = reactive({
  count: 0,
  double: computed(() => state.count * 2),
});

5、computed 计算属性

根据以上内容,我们声明了 countreatcive 函数调用的响应式。它可以包装任何原生语法或对象并返回其响应式引用。传入一个 getter 函数,返回一个默认不可手动修改的 ref 对象。

const double = computed(() => count.value * 2);

function increment() {
  count.value++;
}

6、toRefs

可以看到我们上面用了很多的新属性,toRefs 函数可以将 reactive() 创建出来的响应式对象,转换为普通的对象,只不过这个对象上的每个属性节点,都是 ref() 类型的响应式数据,配合 {{}} 插值指令能完成数据的双向绑定,在开发中非常高效。其实就有点像 ES6 的对象解构。

return {
  ...toRefs(state),
  reonly,
  increment,
};

拆分之后,我们可以写出类似这样的伪代码:

return {
  count,
  double,
  reonly,
  increament,
};

countdouble 直接在 html 上使用了:

<button @click="increment">
  <!-- Count is: {{ state.count }}, double is: {{ state.double }} -->
  Count is: {{ count }}, double is: {{ double }} Name is: {{reonly.name}}
</button>

无需使用如下:

<button @click="increment">
  Count is: {{ state.count }}, double is: {{ state.double }} Name is:
  {{reonly.name}}
</button>

所以,这种开发方式就大大提高了开发效率了。

7、watch 监听

watch() 函数用来监视某些数据项的变化,从而触发某些特定的操作,使用之前还是需要按需导入,监听 state.count 的变化,然后触发回调函数里面的逻辑,也就是监听用户输入的检索值,然后触发回调函数的逻辑把 state.count 值打印到控制台上:

  • 第一个参数传入一个 getter 函数,获取 state.count 返回值。
  • 监听 state.count 新旧值变化。
watch(
  () => state.count,
  (newVal, oldVal) => {
    console.log("Counter is change ===>", oldVal, newVal);
  }
);

8、watchEffect 立即执行监听

这个属性有点像 vue 2.x 中的 immediate: true 这个立即执行属性。立即执行传入的一个函数,并响应式追踪其依赖,并在其依赖变更时重新运行该函数。

watchEffect(() => {
  console.log("watchEffect");
});

watchEffect 在组件的 setup() 函数或生命周期钩子被调用时,侦听器会被链接到该组件的生命周期,并在组件卸载时自动停止。

在一些情况下,也可以显式调用返回值以停止侦听:

let stop = watchEffect(() => {
  console.log("watchEffect");
});
stop();

9、readonly 只读代理

传入一个对象(响应式或普通)或 ref,返回一个原始对象的 只读 代理。一个只读的代理是“深层的”,对象内部任何嵌套的属性也都是只读的。

const reonly = readonly({
  name: "Zhangsan",
});

然后我们来修改 reonly.name

watchEffect(() => {
  console.log("watchEffect");
  reonly.name = "Lisi";
});

发现 reonly.name 还是 Zhangsan,没有变化。

10、总结

我们通过一个简单的例子对 Vue 3 组合式 API 有了一个初步的了解:

  • reactive 对普通对象进行响应式代理。
  • setup 类似 created 生命周期。
  • computed 计算属性。
  • watch 属性值监听。
  • watchEffect 立即执行监听。
  • readonly 对值,对象进行只读代理。
  • toRefs 可对 reactive 申明的对象进行解构,提高开发效率。

文章作者: Syhan
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Syhan !
评论
  目录