再也不頭禿!typescript平滑重構vue項目

原始項目,使人頭禿

我剛接手手頭這個項目的時候,console裏處處飄紅,整個項目哪哪都是bug,滿目瘡痍。通過一段時間的調整,雖然能夠正常運行,可是不少問題遲遲沒有解決,好比亂七八糟的調用、沒有閉合的if else、沒有處理的try catch……能夠說,爲了維護這一個問題多多的項目,犧牲了不少個人頭髮...以上是牢騷段落。vue

做爲一個深知「懶是第一輩子產力」的工具人,在煩躁之餘,一直在尋找一勞永逸的方法。終於,typescript進入個人視線。有了typescipt,一些基礎的問題能夠直接在編寫、編譯時報錯,它的好處我也沒必要多說了。webpack

然而,vue+typescript的作法並不廣泛,也有爭議,網上也可能是老版本的作法,對於vue-cli3+typescript,怎麼樣平滑地、一天作一點地引入typescript呢?git

生產力工具篇

vue add typescript

第一步看官網資料,官網詳盡地寫了如何配置,不過,對於大多數用vue-cli搭建的項目,其實重點是第一句github

vue cli
就是vue-cli,經過引入 vue-cli-plugin-typescript插件,很簡單,一行代碼搞定:

vue add @vue/typescript
複製代碼

該插件會幫助配置webpack,引入ts.config,並把js文件轉換成ts文件,做爲參考,還會同時生成一個ts寫法的vue文件。web

由於咱們須要平滑重構,而不是一下完成全部的事情,因此 Allow .js files to be compiled選擇yes,容許js編譯。

vue-js轉換爲vue-ts

重構最累的一點就是,爲了給類型標註,幾乎要把以前的全部文件重寫一遍,好比:vue-cli

import Vue from 'vue'
import Component from 'vue-class-component'

// 1.添加修飾符
@Component()
// 2.基於類的vue文件
export default class MyComponent extends Vue {
  // 3.屬性標註
  message: string = 'Hello!'
  // 4.方法標註
  onClick (): void {
    window.alert(this.message)
  }
  // 5.其餘變化
}
複製代碼

這樣修改很難嗎?不難,但誰會想作個重複勞動百八十回的工具人呢?typescript

解放雙手,自動轉換:TransVue2Ts

這裏特別感謝 @清液 大神的解放雙手-vue語法自動轉typescript ,文中提到了轉換工具,能夠將vue-js的data/computed/prop/watch/mixin等通通轉換成vue-ts,我都一一測試過,沒有任何問題,強力推薦!👍👍👍npm

具體的轉換方式和寫法都在上文帖子中,我就不贅述了。 有了轉換工具,徹底能夠在須要時再將vue-js轉爲vue-ts,局部重構。bash

tslint

我用的是騰訊團隊的tslint-config-alloy,規則因團隊而異,大致按照這套規則。工具

踩坑篇

引入第三方插件

當在vue中引入第三方的插件時,typescript會沒法識別

import '*' as _ from 'lodash'
複製代碼

這時能夠先嚐試添加官方的typescript類型聲明npm install @types/xxx

npm install @types/lodash 
複製代碼

像lodash這種,官方是有ts聲明文件的,添加後就能夠識別了;對於沒有聲明文件的,則須要在shime-global.d.ts文件中聲明

declare module 'xxx'
複製代碼

data屬性沒法訪問全局屬性

解決方案:寫在created()鉤子中。最多見的例子:

@Component()
export default class Hello extends Vue {
    id:string = this.$route.query.id  // 這樣是會報錯的
    
    // 改爲這樣便可
    id:string = ''
    created(){
        this.id = this.$route.query.id
    }
}
複製代碼

對象的undefined、null處理

咱們常常會遇到這種狀況:

let user= {
    name:'小明',
    friends:[
        {name:'小明的朋友'}
    ]
}
alert(user.friends[0].name) // '小明的朋友'
複製代碼

當小明不存在(user爲null),或者小明沒有朋友(friends爲null)時,就會報錯,解決:

// 方法一
if(user&&user.friends&&user.friends.length>0){
    alert(user.friends[0].name) 
}
// 方法二
alert((((user||{}).friends||[])[0]||{}).name) 
複製代碼

要是再多幾層,就會更難寫難讀,因此我推薦方法三:使用 ts-optchain

import { oc } from 'ts-optchain';
alert(oc(user).friends[0].name('這裏能夠給個默認值'))
複製代碼

小結

文章僅是我我的的經驗總結,也只是提到了重構中關鍵性的工具,具體配置以官方爲準,若有錯漏,歡迎批評指正!

相關文章
相關標籤/搜索