Vue 3 组合式API

简介

组合式API,是Vue 3的新功能,主要是将组件的逻辑关注点,收集在一起,提高逻辑代码的复用率,方便复杂组件逻辑功能的理解与维护。

实现上,通过setup组件选项,整合逻辑功能,并返回,在组件模板直接使用。setupmethodsdatacomputed等是向下兼容的。

需要注意的是: 在setup中不能使用this,会找不到组件的实例,因为setup选项是在组件创建前执行的。methodsdatacomputed定义的属性、方法均无法在setup中被获取。

接下来我们通过一个简单的示例来了解组合式API的关注点分离、逻辑功能复用;

示例

示例: 一个计数器,每次遇到偶数的时候,加入列表进行展示;可排序翻转、可修改列表数据。

逻辑功能:

  1. 基于步幅的累加
  2. 列表数据更新(添加)
  3. 列表数据排序&翻转
  4. 列表数据的修改

实现

<script>export default {    ///定义组件属性   props: {    initialCount: {      type: Number,      required: false,      default: 0,    },    step: {        type: Number,        default: 1    }  },  data() {    return {     count: this.initialCount,//功能1     stepValue : this.step,//功能1     captureValues: [],//功能2、3、4    };  },  methods: {    increment() {//功能1      this.count += this.stepValue;    },    sortCaptureValues() {//功能2      this.captureValues.sort((a, b) => a > b).reverse();    },    updateCaptureValues() {//功能3      if (this.isEven) {        this.captureValues.push(this.count);      }    },    changeCaptureValues() {//功能4      this.captureValues = this.captureValues.map((a) => a * 10);    },  },  computed: {    isEven() {//功能3      return this.count % 2 == 0;    },  },  watch: {    count(newVal, oldVal) {     this.updateCaptureValues();//功能3    },  },  onmounted() {    console.log("🔥");  },};</script>

可以看到组件中功能实现是分散在不同的组件选项中,当功能很多很复杂的时候,代码的可读性也会大大降低。多个组件间,相同逻辑功能复用不易。 Vue 2 中,虽然可通过mixins解决,但mixins容易出现命名冲突等问题。

setup 实现

接下来,我们基于组合式API来实现,代码如下:

<script>import { ref, computed, watch } from "vue";export default {  ///定义组件属性  props: {    initialCount: {      type: Number,      required: false,      default: 0,    },    step: {      type: Number,      default: 1,    },  },  setup(props) {    ///功能1:基于步幅的累加    const count = ref(props.initialCount);    const stepValue = ref(props.step);    const increment = () => (count.value += stepValue.value);    ///功能2: 列表数据更新(添加)    const captureValues = ref([]);    const isEven = computed(() => count.value % 2 === 0);    const updateCaptureValues = () => {      console.log(isEven);      if (isEven.value === true) {        captureValues.value.push(count.value);      }    };    ///功能3: 列表数据排序&翻转    const sortCaptureValues = () => {      captureValues.value.sort((a, b) => a > b).reverse();    };    ///功能4:列表数据的修改    const changeCaptureValues = () => {      captureValues.value = captureValues.value.map((a) => a * 10);    };    ///监听count    watch(count, updateCaptureValues);    return {      count,      stepValue,      increment,      isEven,      captureValues,      updateCaptureValues,      sortCaptureValues,      changeCaptureValues,    };  },};</script>

可以清楚的看到代码逻辑功能更加聚焦,可读性增强。 需要注意的是,组件中的数据需要通过ref变为响应式的。

功能复用

基于setup的实现方式,我们可将功能提取到独立的js文件中,以便其他组件复用。

///文件路径: src/composables/useIncrementimport {ref,computed} from 'vue'///功能1:基于步幅的累加export default function useIncrement(initialCount,step) {    const count = ref(initialCount)    const stepValue = ref(step)    const increment = () => count.value += stepValue.value    return {        count,        stepValue,        increment    }} ///功能2: 列表数据更新(添加)export function useUpdateValues(count) {    const captureValues = ref([]);    const isEven = computed(() => count.value % 2 === 0);    const updateCaptureValues = () => {      if (isEven.value === true) {        captureValues.value.push(count.value);      }    };    return {        captureValues,        updateCaptureValues,    }}///功能3: 列表数据排序&翻转export function useSortValues(values) {    const sortCaptureValues = () => {        values.value.sort((a, b) => a > b).reverse();    };    return { sortCaptureValues }}///功能4:列表数据的修改export function useChangeValues(values,base) {     const changeCaptureValues = () => {        values.value = values.value.map((a) => a * base);      };      return {        changeCaptureValues      }}

再将提取的功能函数引入到我们Counter组件中:

<script>import {watch,onMounted} from "vue";import useIncrement, {useUpdateValues,useSortValues,useChangeValues} from "../composables/useIncrement";export default {  ///定义组件属性  props: /*...*/    setup(props) {    ///累加    const {count, stepValue, increment} = useIncrement(props.initialCount, props.step)    ///添加到列表    const {captureValues,updateCaptureValues} = useUpdateValues(count)    ///排序数据    const {sortCaptureValues} = useSortValues(captureValues)    ///改变数据    const { changeCaptureValues } = useChangeValues(captureValues,10)    ///监听count    watch(count, updateCaptureValues);    ///生命周期    onMounted(()=>console.log("已挂载组件"))    return {      count,      stepValue,      increment,      captureValues,      updateCaptureValues,      sortCaptureValues,      changeCaptureValues,    };  },};</script>

这样其他的组件就可以复用提取功能了,比如:SimpleCounter组件复用基于步幅的累加功能。

<template>    <button @click="increment" > {{count}}</button></template><script>import useIncrement from "../composables/useIncrement";export default {    setup(props) {        return {            ...useIncrement(0,2) // 增幅为2,初始值为0,的计数器        }    }}</script>

或者使用<script setup>单文件组件中使用组合式API的语法糖:

<template>    <button @click="increment" > {{count}}</button></template><script setup>import useIncrement from "../composables/useIncrement";const {count, increment} = useIncrement(0,2) // 增幅为2 ,初始值为0,的计数器</script>

参考资料

https://v3.cn.vuejs.org/guide/composition-api-introduction.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章