摘要:想要使用語法的話,配合,這個插件,體驗更佳,這個插件在語法中實現了。這種方式最接近的單文件組件的寫法,如果一個完善項目從改成,用這種方法很快,只要加上和一些必要的變量類型就好了,然后用包裹就好。不推薦混入用這種方式寫,無法實現多繼承。
最近嘗試了一下 TypeScript,試著把一個 Vue 項目改成了 TypeScript 的,感覺還不錯 目前 Vue 和 TypeScript 的配合還不算很完美,Vuex 和 TypeScript 的配合挺糟糕的,嘗試需要謹慎 如果想體驗一下的話,強烈建議你用 vue-cli 3 直接生成項目目錄,這樣會少挺多配置,比如配 tsconfig 什么的,在用 vue-cli 的時候選擇 TypeScript 就好
如果想自己體驗從 0 開始配置請參考這個文檔 TypeScript-Vue-Starter
初始配置這里不提初始配置,因為 vue-cli 已經默認配置好了,在根目錄下,有個 tsconfig.json 的文件,在 src 的文件夾下面,有 shims-tsx.d.ts, shims-vue.d.ts 文件
shims-vue.d.ts 這個文件,主要用于 TypeScript 識別.vue 文件,Ts 默認并不支持導入 vue 文件,這個文件告訴 ts 導入.vue 文件都按VueConstructor
說那么多可能沒用,看一下下面兩張圖就懂了
導入地址是正確的
導入地址是錯誤的
shims-tsx.d.ts 文件,這個文件主要是方便你使用在 ts 中使用 jsx 語法的,如果不使用 jsx 語法,可以無視這個,但是強烈建議使用 jsx 語法,畢竟模板是沒法獲得靜態類型提示的,當然,如果你境界高的話,直接用 vue render function。想要使用 jsx 語法的話,配合 babel-plugin-jsx-v-model,這個插件,體驗更佳,這個插件在 jsx 語法中實現了 v-model。
編輯器支持推薦使用 Visual Studio Code 和 Vetur 插件,如果用的是 IDE,推薦使用 WebStorm
使用 TypeScript 編寫 Vue 的時候,主要有兩種方法Vue.extend() 和 vue-class-component
Vue.extend():使用基礎 Vue 構造器,創建一個“子類”。 這種方式最接近 Vue 的單文件組件的寫法,如果一個完善 Vue 項目從 JS 改成 TS,用這種方法很快,只要加上 lang=ts和一些必要的變量類型就好了,然后用Vue.extend()包裹就好。請看下面的例子:
JavaScript
TypeScript
vue-class-component:通常和vue-property-decorator一起搭配使用,實際使用只使用vue-property-decorator就好了,vue-property-decorator是在vue-class-component上擴展來的,并且提供了很多修飾器比如 @Prop和@Watch等等,使用這個可以編寫類式組件,但是如果你是完善的項目 JS 改 TS 的話,需要改的地方很多。看一下下面的例子:
JavaScript
TypeScript
可以看出變化真的很大
這兩種編寫方式風格有很大的不同,下面具體說一下兩種方式的具體實現
組件 props
Vue.extend()實現 props 其實和 JavaScript 沒有任何差別,但是如果你需要有 Object 變量類型提示,那就有點不一樣了
vue-class-component實現 props, 需要從 vue-property-decorator 引入 Prop 這個修飾符,使用起來也非常方便,還是用上面的例子
// JavaScript props: ["isVisible", "title", "item", "count", "items"] // 如果加入了prop驗證,這樣寫 props: { isVisible: { type: Boolean, required: true }, title: { type: [String, Number] }, item: { type: Object }, items: { type: Array, } count: { count: Number } } // TypeScript /* 這種寫法沒有任何改變,但是這樣沒有任何類型提示,這些變量能被TS識別,但是會全部被識別成any,和沒類型檢查一樣 */ props: ["isVisible", "title", "item", "count", "items"] /* 當加入prop驗證之后,TS就會提示prop類型了,如果是對象的話,還能有對象的成員提示,寫法和JS寫法差不多,只是對象類型(包括對象,數組和函數)的有點差別,這樣寫的話。*/ // 假設item對象的結構是 interface Item { key: string val: string num: number } props: { isVisible: { type: Boolean, required: true }, title: { type: [String, Number] }, item: { // 注意這里不是 // Object as Item type: Object as () => Item }, itmes: { // 注意這里不是 // Array as Array- type: Array as () => Array
- } count: { count: Number } } // vue-class-component方式 import { Vue, Component, Prop } from "vue-property-decorator" // 注意要加非空斷言符 ! 不然會報,當然,你定義成any類型當我沒說 /* [non-null-assertion-operator](https://github.com/Microsoft/TypeScript/wiki /What"s-new-in-TypeScript#non-null-assertion-operator) 關于非空斷言可以參考這個 */ @Prop({ required: true }) isVisible!: boolean @Prop() title!: string | number @Prop() item!: Item @Prop() items!: Array
- @Prop() count!: number
組件 data computed methods watch
Vue.extend()實現 data 其實和 JavaScript 沒有任何差別,computed 的話,也沒什么大的改變,但是有 this 參與運算的必須標明返回值類型,不然會報錯, methods 的處理方式和 computed 的一樣,有 this 參與運算的必須標明返回值類型,watch 也是一樣
vue-class-component實現 data 的話,直接在類里面寫變量就好,computed 的話,寫法類似 getter 和 setter,methods 處理方式就是直接在里面寫方法,watch 需要從 vue-property-decorator 引入 Watch 這個修飾符
//一個簡單的例子 // Vue.extend() import Vue from "vue" export default Vue.extend({ data() { return { count: 1, item: { c: "", n: "" } } }, computed: { // 需要標注有 `this` 參與運算的返回值類型 num(): number { return this.count }, name: { // 需要標注有 `this` 參與運算的返回值類型 get(): string { return this.item.n }, set(val: string) { this.item.n = val } } }, watch: { count(newVal: number, oldVal: number): void { console.log(newVal) }, "item.n"(newVal: string, oldVal: string): void { console.log(newVal) }, item: { handler(newV, oldVal) { console.log(oldVal) }, deep: true } }, methods: { reset(): void { this.$emit("reset") }, getKey(): string { return this.item.c } } }) // vue-class-component import { Vue, Component, Watch } from "vue-property-decorator" interface KeyValue { c: string n: string } @Component export default class Test extends Vue { // data count: number = 1 item: KeyValue = { c: "", n: "" } // computed get num(): number { return this.count } get name(): string { return this.item.n } // 注意,這里不能標返回值類型,就算寫void也不行 set name(val: string) { this.item.n = val } // watch @Watch("count") watchCount(newVal: number, oldVal: number): void { console.log(newVal) } @Watch("item.n") watchName(newVal: string, oldVal: string): void { console.log(newVal) } @Watch("item", { deep: true }) watchItem(newVal: KeyValue, oldVal: KeyValue): void { console.log(newVal) } // methods reset(): void { this.$emit("reset") }, getKey(): string { return this.item.c } }
組件 components
Vue.extend() components 和 JavaScript 寫法完全一致
vue-class-component 需要把導入的組件寫在修飾器@Components({})里面
// Vue.extend import Vue from "vue" import MainHeader from "./header.vue" import MainContent from "./content.vue" export default Vue.extend({ components: { MainHeader, MainContent } }) // vue-class-component import { Vue, Component } from "vue-property-decorator" import MainHeader from "./header.vue" import MainContent from "./content.vue" @Component({ components: { MainHeader, MainContent } }) export default class extends Vue {}
組件 mixins
Vue.extend() 并不能完全實現 mixins 多混入的效果,只能混入一個。不推薦混入用這種方式寫,無法實現多繼承。如果你非要嘗試這種寫法,可以看看這個Issue,我沒有嘗試過這種寫法,不過有人寫了個例子,可以作為參考,但是我嘗試了沒成功
// ExampleMixin.vue export default Vue.extend({ data () { return { testValue: "test" } } }) // other.vue export default Vue.extend({ mixins: [ExampleMixin], created () { this.testValue // error, testValue 不存在! } }) 我們需要稍作修改: // other.vue export default ExampleMixin.extend({ mixins: [ExampleMixin], created () { this.testValue // 編譯通過 } })
vue-class-component 能夠實現多混入,寫法類似類繼承
// mixin1.ts import Vue from "vue" export default Vue.extend({ data () { return { valFromMixin1: "test" } } }) // 不能是 // 這種寫法會報 Mixin1 is not a constructor function type export default { data () { return { valFromMixin1: "test" } } } // mixin2.ts import { Component, Vue } from "vue-property-decorator" @Component export default class Mixin2 extends Vue { methodFromMixin2() {} } // test.ts import Mixin1 from "./mixin1" import Mixin2 from "./mixin2" import { Component, Mixins } from "vue-property-decorator" export default class Test extends Mixins(Mixin1, Mixin2) { test() { this.methodFromMixin2() console.log(this.valFromMixin1) } } // 如果只混入一個的話,可以這樣寫 export default class Test extends Mixin1 {} export default class Test extends Mixin2 {}
這樣寫不僅不會報錯,而且編輯器還有提示
這張圖可以看出,setWatch 是 BookingWatcher 里面的方法,實際上,Test 這個類并沒有自身的屬性,都是從 Vue,BookingWatcher 還有 TestMixins 繼承過來的
函數式組件
這個只能用 Vue.extends(),Vue-class-component 無能為力,可以看看這個 Issue
這里提供一個函數式組件的例子
在 Vue 中使用 TypeScript 的一些思考(實踐)
vue 官網 TypeScript 支持
$refs 報錯
$refs 報錯這個問題相信基本都遇到,除非你真沒用到這個,如圖:
報錯信息是
Property "blur" does not exist on type "Vue | Element | Vue[] | Element[]".
Property "blur" does not exist on type "Vue".
解決方案:把上圖報錯部分改成
// 把這個變量改成定義成HTMLInputElement就好,這里需要用到類型斷言 test() { let inputBox: HTMLInputElement = this.$refs.inputBox as HTMLInputElement inputBox.blur() }
如果引用的比較多,并且引用里面有自己的組件的話,可以這樣寫:
$refs: {}
這樣編輯器還會提示組件里面有什么方法,當你打出 this.$refs.header.時候,編輯器有提示 Header 這個組件里面的屬性和方法
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/98790.html
摘要:新項目起手式最后更新于,技術文具有時效性,請知悉我知道你們早就想用上強類型了還有后續進階篇安裝安裝依賴配置添加添加讓識別改造文件什么是是的強類型版本。是的超集,這意味著他支持所有的語法。與此同時,也是的超集,的也宣布采用進行開發。 vue + typescript 新項目起手式 最后更新于2018-06-30,技術文具有時效性,請知悉 我知道你們早就想用上 vue + ts 強類型...
摘要:前言本文講解如何在項目中使用來搭建并開發項目,并在此過程中踩過的坑。具有類型系統,且是的超集,在年勢頭迅猛,可謂遍地開花。年將會更加普及,能夠熟練掌握,并使用開發過項目,將更加成為前端開發者的優勢。 showImg(https://segmentfault.com/img/remote/1460000018720573); 前言 本文講解如何在 Vue 項目中使用 TypeScript...
摘要:創建項目安裝創建一個項目默認套餐,提供和支持。自己去選擇需要的功能,提供更多的特性選擇。比如如果想要支持,就應該選擇這一項。支持使用書寫源碼。支持代碼風格檢查和格式化。 Vue Cli3 創建項目 Vue,Markdown 1. 安裝 npm install -g @vue/cli 2. 創建一個項目 vue create iview-admin # OR vue ui showIm...
摘要:詳情發布新版本中可以自動修復和合并沖突的文件,還新增了命令。詳情是一個用構建設計系統的開源工具,提供了一套基礎應用程序開發的工具,模式和實踐。目前,只有和的最新版本支持該屬性。詳情每周一同步更新到歡迎 01. JS 引擎 V8 v6.6 的更新 最新 v6.6 版本的 V8 JavaScript 引擎更新了方法 Function.prototype.toString(),改進了代碼緩存...
閱讀 3696·2021-08-10 09:42
閱讀 591·2019-08-30 15:55
閱讀 890·2019-08-30 15:54
閱讀 3114·2019-08-30 13:45
閱讀 556·2019-08-29 16:23
閱讀 1992·2019-08-29 16:23
閱讀 986·2019-08-29 15:18
閱讀 2264·2019-08-29 12:57