日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

vue ts 设置tslint提示_Typescript 在 Vue 中的实践(包含2.x、3.x)

發布時間:2023/11/27 生活经验 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vue ts 设置tslint提示_Typescript 在 Vue 中的实践(包含2.x、3.x) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1 使用 typescript 的優勢

聊到 ts 時有一個不能規避的問題:為什么要使用 ts ,相比 js 有什么優勢嗎?下面我從兩個方面試著回答一下這個問題:

1.1 項目開發時的便利

  1. 避免低級 bug 產生

相信大家都遇到在編輯器一頓操作,打開瀏覽器頁面空白的尷尬翻車現場,然后一頓 debug 最后發現是把變量名拼錯了, 用上 ts 之后再也不會有這樣的煩惱了,類似的錯誤編輯器立馬就提示你了:

debug
? 2. 編輯器智能提示

項目變的越來越龐大時,記住一個變量描述的具體是什么也是一件很困難的事,可能需要我們不停的去查找類型的定義,事實上 ts 可以很好的解決這個問題,雖然一開始的類型定義稍顯繁瑣,但是他帶來的類型提示、代碼補全等會讓我們覺得這份工作量是值得的。

1.2 后期項目維護成本

  1. 類型即注釋

工作中難免會需要我們對某個模塊升級或者修改等,有時候沒有注釋或者注釋不全的話就需要我們去讀代碼了,其實很多時候我們并不關心某個模塊內部的具體實現,我們只想知道他的輸入輸出,這時候 ts 就很適合這個場景了:

type?Pay?=?(orderId:?string)?=>?Promise<-1?|?0>

const?pay:?Pay?=?orderId?=>?{
??//?do?something
}

類似于上面的代碼,從類型定義就可以大致推斷出其目的

  1. 利于重構

這可能是類型系統一個比較大的優勢了,之前在重構 js 項目時可謂是如履薄冰,生怕修改了某個模塊后搞崩整個項目,有了類型系統就可以安心多了,編輯器哪里飄紅去修改哪個地方就可以了。

2 讓類型流動起來

通常情況下我們會為項目中的接口添加類型定義,這可能也是最繁瑣的地方。假設我們有一個獲取商品信息的接口如下:

//?goodApi.ts
export?type?GoodInfo?=?{
??infoId:?string,
??price:?string,
??title:?string,
??label:?{
????labeltxt:?string,
????labelImg:?string
??}[]
}

const?getGoodInfo?=?():?GoodInfo[]?=>?{
??//?do?something
}

現在有一個方法 processLabel 需要輸入商品的 label 來對 labelImg 做一些處理,如下:

type?LabelMsg?=?{
??labeltxt:?string,
??labelImg:?string
}[]

const?processLabel?=?(labelArr:?LabelMsg)?=>?{
??//?do?something
}

顯然 labelArr 的源自于 GoodInfolabel,所以更好的方式是復用 GoodInfo 中的類型:

import?{?GoodInfo?}?from?'./goodApi.ts'

const?processLabel?=?(labelArr:?GoodInfo['label'])?=>?{
??//?do?something
}

當然,我們遇到的場景不可能都如此的簡單,可能有一個復雜點的函數 processLabel 依賴于兩個或多個接口的返回數據:

import?{?GoodInfo?}?from?'./goodApi.ts'
import?{?UserInfo?}?from?'./userApi.ts'

type?Info?=?Pick'label'>?&?Pick'tag?|?avatar'>const?processLabel?=?(info:?Info)?=>?{//?do?something
}

總之,我想表達的是應該盡量的復用類型或者使用類型推導,而不是一味的去聲明新的類型,這樣在項目后期維護或者代碼重構時能帶來一些方便。

3 在 Vue@2.x 中使用 ts

好的接下來進入本文的主題,在 Vue 中使用 ts,Vue 中一個常規的組件可能是這樣的:

export?default?{
??template:?'Click!',
??data()?{
????return?{
??????preStr:?'Hello!'
????}
??},
??props:?{
????message:?{
??????type:?String,
??????default:?'world'
????}
??},
??methods:?{
????onClick?()?{
??????window.alert(this.preStr?+?this.message)
????}
??}
}

Vue@2.x 要用上 ts 通常需要借助于 vue-property-decorator[1] 這個庫,我們大致看一下它的使用方式:

import?Vue?from?'vue'
import?{?Component,?Prop?}?from?'vue-property-decorator';

@Component({
??template:?'Click!'
})
export?default?class?Test?extends?Vue?{
??preStr:?string?=?'Hello!'

??@Prop({?type:?String,?default:?'world'?})
??message:?string

??onClick?():?void?{
????window.alert(this.preStr?+?this.message)
??}
}

可以看到需要將對象字面量的寫法轉換為基于類的組件定義方式,這樣很容易就可以對組件的 state 、 prop 、 method 等添加類型,同時其利用裝飾器在運行時導出了標準的 vue 組件,我們來大致看下 Component 裝飾器[2]的內部原理:

export?function?componentFactory?(//?Component即定義的組件類
??Component:?VueClass,//?options為傳給Component裝飾器的初始選項
??options:?ComponentOptions?=?{}):?VueClass<Vue>?{
??options.name?=?options.name?||?(Component?as?any)._componentTag?||?(Component?as?any).name

??const?proto?=?Component.prototype
??Object.getOwnPropertyNames(proto).forEach(function?(key)?{

????//?如果方法名與vue生命周期同名?直接放進options內
????if?($internalHooks.indexOf(key)?>?-1)?{
??????options[key]?=?proto[key]
??????return
????}
????const?descriptor?=?Object.getOwnPropertyDescriptor(proto,?key)
????//?普通方法放進options的methods內
????if?(descriptor.value?!==?void?0)?{
??????if?(typeof?descriptor.value?===?'function')?{
????????(options.methods?||?(options.methods?=?{}))[key]?=?descriptor.value
??????}
????//?get?set函數放進options的計算computed內
????}?else?if?(descriptor.get?||?descriptor.set)?{
??????(options.computed?||?(options.computed?=?{}))[key]?=?{
????????get:?descriptor.get,
????????set:?descriptor.set
??????}
????}
??})

??;(options.mixins?||?(options.mixins?=?[])).push({
????data?(this:?Vue)?{
??????//?類實例上的屬性當做options中data函數的返回值,即state
??????return?collectDataFromConstructor(this,?Component)
????}
??})

??//?Super就是Vue?根據計算得到的options選項extend一個常規的vue組件
??const?Extended?=?Super.extend(options)

??return?Extended
}

上面是 Component 裝飾器的部分源碼,大致就是收集組件類原型上的方法,按照不同的條件分發到 options 的生命周期方法、普通方法和計算屬性上,然后收集類實例上的屬性作為 optionsdata 函數的返回值,最后根據 optionsextend 一個標準的 vue 組件。

下面再簡單看下 Prop 裝飾器的原理:

export?function?Prop(options:?PropOptions?|?Constructor[]?|?Constructor?=?{})?{
??return?(target:?Vue,?key:?string)?=>?{
????applyMetadata(options,?target,?key)
????createDecorator((componentOptions,?k)?=>?{
??????//?componentOptions即上文中的options對象??k即被修飾的鍵名
??????;(componentOptions.props?||?((componentOptions.props?=?{})?as?any))[
????????k
??????]?=?options
????})(target,?key)
??}
}

Prop 的工作很簡單,將 Prop 修飾的鍵名和傳入的參數組成鍵值對放進 options.props 中,類似的vue-property-decorator[3]還提供了很多別的裝飾器(Model 、Watch 、 Ref 等),覆蓋了常見的使用場景,其基本原理大致都是在運行時修改構造組件的參數 options。

4 在 Vue@3.x 中使用 ts

Vue@3.x 已經發布了正式版,帶來了 Composition Api 和更好的 typescript 支持。對于 Vue@3.x + ts 的項目,只需通過 defineComponent 定義組件即可完美推斷出 component options 中的類型:

import?{?defineComponent?}?from?'vue'

const?Component?=?defineComponent({
??data()?{
????return?{
??????preStr:?'hello!'
????}
??},
??props:?{
????message:?{
??????type:?String,
??????required:?true
????}
??},
??methods:?{
????onClick()?{
??????this.preStr?=?'hi!'?//?ok????preStr被推斷成?string
??????this.preStr?=?123???//?error?number類型不能分配給string類型
??????this.message?=?'zz'?//?error?message是read-only屬性
????}
??}
})

對于 Composition Api 的支持度也很高:

import?{?defineComponent,?ref,?PropType?}?from?'vue';

export?default?defineComponent({
??props:?{
????callback:?{
??????required:?true,
??????type:?Function?as?PropType<(nums:?number)?=>?void>
????},
????message:?{
??????type:?String,
??????required:?true
????}
??},
??setup(props)?{
????const?nums?=?ref(0)

????props.callback(props.message)??//?error?callback的參數應該是number類型

????props.callback(nums.value)?????//?ok
??}
})

本人也是通過 demo 大概嘗試了一下在 Vue@3.x 中使用 ts,可以說是十分順滑,相較于 Vue@2.x 中基于類的組件定義方式,Vue@3.x 不需要我們改變什么代碼習慣就可輕松接入 ts,并且其類型推導也是相當的強大。

最后如果非要找出個不足的話,Vue 的模板寫法還是不能與 ts 兼容,雖說還有 tsx 的備選方案,但是用 tsx 就不太 Vue 了,不過相信后續也會有優秀的工具來彌補這個不足。總而言之,Vue 對 ts 的支持已足夠強大,趕緊用起來吧,真香!

參考資料

[1]

vue-property-decorator: https://github.com/kaorun343/vue-property-decorator

[2]

Component 裝飾器: https://github.com/vuejs/vue-class-component/blob/master/src/component.ts

[3]

vue-property-decorator: https://github.com/kaorun343/vue-property-decorator

???往期相關文章

- 從0到1,帶你徹底搞懂 vite 中的 HMR 原理

-?vue3.0新特性盤點

-?快速體驗Vue2和Vue3組件開發的區別-【官宣】Vue 3.0 發布!???交流討論歡迎關注公眾號?秋風的筆記,主要記錄日常中覺得有意思的工具以及分享開發實踐,保持深度和專注度。回復"好友"可加微信,秋風的筆記常年陪伴你的左右。

總結

以上是生活随笔為你收集整理的vue ts 设置tslint提示_Typescript 在 Vue 中的实践(包含2.x、3.x)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。