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

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