Vue 3 組合式API

簡介

組合式API,是Vue 3的新功能,主要是將組件的邏輯關(guān)注點(diǎn),收集在一起,提高邏輯代碼的復(fù)用率,方便復(fù)雜組件邏輯功能的理解與維護(hù)。

實(shí)現(xiàn)上,通過setup組件選項(xiàng),整合邏輯功能,并返回,在組件模板直接使用。setupmethods、datacomputed等是向下兼容的。

需要注意的是: 在setup中不能使用this,會(huì)找不到組件的實(shí)例,因?yàn)?code>setup選項(xiàng)是在組件創(chuàng)建前執(zhí)行的。methods、datacomputed定義的屬性、方法均無法在setup中被獲取。

接下來我們通過一個(gè)簡單的示例來了解組合式API的關(guān)注點(diǎn)分離、邏輯功能復(fù)用;

示例

示例: 一個(gè)計(jì)數(shù)器,每次遇到偶數(shù)的時(shí)候,加入列表進(jìn)行展示;可排序翻轉(zhuǎn)、可修改列表數(shù)據(jù)。

image.png

邏輯功能:

  1. 基于步幅的累加
  2. 列表數(shù)據(jù)更新(添加)
  3. 列表數(shù)據(jù)排序&翻轉(zhuǎn)
  4. 列表數(shù)據(jù)的修改

實(shí)現(xiàn)

<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>

可以看到組件中功能實(shí)現(xiàn)是分散在不同的組件選項(xiàng)中,當(dāng)功能很多很復(fù)雜的時(shí)候,代碼的可讀性也會(huì)大大降低。多個(gè)組件間,相同邏輯功能復(fù)用不易。 Vue 2 中,雖然可通過mixins解決,但mixins容易出現(xiàn)命名沖突等問題。

setup 實(shí)現(xiàn)

接下來,我們基于組合式API來實(shí)現(xiàn),代碼如下:

<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: 列表數(shù)據(jù)更新(添加)    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: 列表數(shù)據(jù)排序&翻轉(zhuǎn)    const sortCaptureValues = () => {      captureValues.value.sort((a, b) => a > b).reverse();    };    ///功能4:列表數(shù)據(jù)的修改    const changeCaptureValues = () => {      captureValues.value = captureValues.value.map((a) => a * 10);    };    ///監(jiān)聽count    watch(count, updateCaptureValues);    return {      count,      stepValue,      increment,      isEven,      captureValues,      updateCaptureValues,      sortCaptureValues,      changeCaptureValues,    };  },};</script>

可以清楚的看到代碼邏輯功能更加聚焦,可讀性增強(qiáng)。 需要注意的是,組件中的數(shù)據(jù)需要通過ref變?yōu)轫憫?yīng)式的。

功能復(fù)用

基于setup的實(shí)現(xiàn)方式,我們可將功能提取到獨(dú)立的js文件中,以便其他組件復(fù)用。

///文件路徑: 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: 列表數(shù)據(jù)更新(添加)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: 列表數(shù)據(jù)排序&翻轉(zhuǎn)export function useSortValues(values) {    const sortCaptureValues = () => {        values.value.sort((a, b) => a > b).reverse();    };    return { sortCaptureValues }}///功能4:列表數(shù)據(jù)的修改export function useChangeValues(values,base) {     const changeCaptureValues = () => {        values.value = values.value.map((a) => a * base);      };      return {        changeCaptureValues      }}

再將提取的功能函數(shù)引入到我們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)    ///排序數(shù)據(jù)    const {sortCaptureValues} = useSortValues(captureValues)    ///改變數(shù)據(jù)    const { changeCaptureValues } = useChangeValues(captureValues,10)    ///監(jiān)聽count    watch(count, updateCaptureValues);    ///生命周期    onMounted(()=>console.log("已掛載組件"))    return {      count,      stepValue,      increment,      captureValues,      updateCaptureValues,      sortCaptureValues,      changeCaptureValues,    };  },};</script>

這樣其他的組件就可以復(fù)用提取功能了,比如:SimpleCounter組件復(fù)用基于步幅的累加功能。

<template>    <button @click="increment" > {{count}}</button></template><script>import useIncrement from "../composables/useIncrement";export default {    setup(props) {        return {            ...useIncrement(0,2) // 增幅為2,初始值為0,的計(jì)數(shù)器        }    }}</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,的計(jì)數(shù)器</script>

參考資料

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容