拉開序幕的 setup

1. 拉開序幕的 setup

  1. 理解:vue3 中的一個(gè)新的配置項(xiàng)勾笆,值為一個(gè)函數(shù)橡类。

  2. setup 是所有 Compositon api 的表演的舞臺(tái)。

  3. 組件中用到的:數(shù)據(jù)摆碉,方法塘匣,watch,計(jì)算屬性等都要配置在 setup 中

  4. setup 的返回值有兩種:

  • 若返回一個(gè)對(duì)象巷帝,則對(duì)象中的屬性忌卤,方法,在模板中均可以直接使用楞泼。(重點(diǎn)關(guān)注)
  • 若返回的是一個(gè)渲染函數(shù)驰徊,則可以直接定義渲染內(nèi)容。(了解)
  1. 注意點(diǎn):
  • 盡量不要與 vue2 混用堕阔。
    -- vue2配置(data, methods, computed...)中可以訪問到 setup 中的屬性棍厂,方法。但是setup 中不能訪問到 vue2 中的配置(data, methods, computed...)
    -- 如果有重名超陆,setup 優(yōu)先

  • setup 不能是一個(gè) async 函數(shù)牺弹,因?yàn)榉祷刂挡辉偈?return 的對(duì)象,而是 promise, 模板看不到 returen 對(duì)象中的屬性例驹。

2. ref函數(shù)

  1. 作用:定義一個(gè)響應(yīng)式的數(shù)據(jù)捐韩。
  2. 語法: const xxx = ref(initeValue)
  • 創(chuàng)建一個(gè)包含響應(yīng)式數(shù)據(jù)的引用對(duì)象(reference 對(duì)象)。
  • JS 中操作數(shù)據(jù): xxx.value
  • 模板中讀取不用 .vulue 直接寫鹃锈。
  1. 備注:
  • 接收數(shù)據(jù)可以是是基本數(shù)據(jù)類型荤胁,也可以是對(duì)象類型。
  • 基本數(shù)據(jù)類型:響應(yīng)依然是靠 Object.defineProperty() 里的 get 和 set 完成的屎债。
  • 對(duì)象類型:內(nèi)部是求助了 vue3 中的內(nèi)置的新函數(shù) reactive 函數(shù)仅政。

3. reactive 函數(shù)

  1. 作用:定義一個(gè)對(duì)象類型的響應(yīng)式∨杈裕基本理性用 ref 函數(shù)圆丹。
  2. 語法: const 代理對(duì)象 = reactive(原對(duì)象)。 接收一個(gè)對(duì)象(或者數(shù)據(jù))躯喇,返回一個(gè)代理對(duì)象(proxy 對(duì)象)辫封。
  3. reactive 定義的響應(yīng)式數(shù)據(jù)是深層次的。
  4. 內(nèi)部基于 ES6 的 proxy 實(shí)現(xiàn)廉丽,通過代理對(duì)象操作源對(duì)象內(nèi)部數(shù)據(jù)倦微,進(jìn)行操作。

4. vue2 的響應(yīng)式原理

  1. 實(shí)現(xiàn)原理:
  • 對(duì)象類型:通過 Object.defineProperty() 對(duì)屬性的讀取正压,修改進(jìn)行攔截(數(shù)據(jù)劫持)欣福。
  • 數(shù)據(jù)類型:通過重寫更新數(shù)組的一系列方法來實(shí)現(xiàn)攔截. (對(duì)數(shù)組的變更方法進(jìn)行了包裹)。
Object.defineProperty(data,'count',{
  set(){},
  get(){}
})
  1. 存在問題:
  • 新增屬性焦履,刪除屬性拓劝,界面不會(huì)發(fā)生變化
  • 數(shù)組通過下標(biāo)修改,不會(huì)更新界面

5. vue3 的響應(yīng)式

  1. 實(shí)現(xiàn)原理:
  • 通過 Proxy(代理):攔截對(duì)象中任意屬性的變化嘉裤,包括屬性的讀寫郑临,添加,刪除等屑宠。
  • 通過 Reflect (反射):實(shí)現(xiàn)源對(duì)象的屬性進(jìn)行操作
  • MDN 有對(duì)應(yīng)的文檔
new Proxy(data, {
  //攔截讀取數(shù)據(jù)屬性值
  get(target, prop){
    return Reflect.get(target,prop)
  },
  //攔截設(shè)置或或添加屬性值
  set(target,prop,value){
    return Reflect.set(target,prop,value)
  }
  //攔截刪除屬性
  deleteProperty(target, prop){
    return Reflect.deleteProperty(target, prop)
  }
})

6. ref 和 reactive 的對(duì)比

  1. 從定義數(shù)據(jù)角度對(duì)比
  • ref 定義基本類型數(shù)據(jù)
  • reactive 定義對(duì)象或者數(shù)組類型數(shù)據(jù)
  • 備注:ref 也可以定義對(duì)象或者數(shù)組類型數(shù)據(jù)牧抵,但是內(nèi)部它自動(dòng)通過 reactive 轉(zhuǎn)為代理對(duì)象實(shí)現(xiàn)。
  1. 從原理角度對(duì)比:
  • ref 還是通過 vue2 的 Object.defineProperty() 的 get 和 set 實(shí)現(xiàn)的響應(yīng)式(數(shù)據(jù)劫持)侨把。

  • reactive 通過使用 Proxy 來實(shí)現(xiàn)響應(yīng)式(數(shù)據(jù)劫持),并通過 Reflect 操作源對(duì)象內(nèi)部的數(shù)據(jù)妹孙。

  1. 從使用角度對(duì)比:
  • ref 定義的數(shù)據(jù):操作數(shù)據(jù)需要 .value秋柄。 讀取數(shù)據(jù)時(shí)候模板中直接讀取不需要 .value

  • reactive 定義的數(shù)據(jù),操作與讀取均不需要 .value

7. setup 的兩個(gè)注意點(diǎn)

  1. setup 的執(zhí)行時(shí)機(jī)
    在 beforeCreate 之前執(zhí)行一次蠢正,this 是 undifined

  2. setup 的參數(shù)

  • props:值為對(duì)象骇笔,包含:組件外部傳遞過來,且組件內(nèi)部聲明接收了的屬性。
  • context:上下文對(duì)象
    -- attrs:值為對(duì)象笨触,包含:組件外部傳遞過來懦傍,但是沒有在 props 配置中-聲明的屬性。相當(dāng)于 this.attrs. -- slots: 接收的插槽內(nèi)容芦劣,相當(dāng)于this.slots.
    -- emit: 分發(fā)自定義函數(shù)粗俱,相當(dāng)于 this.$emit.

8. 計(jì)算屬性與監(jiān)視

8.1 computed 函數(shù)

  1. 與vue2 中的 computed 相比,配置功能一致虚吟。
  2. 寫法
import {computed} from 'vue'

setup(){
  ...
  //計(jì)算屬性一般寫法
  let fullName = computed(()=>{
    return person.firstName + '-' + person.lastName
  })
  
  //計(jì)算屬性完整寫法
  let fullName = computed(()=>{
  get(){
    
   return person.firstName + '-' + person.lastName
  },
  set(value){
    const nameArr = value.splice("-")
    person.firstName = nameArr[0]
    person.lastName = nameArr[1]
  }
  })
  
}

8.2 watch 函數(shù)

  1. 與 vue2 中的 watch 配置一樣
  2. 兩個(gè)小坑
  • 監(jiān)視 reactive 定義的響應(yīng)式數(shù)據(jù)時(shí)寸认,oldValue 無法正確獲取,強(qiáng)制開啟了深度監(jiān)視(deep 配置失效)串慰。
  • 監(jiān)視 reactive 定義的響應(yīng)式數(shù)據(jù)中的某個(gè)屬性時(shí)候偏塞,deep 配置有效。
//情況一邦鲫,監(jiān)視 ref定義的數(shù)據(jù)
watch(sum, (newValue,oldVaule)=>{
  consolo.log("sum數(shù)據(jù)變化了", newValue,oldVaule)
})

//情況二灸叼,監(jiān)視多個(gè) ref定義的數(shù)據(jù)
watch([sum,msg], (newValue,oldVaule)=>{
  consolo.log("sum或者 msg 數(shù)據(jù)變化了", newValue,oldVaule)
})

//情況三,監(jiān)視r(shí)eactive定義的數(shù)據(jù)
//若 watch 監(jiān)視的是 reactive 定義的響應(yīng)式數(shù)據(jù)庆捺,則無法獲取正確的 oldValue
//若 watch 監(jiān)視的是 reactive 定義的響應(yīng)式數(shù)據(jù)古今,則強(qiáng)制開啟了深度監(jiān)視

watch(person, (newValue,oldVaule)=>{
  consolo.log("person數(shù)據(jù)變化了", newValue,oldVaule)
}, {immediate:ture, deep: false}) //此處的 deep 不生效

//情況四,監(jiān)視r(shí)eactive定義的某個(gè)屬性
watch(()=>person.job, (newValue,oldVaule)=>{
  consolo.log("person的job數(shù)據(jù)變化了", newValue,oldVaule)
}) 

//情況五疼燥,監(jiān)視r(shí)eactive定義的某些屬性
watch([()=>person.job,()=>person.name], (newValue,oldVaule)=>{
  consolo.log("person的job或者name數(shù)據(jù)變化了", newValue,oldVaule)
})

//特殊情況
watch([()=>person.job,()=>person.name], (newValue,oldVaule)=>{
  consolo.log("person的job或者name數(shù)據(jù)變化了", newValue,oldVaule)
}, {deep:true}) //此處由于監(jiān)視的是 reactive 定義中的某個(gè)屬性沧卢,所以 deep配置有效。

8.3 watchEffect 函數(shù)

  1. watch 函數(shù)的套路:既要指明監(jiān)視的屬性醉者,也要指明監(jiān)視的回調(diào)
  2. watchEffect 函數(shù)的套路是:不用指明監(jiān)視那個(gè)屬性但狭,監(jiān)視的回調(diào)中用到那個(gè)屬性,那就監(jiān)視那個(gè)屬性撬即。
  3. watchEffect有點(diǎn)像 computed:
  • 但是 computed 注重的計(jì)算出來的值(回調(diào)函數(shù)返回值)立磁,所以必須要寫返回值。
  • 而 watchEffect 更注重的是過程(回調(diào)函數(shù)的函數(shù)體)剥槐,所以不用寫返回值唱歧。
//watchEffect所指定的回調(diào)中用到的數(shù)據(jù)只要發(fā)生變化,則直接重新執(zhí)行回調(diào)
watchEffect(()=>{
  const x = sum.value
  const x2 = person.age
  console.log("watchEffect配置的回調(diào)執(zhí)行了")
})
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末粒竖,一起剝皮案震驚了整個(gè)濱河市颅崩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蕊苗,老刑警劉巖沿后,帶你破解...
    沈念sama閱讀 212,080評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異朽砰,居然都是意外死亡尖滚,警方通過查閱死者的電腦和手機(jī)喉刘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來漆弄,“玉大人睦裳,你說我怎么就攤上這事『惩伲” “怎么了廉邑?”我有些...
    開封第一講書人閱讀 157,630評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長券坞。 經(jīng)常有香客問我鬓催,道長,這世上最難降的妖魔是什么恨锚? 我笑而不...
    開封第一講書人閱讀 56,554評(píng)論 1 284
  • 正文 為了忘掉前任宇驾,我火速辦了婚禮,結(jié)果婚禮上猴伶,老公的妹妹穿的比我還像新娘课舍。我一直安慰自己,他們只是感情好他挎,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評(píng)論 6 386
  • 文/花漫 我一把揭開白布筝尾。 她就那樣靜靜地躺著,像睡著了一般办桨。 火紅的嫁衣襯著肌膚如雪筹淫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,856評(píng)論 1 290
  • 那天呢撞,我揣著相機(jī)與錄音损姜,去河邊找鬼。 笑死殊霞,一個(gè)胖子當(dāng)著我的面吹牛摧阅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播绷蹲,決...
    沈念sama閱讀 39,014評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼棒卷,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了祝钢?” 一聲冷哼從身側(cè)響起比规,我...
    開封第一講書人閱讀 37,752評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拦英,沒想到半個(gè)月后蜒什,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,212評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡龄章,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評(píng)論 2 327
  • 正文 我和宋清朗相戀三年吃谣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片做裙。...
    茶點(diǎn)故事閱讀 38,687評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡岗憋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出锚贱,到底是詐尸還是另有隱情仔戈,我是刑警寧澤,帶...
    沈念sama閱讀 34,347評(píng)論 4 331
  • 正文 年R本政府宣布拧廊,位于F島的核電站监徘,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏吧碾。R本人自食惡果不足惜凰盔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評(píng)論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望倦春。 院中可真熱鬧户敬,春花似錦、人聲如沸睁本。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呢堰。三九已至抄瑟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間枉疼,已是汗流浹背皮假。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留往衷,地道東北人钞翔。 一個(gè)月前我還...
    沈念sama閱讀 46,406評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像席舍,于是被迫代替她去往敵國和親布轿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評(píng)論 2 349

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