20.compositionApi介紹和setup函數(shù)的參數(shù)和返回值

Options API的弊端

在Vue2中叮阅,我們編寫組件的方式是Options API:

  • Options API的一大特點(diǎn)就是在對應(yīng)的屬性中編寫對應(yīng)的功能模塊嫂伞;
  • 比如data定義數(shù)據(jù)展运、methods中定義方法顶别、computed中定義計(jì)算屬性些阅、watch中監(jiān)聽屬性改變狐粱,也包括生命
    周期鉤子舀寓;
但是這種代碼有一個(gè)很大的弊端:
  • 當(dāng)我們實(shí)現(xiàn)某一個(gè)功能時(shí),這個(gè)功能對應(yīng)的代碼邏輯會(huì)被拆分到各個(gè)屬性中脑奠;
  • 當(dāng)我們組件變得更大基公、更復(fù)雜時(shí),邏輯關(guān)注點(diǎn)的列表就會(huì)增長宋欺,那么同一個(gè)功能的邏輯就會(huì)被拆分的很分散轰豆;
  • 尤其對于那些一開始沒有編寫這些組件的人來說,這個(gè)組件的代碼是難以閱讀和理解的(閱讀組件的其他人)齿诞;
下面我們來看一個(gè)非常大的組件酸休,其中的邏輯功能按照顏色進(jìn)行了劃分:
  • 這種碎片化的代碼使用,理解和維護(hù)這個(gè)復(fù)雜的組件變得異常困難,并且隱藏了潛在的邏輯問題祷杈;
  • 并且當(dāng)我們處理單個(gè)邏輯關(guān)注點(diǎn)時(shí)斑司,需要不斷的跳到相應(yīng)的代碼塊中;


    image.png

    如果我們能將同一個(gè)邏輯關(guān)注點(diǎn)相關(guān)的代碼收集在一起會(huì)更好但汞。

這就是Composition API想要做的事情宿刮,以及可以幫助我們完成的事情。也有人把Vue CompositionAPI簡稱為VCA私蕾。

認(rèn)識(shí)Composition API

那么既然知道Composition API想要幫助我們做什么事情僵缺,接下來看一下到底是怎么做呢?

  • 為了開始使用Composition API踩叭,我們需要有一個(gè)可以實(shí)際使用它(編寫代碼)的地方磕潮;
  • 在Vue組件中,這個(gè)位置就是 setup 函數(shù)容贝;
setup其實(shí)就是組件的另外一個(gè)選項(xiàng):
  • 只不過這個(gè)選項(xiàng)強(qiáng)大到我們可以用它來替代之前所編寫的大部分其他選項(xiàng)自脯;
  • 比如methods、computed斤富、watch膏潮、data、生命周期等等满力;
接下來我們一起學(xué)習(xí)這個(gè)函數(shù)的使用:
  • 函數(shù)的參數(shù)
  • 函數(shù)的返回值

setup函數(shù)的參數(shù)

我們先來研究一個(gè)setup函數(shù)的參數(shù)戏罢,它主要有兩個(gè)參數(shù):

  • 第一個(gè)參數(shù):props
  • 第二個(gè)參數(shù):context
props非常好理解屋谭,它其實(shí)就是子組件接收的從父組件傳遞過來的屬性,會(huì)被放到1props對象中龟糕,我們在setup函數(shù)中如果需要使用桐磁,那么就可以直接通過props參數(shù)獲取:
  • 對于定義props的類型讲岁,我們還是和之前的規(guī)則是一樣的我擂,在props選項(xiàng)中定義;
  • 并且在template中依然是可以正常去使用props中的屬性缓艳,比如message校摩;
  • 如果我們在setup函數(shù)中想要使用props,那么不可以通過 this 去獲冉滋浴(后面我會(huì)講到為什么)衙吩;
  • 因?yàn)閜rops有直接作為參數(shù)傳遞到setup函數(shù)中,所以我們可以直接通過參數(shù)來使用即可溪窒;
另外一個(gè)參數(shù)是context坤塞,我們也稱之為是一個(gè)SetupContext,它里面包含三個(gè)屬性:

attrs:為一個(gè)對象澈蚌,存儲(chǔ)著所有的從父組件傳遞過來的非props的attribute摹芙;
slots:父組件傳遞過來的插槽(這個(gè)在以渲染函數(shù)返回時(shí)會(huì)有作用,后面會(huì)講到)宛瞄;
emit:當(dāng)我們組件內(nèi)部需要發(fā)出事件時(shí)會(huì)用到emit(因?yàn)槲覀儾荒茉L問this浮禾,所以不可以通過 this.$emit發(fā)出事件);

setup函數(shù)的返回值

setup既然是一個(gè)函數(shù)份汗,那么它也可以有返回值盈电,它的返回值用來做什么呢?

  • setup的返回值可以在模板template中被使用杯活;
  • 也就是說我們可以通過setup的返回值來替代data選項(xiàng)匆帚;

甚至是我們可以返回一個(gè)執(zhí)行函數(shù)來代替在methods中定義的方法

setup() {
  let counter = 100
  const increment = () => {
    counter++
  }
  const decrement = () => {
    counter--
  }
  return {
    counter,
    increment,
    decrement
  }
}

但是,如果我們將 counter 在 increment 或者 decrement進(jìn)行操作時(shí)轩猩,是否可以實(shí)現(xiàn)界面的響應(yīng)式呢卷扮?

  • 答案是不可以荡澎;
  • 這是因?yàn)閷τ谝粋€(gè)定義的變量來說均践,默認(rèn)情況下,Vue并不會(huì)跟蹤它的變化摩幔,來引起界面的響應(yīng)式操作彤委;

案例

App.vue
所有在template模板中使用的變量方法(除了props$attrs中的屬性),都得在setup函數(shù)中返回

<template>
  <div>
    <!--父組件在使用子組件home時(shí)或衡,除了給其傳了內(nèi)部接收的props的屬性message,title外焦影,還額外傳了兩個(gè)非props屬性id, class-->
    <home
      message="hahahh"
      title="標(biāo)題"
      id="home"
      class="homeClass"
      @change="change"
    />
  </div>
</template>

<script>
import Home from "./Home.vue";
export default {
  name: "App",
  components: {
    Home,
  },
  setup() {
    const change = (value) => {
      console.log("監(jiān)聽到了change事件", value);
    };
    return {
      //所有在template模板中使用的變量或方法(除了props和$attrs中的屬性)车遂,都得在setup函數(shù)中返回
      change,
    };
  },
};
</script>

<style></style>

Home.vue
父組件傳遞給子組件的非props屬性template中使用,這些屬性都存儲(chǔ)在$attrs對象中,可以通過attrs.屬性名獲取
父組件傳遞給子組件的非props屬性setup函數(shù)中獲取斯辰,這些屬性都存儲(chǔ)在setup函數(shù)的第二個(gè)參數(shù)對象contextattrs屬性中,可以通過context.attrs.屬性名獲取

父組件傳遞給子組件的props屬性setup函數(shù)中獲取舶担,這些屬性都存儲(chǔ)在setup函數(shù)第一個(gè)參數(shù)對象props中,可以通過props.屬性名獲取
在setup函數(shù)中,子組件向父組件發(fā)射事件彬呻,可以通過context.emit發(fā)射事件

<template>
  <div>
    <h2>{{ title }}</h2>
    <p>{{ message }}</p>
    <!-- 下面展示父組件傳遞給子組件的非props屬性在template中的使用衣陶,這些屬性都存儲(chǔ)在$attrs對象中 -->
    <div>id: {{ $attrs.id }} - class: {{ $attrs.class }}</div>
    <slot></slot>
  </div>
</template>

<script>
export default {
  props: {
    message: {
      type: String,
      required: true,
    },
    title: {
      type: String,
      default: "",
    },
  },
  emits: ["change"],
  setup(props, context) {
    const { attrs, slots, emit } = context;
    //在setup中獲取props中屬性,通過setup函數(shù)的第一個(gè)參數(shù)獲取
    console.log("props", props, props.message, props.title);
    //父組件傳遞給子組件的非props屬性在setup中使用闸氮,這些屬性都存儲(chǔ)在context.attrs對象中
    console.log("attrs", attrs, attrs.id, attrs.class);
    //父組件插入子組件插槽中的內(nèi)容
    console.log("slots", slots);
    emit("change", "今天天氣不錯(cuò)"); //emit用來向父組件發(fā)射事件
  },
};
</script>

<style lang="scss" scoped></style>

image.png

setup不可以使用this

官方關(guān)于this有這樣一段描述:

  • 表達(dá)的含義是this并沒有指向當(dāng)前組件實(shí)例剪况;
  • 并且在setup被調(diào)用之前,data蒲跨、computed译断、methods等都沒有被解析;
  • 所以無法在setup中獲取this或悲;


    image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末孙咪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子隆箩,更是在濱河造成了極大的恐慌该贾,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,080評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捌臊,死亡現(xiàn)場離奇詭異杨蛋,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)理澎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評論 3 385
  • 文/潘曉璐 我一進(jìn)店門逞力,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人糠爬,你說我怎么就攤上這事寇荧。” “怎么了执隧?”我有些...
    開封第一講書人閱讀 157,630評論 0 348
  • 文/不壞的土叔 我叫張陵揩抡,是天一觀的道長。 經(jīng)常有香客問我镀琉,道長峦嗤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,554評論 1 284
  • 正文 為了忘掉前任屋摔,我火速辦了婚禮烁设,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘钓试。我一直安慰自己装黑,他們只是感情好副瀑,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著恋谭,像睡著了一般糠睡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,856評論 1 290
  • 那天,我揣著相機(jī)與錄音抄沮,去河邊找鬼。 笑死除抛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的母截。 我是一名探鬼主播到忽,決...
    沈念sama閱讀 39,014評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼清寇!你這毒婦竟也來了喘漏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,752評論 0 268
  • 序言:老撾萬榮一對情侶失蹤华烟,失蹤者是張志新(化名)和其女友劉穎翩迈,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盔夜,經(jīng)...
    沈念sama閱讀 44,212評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡负饲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了喂链。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片返十。...
    茶點(diǎn)故事閱讀 38,687評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖椭微,靈堂內(nèi)的尸體忽然破棺而出洞坑,到底是詐尸還是另有隱情,我是刑警寧澤蝇率,帶...
    沈念sama閱讀 34,347評論 4 331
  • 正文 年R本政府宣布迟杂,位于F島的核電站,受9級特大地震影響本慕,放射性物質(zhì)發(fā)生泄漏排拷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評論 3 315
  • 文/蒙蒙 一间狂、第九天 我趴在偏房一處隱蔽的房頂上張望攻泼。 院中可真熱鬧火架,春花似錦鉴象、人聲如沸忙菠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽牛欢。三九已至,卻和暖如春淆游,著一層夾襖步出監(jiān)牢的瞬間傍睹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評論 1 266
  • 我被黑心中介騙來泰國打工犹菱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拾稳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,406評論 2 360
  • 正文 我出身青樓腊脱,卻偏偏與公主長得像访得,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子陕凹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評論 2 349

推薦閱讀更多精彩內(nèi)容