真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Vue3中如何使用TypeScript

這篇文章主要介紹“Vue3中如何使用TypeScript”,在日常操作中,相信很多人在Vue3中如何使用TypeScript問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Vue3中如何使用TypeScript”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

創(chuàng)新互聯(lián)是一家專注于成都做網(wǎng)站、網(wǎng)站制作、成都外貿(mào)網(wǎng)站建設(shè)與策劃設(shè)計(jì),永仁網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十多年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:永仁等地區(qū)。永仁做網(wǎng)站價(jià)格咨詢:028-86922220

如何聲明字段名為枚舉的類型?

根據(jù)設(shè)計(jì),type 字段應(yīng)該是一個(gè)枚舉值,不應(yīng)該由調(diào)用方隨意設(shè)置。

下面是 Type 的枚舉聲明,共有 6 個(gè)字段。

enum Type {    primary = "primary",    success = "success",    warning = "warning",    warn = "warn", // warning alias    danger = "danger",    info = "info",  }

TypeScript 中聲明類型的關(guān)鍵字有兩個(gè),interface 和 type,在聲明 key 不確定類型的字段時(shí)稍有不同。

使用 type 進(jìn)行聲明:

type ColorConfig = {    [key in Type]: Colors;  };

使用 interface 卻只能像下面這樣:

interface ColorConfig {    [key: string]: Colors;  }

因?yàn)?interface 的索引只能是基礎(chǔ)類型,類型別名也不可以。而 type 的索引可以是復(fù)合類型。

Vue 3 如何獲取元素實(shí)例?

在 vue3 中,組件的邏輯可以放在 setup 函數(shù)里面,但是 setup 中不再有 this,所以 vue2 中的 this.$refs 的用法在 vue3 中無法使用。

新的用法是:

給元素添加 ref 屬性。

在 setup 中聲明與元素 ref 同名的變量。

在 setup 的 return 對(duì)象中將 ref 變量作為同名屬性返回。

在 onMounted 生命周期中訪問 ref 變量,既是元素實(shí)例。

第一步:

第二步:

const point = ref(null);

注意類型要填寫 HTMLDivElement,這樣才能享受類型推斷。

第三步:

return { point };

這一步必不可少,如果返回對(duì)象中不包含這個(gè)同名屬性,onMounted 中訪問的 ref 對(duì)象會(huì)是 null。

第四步:

onMounted(() => {    if (point?.value) {      // logic    }  });
如何操作偽類?

JavaScript 無法獲取到偽類元素,但是可以換一種思路。偽類樣式引用 css 變量,再通過 js 控制 css 變量來完成間接操作偽類的效果。

比如這是一個(gè)偽類:

.point-flicker:after {    background-color: var(--afterBg);  }

它依賴了 afterBg 變量。

如果需要修改它的內(nèi)容,只需要使用 js 操作 afterBg 的內(nèi)容即可。

point.value.style.setProperty("--bg", colorConfig[props.type].bg);

API 的變化

Vue3 中組件如何修改自身的 props?

有一種不是很常見的情況,需要組件修改父組件傳遞給自己的 Props。

比如抽屜組件、擬態(tài)框組件等。

在 vue2 中常見的用法是 sync 和 v-model。

vue3 中只推薦使用 v-model:xxx="" 的方式。

比如父組件傳遞:

子組件:

  
Vue3 中 watch 用法的變化

watch 變得更加簡(jiǎn)單。

import { watch } from "vue";  watch(source, (currentValue, oldValue) => {      // logic  });

當(dāng) source 變化時(shí)自動(dòng)執(zhí)行 watch 第二個(gè)參數(shù)所傳入的函數(shù)。

Vue3 中 computed 用法的變化

computed 也變得更加簡(jiǎn)單。

import { computed } from "vue"  const v = computed(() => {      return x  });

computed 返回的變量是一個(gè)響應(yīng)式對(duì)象。

Vue3 中組件循環(huán)自身的技巧

這是一種開發(fā)組件的技巧。

假設(shè)你有一個(gè)不確定深度的樹狀結(jié)構(gòu)數(shù)據(jù)。

{    "label": "root",    "children": [      {        "label": "a",        "children": [          {            "label": "a1",            "children": []          },          {            "label": "a2",            "children": []          }        ]      }    ]  }

它的類型定義如下:

export interface Menu {    id: string;    label: string;    children: Menu | null;  }

你需要實(shí)現(xiàn)一種樹狀組件來渲染它們。這時(shí)就需要用到這種技巧。

    import { defineComponent } from "vue";  export default defineComponent({    name: "Menu",    props: {      menu: {        type: Object,      },    },  });  

組件的 name 可以在自身中直接使用,而不需要在 component 中聲明。

一些坑

Vuex:慎用 Map

在 Vuex 中,我設(shè)計(jì)了一個(gè)數(shù)據(jù)結(jié)構(gòu)用于存儲(chǔ)模塊(業(yè)務(wù)概念)不同的狀態(tài)。

type Code = number;  export type ModuleState = Map;

但是我發(fā)現(xiàn)一個(gè)問題,當(dāng)我修改 Map 中某一個(gè) value 中的屬性時(shí),不會(huì)觸發(fā) Vuex 的監(jiān)聽。

所以我只好將數(shù)據(jù)結(jié)構(gòu)修改為對(duì)象的形式。

export type ModuleState = { [key in Code]: StateProperty };

ts 中索引不可以使用類型別名,但是可以寫成下面這樣:

type Code = number;  export type ModuleState = { [key in Code]: StateProperty };

除此之外,Map 還存在另外一個(gè)問題。

當(dāng)一個(gè) Map 類型的 Proxy 對(duì)象作為參數(shù)被傳遞時(shí),是無法使用 get、set、clear 等 Map 方法的,但是 TypeScript 會(huì)提示這些方法可用。如果使用了這些方法,會(huì)得到一個(gè) Uncaught TypeError。

如果使用 Object 則不會(huì)產(chǎn)生這個(gè)問題。

WebSocket 發(fā)生異常無法被 try catch 監(jiān)聽

ws 的異常只能在 onerror 和 onclose 兩個(gè)事件中進(jìn)行處理,try catch 是無法捕獲的。

有些時(shí)候,onerror 和 onclose 會(huì)連續(xù)執(zhí)行,比如觸發(fā) onerror,導(dǎo)致連接關(guān)閉,就會(huì)緊接著觸發(fā) onclose。

Vue Devtools

vue devtools 目前無法支持 Vue3,但是 vue devtools 幾乎是開發(fā)中必不可少的工具,目前可以使用 vue devtools beta 版本,但存在一些 Bug。

用法非常簡(jiǎn)單,安裝后重啟瀏覽器就可以。不需要設(shè)置 vue.config.devtools = true,在 vue3 中 vue.config 實(shí)例不存在 devtools 屬性。

ESbuild 安裝依賴

在使用 vite 啟動(dòng)服務(wù)的同時(shí)安裝依賴,非常容易碰到一個(gè)錯(cuò)誤。

Error: EBUSY: resource busy or locked, open 'E:\gxt\property-relay-fed\node_modules\esbuild\esbuild.exe'

這個(gè)問題的原因是 vite 依賴的編譯工具 esbuild.exe 被占用所導(dǎo)致的,解決方法很簡(jiǎn)單,就是停掉 vite,安裝完依賴后再重新啟動(dòng) vite。

Vite 在 Chrome 中調(diào)試的問題

系統(tǒng)中有一些移動(dòng)頁(yè)面,需要嵌入在 App 中使用。

常見的調(diào)試 WebView 的方法有兩種,一種簡(jiǎn)單的方式是使用騰訊開源的 vcosnole,另一種麻煩一些的調(diào)試方式是使用 Chrome 的 DevTools。

但是 vconsole 并沒有想象中那么好用。

所以我選擇使用 Chrome 調(diào)試,chrome://inspect/#devices

但是在調(diào)試過程中我發(fā)現(xiàn) Chrome 調(diào)試工具里面竟然運(yùn)行的是 TS 源碼,TS 的語(yǔ)法直接被認(rèn)為語(yǔ)法錯(cuò)誤。(我是使用 Vite 啟動(dòng)的開發(fā)服務(wù)。)

解決方案很簡(jiǎn)單,但挺 Low。先使用 vite build 把 TS 代碼編譯成 JS,再使用 vite preview 啟動(dòng)服務(wù)。

WebSocket

websocket 和 Vue3 沒什么關(guān)系,但是在這里簡(jiǎn)單提一下。

設(shè)備管理系統(tǒng)的核心概念是設(shè)備,設(shè)備會(huì)有很多屬性,在硬件上也被稱作數(shù)據(jù)點(diǎn)。這些屬性會(huì)經(jīng)歷非常長(zhǎng)的鏈路傳輸?shù)接脩艚缑嫔?。整體流程大概是:硬件通過 tcp 協(xié)議上傳到接入網(wǎng)關(guān),接入網(wǎng)關(guān)處理后再通過 mqtt 協(xié)議上傳到物聯(lián)網(wǎng)平臺(tái),物聯(lián)網(wǎng)平臺(tái)再經(jīng)過規(guī)則引擎處理,通過 webhook restful 的形式發(fā)送到業(yè)務(wù)系統(tǒng),業(yè)務(wù)系統(tǒng)再通過 websocket 推送到前端。

雖然數(shù)據(jù)通過層層編解碼、不同的協(xié)議繞了非常遠(yuǎn)的距離呈現(xiàn)到用戶面前,但是前端只需要關(guān)心 websocket 就足夠了。

WebSocket 重連

在做重連時(shí),需要注意 onerror 和 onclose 連續(xù)執(zhí)行的問題,通常是使用類似防抖的方法來解決。

我的做法是增加一個(gè)變量來控制重連次數(shù)。

let connecting = false; // 斷開連接后,先觸發(fā) onerror,再觸發(fā) onclose,主要用于防止重復(fù)觸發(fā)

conn();   function conn() {     connecting = false;     if (ctx.state.stateWS.instance && ctx.state.stateWS.instance.close) {       ctx.state.stateWS.instance.close();     }     const url = ctx.state.stateWS.url + "?Authorization=" + getAuthtication();     ctx.state.stateWS.instance = new WebSocket(url);     ctx.state.stateWS.instance.onopen = () => {       ctx.commit(ActionType.SUCCESS);     };     ctx.state.stateWS.instance.onclose = () => {       if (connecting) return;       ctx.commit(ActionType.CLOSE);       setTimeout(() => {         conn();       }, 10 * 1000);       connecting = true;     };    ctx.state.stateWS.instance.onerror = () => {       if (connecting) return;       ctx.commit(ActionType.ERROR);       setTimeout(() => {         conn();       }, 10 * 1000);       connecting = true;     };     ctx.state.stateWS.instance.onmessage = function (       this: WebSocket,       ev: MessageEvent     ) {       // logic       } catch (e) {         console.log("e:", e);       }     };   }
WebSocket 連接活動(dòng)日志

系統(tǒng)是設(shè)計(jì)成 7*24 小時(shí)不間斷運(yùn)行。所以 websocket 很容易受到一些網(wǎng)絡(luò)因素或者其它因素的影響發(fā)生斷開,重連是一項(xiàng)非常重要的功能,同時(shí)還應(yīng)該具備重連日志功能。

在用戶的不同環(huán)境中,排查 WebSocket 的連接狀態(tài)很麻煩,添加一個(gè)連接日志功能是比較不錯(cuò)的方案,這樣可以很好的看到不同時(shí)間的連接情況。

Vue3中如何使用TypeScript

image.png

需要注意,這些日志是存儲(chǔ)在用戶的瀏覽器內(nèi)存中的,需要設(shè)置上限,到達(dá)上限要自動(dòng)清除早期日志。

WebSocket 鑒權(quán)

websocket 的鑒權(quán)是很多人容易忽視的一個(gè)點(diǎn)。

我在系統(tǒng)設(shè)計(jì)中,restful API 的鑒權(quán)是通過在 request header 上附帶 Authorization 字段,設(shè)置生成的 JWT 來實(shí)現(xiàn)的。

websocket 無法設(shè)置 header,但是可以設(shè)置 query,實(shí)現(xiàn)思路類似 restful 的認(rèn)證設(shè)計(jì)。

關(guān)于 ws 鑒權(quán)的過期、續(xù)期、權(quán)限等問題,和 restful 保持一致即可。

script setup:更加清爽的 API

script setup 至今仍是一個(gè)實(shí)驗(yàn)性特性,但它確實(shí)非常清爽。

單文件組件的 setup 常規(guī)用法像下面這樣:

 import { defineComponent } from 'vue'  export default defineComponent({   setup () {      return {}    }  })  

使用 script setup 后,代碼變成了下面這樣:

    

在 sciprt 標(biāo)簽中的頂層變量、函數(shù)都會(huì) return 出去。

在這種模式下,減少了大量代碼,可以提高開發(fā)效率、降低心智負(fù)擔(dān)。

但這時(shí)也存在幾個(gè)問題,比如在 script setup 中怎么使用生命周期和 watch/computed 函數(shù)?怎么使用組件?怎么獲取 props 和 context?

使用組件

直接導(dǎo)入組件后,vue 會(huì)自動(dòng)識(shí)別,無需使用 component 掛載。

    import C from "component"  
使用生命周期和監(jiān)聽計(jì)算函數(shù)

和標(biāo)準(zhǔn)寫法基本無差異。

    import { watch, computed, onMounted } from "vue"  
使用 props 和 context

由于 setup 被提升到 script 標(biāo)簽上了,自然也就沒辦法接收 props 和 context 這兩個(gè)參數(shù)。

所以 vue 提供了 defineProps、defineEmit、useContext 函數(shù)。

defineProps

defineProps 的用法和 OptionsAPI 中的 props 用法幾乎一致。

  import { defineProps } from "vue";  interface Props {    moduleID: string;  }  const props = defineProps(["moduleID"]);  console.log(props.moduleID);  

defineEmit

defineEmit 的用法和 OptionsAPI 中的 emit 用法也幾乎一致。

  import { defineEmit } from "vue";  const emit = defineEmit(["select"]);  console.log(emit("select"));  

emit 的第一個(gè)參數(shù)是事件名稱,后面支持傳遞不定個(gè)數(shù)的參數(shù)。

useContext

useContext 是一個(gè) hook 函數(shù),返回 context 對(duì)象。

const ctx = useContext()
原理

原理相當(dāng)簡(jiǎn)單。增加了一層編譯過程,將 script setup 編譯成標(biāo)準(zhǔn)模式的代碼。

但是實(shí)現(xiàn)上有非常多的細(xì)節(jié),所以導(dǎo)致至今仍未推出正式版。

Vue3 Composition 所帶來的模塊化開發(fā)方式

這套技術(shù)棧帶給我最深的感受還是開發(fā)方式上的變化。

在 Vue2 的開發(fā)中,Options API 在面對(duì)業(yè)務(wù)邏輯復(fù)雜的頁(yè)面時(shí)非常吃力。當(dāng)邏輯長(zhǎng)達(dá)千行時(shí),追蹤一個(gè)變量的變化是一件非常頭痛的事情。

但是有了 Composition API 后,這將不再是問題,它帶來了一種全新的開發(fā)方式,雖然有種 React 的感覺,但這相比之前已經(jīng)非常棒了!

這項(xiàng)目中所有的頁(yè)面,我都使用 hooks 的方式開發(fā)。

在設(shè)備模塊中,我的 js 代碼是這樣的。

  import { defineComponent, toRefs } from "vue";  import { useDeviceCreate } from "./create";  import { useDeviceQuery } from "./query";  import { useDeviceDelete } from "./delete";  import { useUnbind } from "./unbind";  import { useBind } from "./bind";  import { useDeviceEdit } from "./edit";  import { useState } from "./state";  import { useAssign } from "./assign";  export default defineComponent({    setup() {      const queryObj = useDeviceQuery();      const { query, devices } = queryObj;      const reload = query;      return {        ...toRefs(useDeviceCreate(reload)),        ...toRefs(queryObj),        ...toRefs(useDeviceDelete(reload)),        ...toRefs(useUnbind(reload)),        ...toRefs(useBind(reload)),        ...toRefs(useDeviceEdit(reload)),        ...toRefs(useState(devices)),        ...toRefs(useAssign()),      };    },  });  

每個(gè)模塊各司其職,各自有自己的內(nèi)部數(shù)據(jù),各個(gè)模塊如果需要共享數(shù)據(jù),可以通過 Vuex,或者在頂層組件的 setup 中傳遞,比如上面的 reload 函數(shù)。

我的目錄結(jié)構(gòu)是這樣的。

Vue3中如何使用TypeScript

到此,關(guān)于“Vue3中如何使用TypeScript”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!


網(wǎng)頁(yè)題目:Vue3中如何使用TypeScript
URL分享:http://weahome.cn/article/iihecc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部