搜尋
首頁web前端Vue.jsVue3中怎麼使用TypeScript

如何宣告欄位名為枚舉的型別?

根據設計,type 欄位應該是一個枚舉值,不應該由呼叫方隨意設定。

下面是 Type 的枚舉聲明,共有 6 個欄位。

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

TypeScript 中聲明類型的關鍵字有兩個,interface 和 type,在聲明 key 不確定類型的欄位時稍有不同。

使用 type 進行宣告:

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

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

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

因為 interface 的索引只能是基礎類型,類型別名也不可以。而 type 的索引可以是複合型別。

Vue 3 如何取得元素實例?

在 vue3 中,元件的邏輯可以放在 setup 函數裡面,但是 setup 中不再有 this,所以 vue2 中的 this.$refs 的用法在 vue3 中無法使用。

新的用法是:

為元素新增 ref 屬性。

在 setup 中宣告與元素 ref 同名的變數。

在 setup 的 return 物件中將 ref 變數作為同名屬性傳回。

在 onMounted 生命週期中存取 ref 變量,既是元素實例。

第一步:

<div></div>

第二步:

const point = ref<htmldivelement>(null);</htmldivelement>

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

第三步:

return { point };

這一步必不可少,如果傳回物件中不包含這個同名屬性,onMounted 中存取的 ref 物件會是 null。

第四步:

onMounted(() => {    if (point?.value) {      // logic    }  });

如何操作偽類?

JavaScript 無法取得到偽類元素,但是可以換個想法。偽類樣式引用 css 變量,再透過 js 控制 css 變數來完成間接操作偽類的效果。

例如這是一個偽類別:

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

它依賴了 afterBg 變數。

如果需要修改它的內容,只需要使用 js 操作 afterBg 的內容。

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

API 的變更

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

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

例如抽屜組件、擬態框組件等。

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

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

例如父元件傳遞:

<ws-log></ws-log>

子元件:

<template>      <div>      ...     </div>  </template>  <script>  // ...   props: {      visible: {        type: Boolean,      },    },  </script>

Vue3 中 watch 用法的變化

watch 變得更簡單。

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

當 source 變更時自動執行 watch 第二個參數所傳入的函數。

Vue3 中 computed 用法的變化

computed 也變得更簡單。

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

computed 傳回的變數是一個響應式物件。

Vue3 中元件循環本身的技巧

這是一種開發元件的技巧。

假設你有一個不確定深度的樹狀結構資料。

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

它的類型定義如下:

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

你需要實作一個樹狀元件來渲染它們。這時就需要用到這種技巧。

<template>      <div>{{ menu.label }}</div>      <menu></menu>  </template>  <script>  import { defineComponent } from "vue";  export default defineComponent({    name: "Menu",    props: {      menu: {        type: Object,      },    },  });  </script>

元件的 name 可以在自身中直接使用,而不需要在 component 中宣告。

一些坑

Vuex:慎用 Map

在 Vuex 中,我設計了一個資料結構來儲存模組(商業概念)不同的狀態。

type Code = number;  export type ModuleState = Map<code>;</code>

但我發現一個問題,當我修改 Map 中某一個 value 中的屬性時,不會觸發 Vuex 的監聽。

所以我只好將資料結構修改為物件的形式。

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

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

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

除此之外,Map 還存在另一個問題。

當一個 Map 類型的 Proxy 物件被傳遞為參數時,是無法使用 get、set、clear 等 Map 方法的,但是 TypeScript 會提示這些方法可用。如果使用了這些方法,會得到一個 Uncaught TypeError。

如果使用 Object 就不會產生這個問題。

WebSocket 發生異常無法被 try catch 監聽

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

有些時候,onerror 和 onclose 會連續執行,例如觸發 onerror,導致連線關閉,就會緊接著觸發 onclose。

Vue Devtools

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

用法非常簡單,安裝後重新啟動瀏覽器就可以。不需要設定 vue.config.devtools = true,在 vue3 中 vue.config 實例不存在 devtools 屬性。

ESbuild 安裝依賴

在使用 vite 啟動服務的同時安裝依賴,非常容易碰到一個錯誤。

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

這個問題的原因是 vite 依賴的編譯工具 esbuild.exe 被佔用所導致的,解決方法很簡單,就是停掉 vite,安裝完依賴後再重新啟動 vite。

Vite 在 Chrome 中偵錯的問題

系統中有一些行動頁面,需要嵌入在 App 中使用。

常见的调试 WebView 的方法有两种,一种简单的方式是使用腾讯开源的 vcosnole,另一种麻烦一些的调试方式是使用 Chrome 的 DevTools。

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

所以我选择使用 Chrome 调试,chrome://inspect/#devices

但是在调试过程中我发现 Chrome 调试工具里面竟然运行的是 TS 源码,TS 的语法直接被认为语法错误。(我是使用 Vite 启动的开发服务。)

解决方案很简单,但挺 Low。先使用 vite build 把 TS 代码编译成 JS,再使用 vite preview 启动服务。

WebSocket

websocket 和 Vue3 没什么关系,但是在这里简单提一下。

设备管理系统的核心概念是设备,设备会有很多属性,在硬件上也被称作数据点。这些属性会经历非常长的链路传输到用户界面上。整体流程大概是:硬件通过 tcp 协议上传到接入网关,接入网关处理后再通过 mqtt 协议上传到物联网平台,物联网平台再经过规则引擎处理,通过 webhook restful 的形式发送到业务系统,业务系统再通过 websocket 推送到前端。

虽然数据通过层层编解码、不同的协议绕了非常远的距离呈现到用户面前,但是前端只需要关心 websocket 就足够了。

WebSocket 重连

在做重连时,需要注意 onerror 和 onclose 连续执行的问题,通常是使用类似防抖的方法来解决。

我的做法是增加一个变量来控制重连次数。

let connecting = false; // 断开连接后,先触发 onerror,再触发 onclose,主要用于防止重复触发

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 连接活动日志

系统是设计成 7*24 小时不间断运行。所以 websocket 很容易受到一些网络因素或者其它因素的影响发生断开,重连是一项非常重要的功能,同时还应该具备重连日志功能。

在用户的不同环境中,排查 WebSocket 的连接状态很麻烦,添加一个连接日志功能是比较不错的方案,这样可以很好的看到不同时间的连接情况。

Vue3中怎麼使用TypeScript

image.png

需要注意,这些日志是存储在用户的浏览器内存中的,需要设置上限,到达上限要自动清除早期日志。

WebSocket 鉴权

websocket 的鉴权是很多人容易忽视的一个点。

我在系统设计中,restful API 的鉴权是通过在 request header 上附带 Authorization 字段,设置生成的 JWT 来实现的。

websocket 无法设置 header,但是可以设置 query,实现思路类似 restful 的认证设计。

关于 ws 鉴权的过期、续期、权限等问题,和 restful 保持一致即可。

script setup:更加清爽的 API

script setup 至今仍是一个实验性特性,但它确实非常清爽。

单文件组件的 setup 常规用法像下面这样:

<script> import { defineComponent } from &#39;vue&#39;  export default defineComponent({   setup () {      return {}    }  })  </script>

使用 script setup 后,代码变成了下面这样:

<script>    </script>

在 sciprt 标签中的顶层变量、函数都会 return 出去。

在这种模式下,减少了大量代码,可以提高开发效率、降低心智负担。

但这时也存在几个问题,比如在 script setup 中怎么使用生命周期和 watch/computed 函数?怎么使用组件?怎么获取 props 和 context?

使用组件

直接导入组件后,vue 会自动识别,无需使用 component 挂载。

<script>    import C from "component"  </script>

使用生命周期和监听计算函数

和标准写法基本无差异。

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

使用 props 和 context

由于 setup 被提升到 script 标签上了,自然也就没办法接收 props 和 context 这两个参数。

所以 vue 提供了 defineProps、defineEmit、useContext 函数。

defineProps

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

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

defineEmit

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

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

emit 的第一个参数是事件名称,后面支持传递不定个数的参数。

useContext

useContext 是一个 hook 函数,返回 context 对象。

const ctx = useContext()

原理

原理相当简单。增加了一层编译过程,将 script setup 编译成标准模式的代码。

但是实现上有非常多的细节,所以导致至今仍未推出正式版。

Vue3 Composition 所带来的模块化开发方式

这套技术栈带给我最深的感受还是开发方式上的变化。

在 Vue2 的开发中,Options API 在面对业务逻辑复杂的页面时非常吃力。当逻辑长达千行时,追踪一个变量的变化是一件非常头痛的事情。

但是有了 Composition API 后,这将不再是问题,它带来了一种全新的开发方式,虽然有种 React 的感觉,但这相比之前已经非常棒了!

这项目中所有的页面,我都使用 hooks 的方式开发。

在设备模块中,我的 js 代码是这样的。

<script>  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()),      };    },  });  </script>

每个模块各司其职,各自有自己的内部数据,各个模块如果需要共享数据,可以通过 Vuex,或者在顶层组件的 setup 中传递,比如上面的 reload 函数。

我的目录结构是这样的。

Vue3中怎麼使用TypeScript

以上是Vue3中怎麼使用TypeScript的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:亿速云。如有侵權,請聯絡admin@php.cn刪除
Netflix的前端:React(或VUE)的示例和應用Netflix的前端:React(或VUE)的示例和應用Apr 16, 2025 am 12:08 AM

Netflix使用React作為其前端框架。 1)React的組件化開發模式和強大生態系統是Netflix選擇它的主要原因。 2)通過組件化,Netflix將復雜界面拆分成可管理的小塊,如視頻播放器、推薦列表和用戶評論。 3)React的虛擬DOM和組件生命週期優化了渲染效率和用戶交互管理。

前端景觀:Netflix如何處理其選擇前端景觀:Netflix如何處理其選擇Apr 15, 2025 am 12:13 AM

Netflix在前端技術上的選擇主要集中在性能優化、可擴展性和用戶體驗三個方面。 1.性能優化:Netflix選擇React作為主要框架,並開發了SpeedCurve和Boomerang等工具來監控和優化用戶體驗。 2.可擴展性:他們採用微前端架構,將應用拆分為獨立模塊,提高開發效率和系統擴展性。 3.用戶體驗:Netflix使用Material-UI組件庫,通過A/B測試和用戶反饋不斷優化界面,確保一致性和美觀性。

React與Vue:Netflix使用哪個框架?React與Vue:Netflix使用哪個框架?Apr 14, 2025 am 12:19 AM

NetflixusesAcustomFrameworkcalled“ Gibbon” BuiltonReact,notReactorVuedIrectly.1)TeamSperience:selectBasedonFamiliarity.2)ProjectComplexity:vueforsimplerprojects:reactforforforproproject,reactforforforcompleplexones.3)cocatizationneedneeds:reactoffipicatizationneedneedneedneedneedneeds:reactoffersizationneedneedneedneedneeds:reactoffersizatization needefersmoreflexibleise.4)

框架的選擇:是什麼推動了Netflix的決定?框架的選擇:是什麼推動了Netflix的決定?Apr 13, 2025 am 12:05 AM

Netflix在框架選擇上主要考慮性能、可擴展性、開發效率、生態系統、技術債務和維護成本。 1.性能與可擴展性:選擇Java和SpringBoot以高效處理海量數據和高並發請求。 2.開發效率與生態系統:使用React提升前端開發效率,利用其豐富的生態系統。 3.技術債務與維護成本:選擇Node.js構建微服務,降低維護成本和技術債務。

反應,vue和Netflix前端的未來反應,vue和Netflix前端的未來Apr 12, 2025 am 12:12 AM

Netflix主要使用React作為前端框架,輔以Vue用於特定功能。 1)React的組件化和虛擬DOM提升了Netflix應用的性能和開發效率。 2)Vue在Netflix的內部工具和小型項目中應用,其靈活性和易用性是關鍵。

前端中的vue.js:現實世界的應用程序和示例前端中的vue.js:現實世界的應用程序和示例Apr 11, 2025 am 12:12 AM

Vue.js是一種漸進式JavaScript框架,適用於構建複雜的用戶界面。 1)其核心概念包括響應式數據、組件化和虛擬DOM。 2)實際應用中,可以通過構建Todo應用和集成VueRouter來展示其功能。 3)調試時,建議使用VueDevtools和console.log。 4)性能優化可通過v-if/v-show、列表渲染優化和異步加載組件等實現。

vue.js和React:了解關鍵差異vue.js和React:了解關鍵差異Apr 10, 2025 am 09:26 AM

Vue.js適合小型到中型項目,而React更適用於大型、複雜應用。 1.Vue.js的響應式系統通過依賴追踪自動更新DOM,易於管理數據變化。 2.React採用單向數據流,數據從父組件流向子組件,提供明確的數據流向和易於調試的結構。

vue.js vs.反應:特定於項目的考慮因素vue.js vs.反應:特定於項目的考慮因素Apr 09, 2025 am 12:01 AM

Vue.js適合中小型項目和快速迭代,React適用於大型複雜應用。 1)Vue.js易於上手,適用於團隊經驗不足或項目規模較小的情況。 2)React的生態系統更豐富,適合有高性能需求和復雜功能需求的項目。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器