自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Vue3.0 最新動(dòng)態(tài):script-setup 定稿,部分實(shí)驗(yàn)性 API 將棄用

開(kāi)發(fā) 前端
雖然截止至 7 月 2 日的 3.1.4 版本,script-setup 還是處于實(shí)驗(yàn)性階段,但在同一天,尤大在 twitter[2] 上發(fā)布了一條推文,預(yù)告了它將會(huì)在 3.2.0 版本脫離實(shí)驗(yàn)狀態(tài),正式進(jìn)入 Vue 3.0 的隊(duì)伍。

 [[413042]]

最近一段時(shí)間挺忙,對(duì) Vue 3.0 的更新記錄看的比較少,今天看了一下 release 記錄,發(fā)現(xiàn)最新的 2 個(gè)小版本對(duì) script-setup 這個(gè)新特性改動(dòng)還算蠻大的,之前的用法都調(diào)整了不少。今天距離上一次發(fā)文討論 script-setup 新特性已經(jīng)有 4 個(gè)多月了(回顧上一篇[1]),雖然截止至 7 月 2 日的 3.1.4 版本,script-setup 還是處于實(shí)驗(yàn)性階段,但在同一天,尤大在 twitter[2] 上發(fā)布了一條推文,預(yù)告了它將會(huì)在 3.2.0 版本脫離實(shí)驗(yàn)狀態(tài),正式進(jìn)入 Vue 3.0 的隊(duì)伍。

先簡(jiǎn)單梳理一下本次定稿下來(lái)的一些調(diào)整:

useContext API 被棄用

在原先,可以通過(guò)該 API 來(lái)獲取組件的上下文信息,包含了 attrs 、slots 、emit、expose 等父子組件通信數(shù)據(jù)和方法。 

  1. // 導(dǎo)入 useContext 組件  
  2. import { useContext } from "vue";  
  3. // 獲取 context  
  4. const ctx = useContext(); 

該 API 將在 3.2 版本之后刪除,context 里面的數(shù)據(jù),會(huì)用新的 useSlots 和 useAttrs API 來(lái)代替。

新增 useSlots API 和 useAttrs API

在 useContext API 被刪除后,原先的上下文數(shù)據(jù),將由這兩個(gè)新 API 獲取到。

useAttrs

顧名思義, useAttrs 可以是用來(lái)獲取 attrs 數(shù)據(jù)的(也就是非 props 的屬性值)。 

  1. // 導(dǎo)入 useAttrs 組件  
  2. import { useAttrs } from "vue"; 
  3. // 獲取 attrs  
  4. const attrs = useAttrs();  
  5. // attrs是個(gè)對(duì)象,和 props 一樣,需要通過(guò) key 來(lái)得到對(duì)應(yīng)的單個(gè) attr  
  6. console.log(attrs.msg); 

如果當(dāng)前組件里沒(méi)有將某個(gè)屬性指定為 props,那么父組件綁定下來(lái)的屬性值,都會(huì)進(jìn)入到 attrs 里,通過(guò)這個(gè)新 API 來(lái)拿到。

useSlots

同樣,通過(guò) API 的命名也能了解它是用來(lái)獲取插槽數(shù)據(jù)的。但這個(gè) API 對(duì)大部分同學(xué)來(lái)說(shuō)應(yīng)該用的比較少,因?yàn)榇蟛糠?Vue 開(kāi)發(fā)者應(yīng)該都是用的 SFC 模式(單組件),插槽可以直接在 template 里使用 <slot /> 標(biāo)簽渲染。所以,我個(gè)人覺(jué)得這個(gè) API 的目標(biāo)用戶是面向 JSX / TSX 的開(kāi)發(fā)者,簡(jiǎn)單的用法參考如下:父組件,可以傳入默認(rèn)插槽和命名插槽: 

  1. <template>  
  2.   <!-- 子組件 -->  
  3.   <ChildTSX>  
  4.     <!-- 默認(rèn)插槽 -->  
  5.     <p>I am a default slot from TSX.</p>  
  6.     <!-- 默認(rèn)插槽 -->  
  7.     <!-- 命名插槽 -->  
  8.     <template #msg>  
  9.       <p>I am a msg slot from TSX.</p>  
  10.     </template>  
  11.     <!-- 命名插槽 -->  
  12.   </ChildTSX>  
  13.   <!-- 子組件 -->  
  14. </template>  
  15. <script setup lang="ts">  
  16.   import ChildTSX from "@cp/context/Child.tsx";  
  17. </script> 

那么在 JSX / TSX 的子組件,通過(guò) useSlots 來(lái)獲取父組件傳進(jìn)來(lái)的 slots 數(shù)據(jù)進(jìn)行渲染: 

  1. import { defineComponent, useSlots } from "vue";  
  2. const ChildTSX = defineComponent({  
  3.   setup() {  
  4.     // 獲取插槽數(shù)據(jù)  
  5.     const slots = useSlots();  
  6.     // 渲染組件  
  7.     return () => (  
  8.       <div>  
  9.         // 渲染默認(rèn)插槽  
  10.         <p>{slots.default ? slots.default() : ""}</p>  
  11.         // 渲染命名插槽  
  12.         <p>{slots.msg ? slots.msg() : ""}</p>  
  13.       </div>  
  14.     );  
  15.   },  
  16. });  
  17. export default ChildTSX; 

新增 defineExpose API

在標(biāo)準(zhǔn)組件寫(xiě)法里,子組件的數(shù)據(jù)都是默認(rèn)隱式暴露給父組件的,但在 script-setup 模式下,所有數(shù)據(jù)只是默認(rèn) return 給 template 使用,不會(huì)暴露到組件外,所以父組件是無(wú)法直接通過(guò)掛載 ref 變量獲取子組件的數(shù)據(jù)。如果要調(diào)用子組件的數(shù)據(jù),需要先在子組件顯示的暴露出來(lái),才能夠正確的拿到,這個(gè)操作,就是由 expose 來(lái)完成。expose 也是 context 的一個(gè)組件成員,原來(lái)的用法,是從 useContext 里導(dǎo)出: 

  1. // 導(dǎo)入 useContext 組件  
  2. import { useContext } from "vue";  
  3. // 啟用expose組件  
  4. const { expose } = useContext();  
  5. // 定義一個(gè)想提供給父組件拿到的數(shù)據(jù)  
  6. const msg: string = "Hello World!" 
  7. // 顯示暴露的數(shù)據(jù),才可以在父組件拿到  
  8. expose({  
  9.   msg,  
  10. }); 

由于 useContext 會(huì)在未來(lái)版本里移除,所以新增了 defineExpose API 來(lái)實(shí)現(xiàn) expose 的功能。新的 API 用法: 

  1. // 導(dǎo)入 defineExpose 組件  
  2. import { defineExpose } from "vue";  
  3. // 定義數(shù)據(jù)  
  4. const msg: string = "Hello World!" 
  5. // 暴露給父組件  
  6. defineExpose({  
  7.   msg,  
  8. }); 

父組件就可以通過(guò) ref API 去拿到子組件暴露出來(lái)的 msg 數(shù)據(jù)了。

改名 defineEmits API

使用 defineEmits 取待原來(lái)的 defineEmit API ,也就是改名了。好吧,我之前的文章還特地強(qiáng)調(diào)了 defineProps 是復(fù)數(shù)結(jié)尾,帶有 s,而 defineEmit 沒(méi)有,如今,都統(tǒng)一了,都是復(fù)數(shù)形式。從尤大的更新說(shuō)明里看,大約只是一個(gè) typo 更新,對(duì)比原來(lái)的 defineEmit ,目的是使用新的 defineEmits 與標(biāo)準(zhǔn)組件的 emits 命名上更為接近,和 defineProps 也更統(tǒng)一。╮(╯▽╰)╭ 所以用法方面和原來(lái)是沒(méi)什么區(qū)別的: 

  1. // 導(dǎo)入 defineEmits 組件  
  2. import { defineEmits } from "vue";  
  3. // 獲取 emit  
  4. const emit = defineEmits(["say-hi", "chang-name"]);  
  5. // 調(diào)用 emit 打招呼  
  6. emit("say-hi", "Hello!");  
  7. // 調(diào)用 emit 改名  
  8. emit("chang-name", "Tom"); 

新增 withDefaults API

說(shuō)完 emits,經(jīng)常與之同時(shí)出現(xiàn)的 props 也有一些變化,本次是帶來(lái)了一個(gè)全新的 withDefaults API,用于輔助 defineProps 來(lái)指定 prop 的默認(rèn)值。在以前的文章我有提及到,當(dāng)你用 TypeScript 編程時(shí),defineProps 有兩種類型指定方式:

    1.  通過(guò)構(gòu)造函數(shù)進(jìn)行檢查(傳統(tǒng)方法)

第一種方式是使用 JavaScript 原生構(gòu)造函數(shù)進(jìn)行類型規(guī)定,使用這種方法時(shí),如果你要限制 props 的類型和默認(rèn)值,需要通過(guò)一個(gè) “對(duì)象” 入?yún)?lái)傳遞給 defineProps,比如: 

  1. // 導(dǎo)入 defineProps 組件  
  2. import { defineProps } from "vue"; 
  3.  // 定義 props  
  4. defineProps({  
  5.   name: {  
  6.     type: String,  
  7.     required: false,  
  8.     default: "Petter",  
  9.   },  
  10.   userInfo: Object,  
  11.   tags: Array,  
  12. }); 

    1.  使用類型注解進(jìn)行檢查(TS 專屬)

第二種方式是按照 TS 的書(shū)寫(xiě)習(xí)慣來(lái)定義數(shù)據(jù)類型,這種情況下需要遵循 TypeScript 的類型規(guī)范,比如字符串是 string,而不是 String。 

  1. // 導(dǎo)入 defineProps 組件  
  2. import { defineProps } from "vue";  
  3. // 對(duì)象類型接口  
  4. interface UserInfo {  
  5.   id: number;  
  6.   age: number;  
  7.  
  8. // 定義 props  
  9. defineProps< 
  10.   name: string;  
  11.   phoneNumber: number;  
  12.   userInfo: UserInfo;  
  13.   tags: string[];  
  14. }>();import { defineProps, withDefaults } from "vue";  
  15. withDefaults(  
  16.   defineProps< 
  17.     size?: number;  
  18.     labels?: string[];  
  19.   }>(),  
  20.   {  
  21.     size: 3,  
  22.     labels: () => ["default label"],  
  23.   }  
  24. );  
  25. import { defineProps, withDefaults } from "vue";  
  26. withDefaults( 
  27.    defineProps< 
  28.     size?: number;  
  29.     labels?: string[];  
  30.   }>(),  
  31.   {  
  32.     size: 3,  
  33.     labels: () => ["default label"],  
  34.   }  
  35. ); 

在此之前,使用第二種方法,是無(wú)法指定默認(rèn)值的(在當(dāng)時(shí)的 RFC 的文檔里也有說(shuō)明無(wú)法指定)。如今,這個(gè)新的 withDefaults API 可以讓你在使用 TS 類型系統(tǒng)時(shí),也可以指定 props 的默認(rèn)值。它接收兩個(gè)入?yún)ⅲ?/p>

可能缺乏一些官方描述,還是看參考用法可能更直觀: 

  1. import { defineProps, withDefaults } from "vue";  
  2. withDefaults(  
  3.   defineProps< 
  4.     size?: number;  
  5.     labels?: string[];  
  6.   }>(),  
  7.   {  
  8.     size: 3,  
  9.     labels: () => ["default label"],  
  10.   }  
  11. ); 

頂級(jí) await 的支持

不必再配合 async 就可以直接使用 await 了,這種情況下,組件的 setup 會(huì)自動(dòng)變成 async setup 。 

  1. <script setup lang="ts">  
  2.   const post = await fetch(`/api/post/1`).then((r) => r.json());  
  3. </script> 

它轉(zhuǎn)換成標(biāo)準(zhǔn)組件的寫(xiě)法就是: 

  1. <script lang="ts">  
  2.   import { defineComponent, withAsyncContext } from "vue"; 
  3.    export default defineComponent({  
  4.     async setup() {  
  5.       const post = await withAsyncContext(  
  6.         fetch(`/api/post/1`).then((r) => r.json())  
  7.       );  
  8.       return {  
  9.         post,  
  10.       };  
  11.     },  
  12.   });  
  13. </script> 

參考資料

以上所有的資料都來(lái)自于尤大在 PR 227 的評(píng)論通告……傳送門(mén):script setup by yyx990803 · Pull Request #227 · vuejs/rfcsgithub.com[3]好隱蔽的說(shuō),而且原來(lái)的 RFC 倉(cāng)庫(kù)的文檔也刪除了,換了新的文檔也是找了好久才翻到新的,本文先根據(jù)尤大的通告做一波簡(jiǎn)單的說(shuō)明,文章首發(fā)在博客,只同步在知乎。Vue3.0 最新動(dòng)態(tài):script-setup 定稿 部分實(shí)驗(yàn)性 API 將棄用 - 程沛權(quán) - 養(yǎng)了三只貓 chengpeiquan.com[4]后續(xù)將會(huì)詳細(xì)更新到 Vue3.0 學(xué)習(xí)教程與實(shí)戰(zhàn)案例[5] 里。 

 

責(zé)任編輯:龐桂玉 來(lái)源: 前端大全
相關(guān)推薦

2020-10-13 08:24:31

Vue3.0系列

2022-08-04 14:38:49

vue3.2setup代碼

2023-05-11 08:57:49

ReactHooks

2023-09-13 15:16:50

2022-02-06 22:13:47

VueVue3.0Vue項(xiàng)目

2020-08-25 09:50:35

Vue3.0命令前端

2021-09-26 00:24:58

開(kāi)發(fā)項(xiàng)目TypeScript

2009-11-30 10:15:12

DellChrome OS鏡像

2022-07-27 11:59:45

Vue3Suspense

2023-12-04 18:24:17

WaylandLinux

2020-09-28 15:48:37

開(kāi)源技術(shù) 軟件

2020-04-20 12:40:12

Vue 3.0 BetReact開(kāi)發(fā)者

2020-12-03 18:29:30

KubernetesDocker容器

2022-02-18 09:39:51

Vue3.0Vue2.0Script Set

2020-09-18 14:01:21

vue3.0

2021-04-02 10:30:18

Vue3.0前端代碼

2022-05-09 13:25:27

Vue3.0前端

2019-10-30 14:31:47

Vue 3.0數(shù)組響應(yīng)

2021-11-22 11:05:20

Vue 3setup前端

2011-03-23 09:40:37

Google GearChrome
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)