如何使用 vue + typescript 編寫頁面 ( 基礎裝飾器部分 )

董輝輝發表於2019-02-15

關於 Vue

Vue是一款前端的庫,用來快速生成頁面,是一款MVVM理念的框架。

關於 Typescript

Typescript是一款ECMAScript/Javascript的超集,提供了更豐富的語法

選擇 vue 的理由

簡單。推薦指數:3.7 。

扣分主要是我不太喜歡 script,css,template放在一個檔案裡面。當然了css還可以剔除到單獨檔案,但是script就沒法剔除了,否則語法器會報找不到

開發相關準備

  • 開發平臺 Windows 10
  • 開發工具使用的微軟旗下的 Visual Studio Code ,以下簡稱 vscode
    • 安裝vue外掛 Vetur
    • 安裝 Beautify css/less/scss 外掛
    • 有需要可以安裝一箇中文語言包
  • 環境安裝
    • node 用來執行環境和使用npm下載相關的開發包
    • git 部分包原始碼需要使用git下載安裝
    • python 安裝py是使用 node-sass 需要使用到,使用其他css預編譯可以忽略
    • 以上工具準備好後接下來安裝 vue-cli 3.0 使用 npm install -g @vue/cli (習慣使用yarn的人可以使用yarn global add @vue/cli
  • 使用 vue-cli 建立專案
    • vue create demo ,demo就是建立專案的名稱
    • 提示選擇預設,選擇 Manually select features 回車確認
    • 選擇typescript vuex router babel css pre-processors,不使用linter,不選單元測試[有需要另說]
    • 回車後按照需要選擇合適的選項
    • 選擇完畢後回車等待資源準備
  • 使用 vue-ui管理專案
    • 執行 vue ui
    • 成功後訪問提供的 url
    • Vue 專案管理器匯入建立的專案
    • 在外掛、依賴、配置可以做相應調整,也可以新增需要的外掛、依賴

編碼開始

開啟 vscode ,檔案-開啟資料夾,選擇剛才建立好的專案資料夾,匯入專案,使用CTRL + ~ 召喚控制檯。 輸入npm run serve執行開發模式,按住CTRL點選連結,開啟專案地址。初次使用ts時,需瞭解以下ts的基本語法,並且在使用ts編寫vue時,需要了解vue相關的基礎知識。以下介紹預設已經熟悉並瞭解相關內容,但是不知如何整合。 開啟src/views/Home.vue 作為參照,進行講解:

熟悉幾個vue的裝飾器 vue-property-decorator

以下的裝飾器的功能和原js編寫的功能相同/相似,可以參照官方文件類比解讀。

import { Vue, Component, Inject, Provide, Prop, Model, Watch, Emit, Mixins } from 'vue-property-decorator'
複製程式碼

1. Vue 實際上就是 Vue 本身,繼承vue相關屬性和函式

class MyComponent extends Vue { }
複製程式碼

2. @Component 宣告成一個vue的元件例項,如果不使用,則不能得到一個vue元件

第一種方式,不需要定義額外內容

@Component
class MyComponent extends Vue { }
複製程式碼

第二種方式,定義相關內容

@Component({
    /* 這裡和js版本編寫的 vue 元件內容相同,
     * 凡是不能在ts裡面完成的都可以在這裡完成 
     * 最終會被合併到一個例項中。
     * 在這裡定義的內容,不會被語法器獲取到,因此必須要同步在class中宣告
     */
    data(){
        return { myname:"",age:18 }
    }
})
class MyComponent extends Vue {
    private myname:string;
    mounted(){
        this.myname;    
        this.age;// 語法器報錯,當前類找不到age屬性
    }
}
複製程式碼

3. @Provide 向任意層級的子元件提供可訪問的屬性,預設為當前屬性的名稱,可以指定名稱

@Component
class ParentComponent extends Vue { 
    @Provide() private info!:string;
    @Provide("next") private infoNext!:string;
}
複製程式碼

4. @Inject 獲取父級由Provide提供的屬性,預設為當前屬性的名稱,可以指定名稱,多個父級提供相同名稱屬性時,獲取最近父級的名稱屬性

@Component
class MyComponent extends Vue { 
    @Inject() private info!:string;
    @Inject("next") private infoNext!:string;
}
複製程式碼

5. @Prop 由標籤屬性注入,獲取對應標籤屬性上值,可配置具體prop內容,參照js版本props內容

@Component
class MyComponent extends Vue { 
   @Prop() age!:number;
   @Prop({default:1}) sex!:number;
}
複製程式碼
<template>
    <MyComponent :age="16" />
</template>

<script lang="ts">  
import MyComponent from './MyComponent.vue';

@Component({
    components:{ MyComponent }
})
class PComponent extends Vue { }
</script>
複製程式碼

6. @Model 是v-model的裝飾器,當自定義元件想使用v-model時,可以使用這種方式,配合emit可以雙向傳遞屬性值

<template>
    <input type="checkbox" :checked="checked" @change="changed"/>
</template>

<script lang="ts">
@Component
class MyComponent extends Vue { 
   @Model("change") checked!:number;
   changed(event:any){ /* 這裡是偷懶寫的any,在實際專案中需要避免 */
       this.$emit("change",event.target.value)
   }
}
</script>
複製程式碼
<template>
    <MyComponent :age="16" v-model="mycheck" />
</template>

<script lang="ts"> 
import MyComponent from './MyComponent.vue';

@Component({
    components:{ MyComponent }
})
class PComponent extends Vue {
    private mycheck:boolean = false;
}
</script>
複製程式碼

7. @Watch 觀察某個屬性更新

@Component
class MyComponent extends Vue { 
   @Prop() age!:number;
   @Watch("age")
   ageChange(newVal:number,oldVal:number){
       /*age屬性更新時,處理相關內容*/
   }
}
複製程式碼

8. @Emit this.$emit 的裝飾器,如果沒有指定名稱,預設使用函式名稱。有返回值時,使用返回值,沒有則使用

@Component
class MyComponent extends Vue { 
   private myname = "";
   
   @Emit()
   ageChangeA(){ /* 僅傳送 this.$emit('ageChangeA') */   }
   
   @Emit()
   ageChangeB(age:number){ /* 傳送 age  this.$emit('ageChangeB',age) */   }
   
   @Emit()
   ageChangeC(age:number){  return 1 /* this.$emit('ageChangeC',1) 傳送return 結果*/ }
}
複製程式碼

9. Mixins

// MyMixin.ts
@Component
export default class MyMixin extends Vue { 
   /* 如果使用private 修飾,則兩個相同的 私有屬性混入時,會產生衝突 */
   protected myname = "張三";
   created(){  /* 混入物件有自己的 生命週期函式*/ }
   getMyName(){ console.log("張三混入") }
}
複製程式碼
// OtherMixin.ts
@Component
export default class OtherMixin extends Vue { 
   /* 如果使用private 修飾,則兩個相同的 私有屬性混入時,會產生衝突 */
   protected myname = "李四";
   created(){  /* 混入物件有自己的 生命週期函式*/ }
   getMyName(){ console.log("李四混入") }
}
複製程式碼
@Component
class MyComponent extends Mixins(MyMixin,OtherMixin) { 
   private myname = ""; /* 混入物件已經定義,這裡產生屬性衝突 */
   mounted(){
       this.getMyName() // 李四混入
   }
}
複製程式碼

裝飾器可以參照 vue-property-decorator

沒有filters,沒有指令相關裝飾器,有需要可以在@Component裡面補充,或者可以直接定義函式呼叫計算返回值 在class裡定義的屬性即data屬性,需要賦值初始值。

對於computed,使用 get 替代

@Component
class MyComponent extends Vue { 
   private myname = ""; /* 混入物件已經定義,這裡產生屬性衝突 */
   get upperName(){
       return "A" + this.myname
   }
}
複製程式碼

相關文章