【Vue3】組合式API

為什么要用組合式API呢

  • 用原始方式寫,業(yè)務(wù)邏輯會(huì)過(guò)于分散;
  • 使用組合式API,可以把同一業(yè)務(wù)邏輯的代碼放在一起;

使用組合式API寫代碼

1、所有邏輯都放在setup函數(shù),它的第一個(gè)參數(shù)是props對(duì)象(setup函數(shù)中的props是響應(yīng)式的,不能用ES6解構(gòu),會(huì)消除prop的響應(yīng)性setup文檔
2、通過(guò)ref、reactive、toRef來(lái)創(chuàng)建響應(yīng)式數(shù)據(jù);
3、視圖要用到的變量、方法為setup函數(shù)返回的對(duì)象屬性;
4、watch、computed是個(gè)函數(shù);
5、生命周期鉤子寫法微調(diào),xyz變成onXyz,比如mounted變成onMounted,而且created和beforeCreate不再需要,這是因?yàn)閟etup函數(shù)本身就是圍繞created和beforeCreate來(lái)進(jìn)行的,所以不需要再定義它們,這兩個(gè)鉤子里編寫的任何代碼都直接寫在setup函數(shù)里即可;

setup函數(shù)中要使用context.emit(context是setup的第二個(gè)參數(shù)),不能在setup函數(shù)里使用this.$emit,你可以在methods里使用this.$emit,但是我們以后在vue3中盡量不使用methods,要使用setup;

響應(yīng)式API

ref

  • ref和reactive一樣, 也是用來(lái)實(shí)現(xiàn)響應(yīng)式數(shù)據(jù)的,不過(guò)它是傳遞一個(gè)簡(jiǎn)單值
  • ref底層的本質(zhì)其實(shí)還是reactive,系統(tǒng)會(huì)自動(dòng)根據(jù)我們給ref傳入的值將它轉(zhuǎn)換成ref(xx) -> reactive({value:xx});
  • 在JS中我們要用xx.value,但是在HTML模板中,直接使用xx
const count = ref(0)
console.log(count.value) // 0

count.value++
console.log(count.value) // 1

reactive

傳遞一個(gè)對(duì)象,把它變成響應(yīng)式數(shù)據(jù)(結(jié)合toRef代碼一起看)

toRef

源響應(yīng)式對(duì)象上的某個(gè) property 新創(chuàng)建一個(gè) ref。然后,ref 可以被傳遞,它會(huì)保持對(duì)其源 property 的響應(yīng)式連接。

const state = reactive({
 foo: 1,
 bar: 2
})
const fooRef = toRef(state, 'foo')

fooRef.value++
console.log(state.foo) // 2

state.foo++
console.log(fooRef.value) // 3

toRefs

將響應(yīng)式對(duì)象轉(zhuǎn)換為普通對(duì)象,其中結(jié)果對(duì)象的每個(gè) property 都是指向原始對(duì)象相應(yīng) property 的 ref;
一般用于setup參數(shù)props的結(jié)構(gòu)居多,比如:const {title} = toRefs(props)

const state = reactive({
  foo: 1,
  bar: 2
})

const stateAsRefs = toRefs(state)
/*
stateAsRefs 的類型:

{
  foo: Ref<number>,
  bar: Ref<number>
}
*/

// ref 和原始 property 已經(jīng)“鏈接”起來(lái)了
state.foo++
console.log(stateAsRefs.foo.value) // 2

stateAsRefs.foo.value++
console.log(state.foo) // 3
image.png
  • 響應(yīng)式狀態(tài)解構(gòu)
import { reactive, toRefs } from 'vue'

const book = reactive({
  author: 'Vue Team',
  year: '2020',
  title: 'Vue 3 Guide',
  description: 'You are reading this book right now ;)',
  price: 'free'
})

let { author, title } = toRefs(book)

title.value = 'Vue 3 Detailed Guide' // 我們需要使用 .value 作為標(biāo)題,現(xiàn)在是 ref
console.log(book.title) // 'Vue 3 Detailed Guide'

完整示例

<template>
  有{{ count }}次
  <button @click="onAddCount">click</button>
  <h1>{{ helloText }}</h1>
</template>

<script>
import { onMounted, ref, computed, watch } from "vue";

function getData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(Math.floor(Math.random() * 5));
    }, 3000);
  });
}

export default {
  props: ["msg"],
  setup(props) {
    let count = ref(0);
    const getCount = async () => {
      count.value = await getData();
    };
    const onAddCount = () => {
      count.value++;
    };
    onMounted(getCount);

    let name = ref("win");
    let helloText = computed(() => {
      return props.msg + " " + name.value;
    });

    watch(count, (newvalue, oldvalue) => {
      let result = "";
      for (let i = 0; i < count.value; i++) {
        result += name.value;
      }
      console.log(result, "result");
      name.value = result;
    });

    return {
      count,
      onAddCount,

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

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

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