嘗試用TypeScript寫一個Vue-todo

TS看起來是大勢所趨,據說vue3.0的源碼都是用TS寫的了,無論如何都應該學習一番TS了!

在實踐中學習也不失爲一種學習方式!

1. 學習之前無論如何也要先看看TypeSCript中文網

2. vue-cli 3.0 提供了開箱即用的TS環境,那就直接開始!


vue create vue-todo

3. three days later

4. 基本完成了

成果

clipboard.png

代碼樣子大概是這樣,和JS寫出來的差別還是很大的

<template>
  <div class="today">
    <div class="menu" v-if="todayTodos.length !== 0 || menuIndex !== 0">
      <template v-for="(menu, index) in menus">
        <div @click="filterTodos(index)" :key="index" :class="['item', `${menuIndex === index ? 'active' : ''}`]">{{menu}}</div>
      </template>
    </div>
    <transition
        enter-active-class="animated fadeInLeft"
        leave-active-class="animated fadeOutRight"
        mode="out-in"
        >
      <Todos
        :key="menuIndex"
        :todos="todayTodos"
        :emptyMsg="emptyMsg"
        :type="menuIndex"
      />
    </transition>
  </div>
</template>
<script lang="ts">
import {Vue, Component} from 'vue-property-decorator'
import {Action, State, Getter} from 'vuex-class'
import Todos from '../components/Todos.vue'
@Component({
  components: {
    Todos,
  },
})
export default class Today extends Vue {
  // vuex-class 代替 mapAction 等幫助函數
  @State public todayTodos: any
  // @Action public getTodayTodos: any
  @Action public filterTodayTodos: any
  // TS data 不再需要 data () { return {}}
  public menus: string[] = ['全部', '已完成', '未完成']
  public menuIndex: number = 0
  // TS computed xuyao 需要關鍵字get
  // get Name() {return .....}
  public get emptyMsg(): string {
    if (this.menuIndex === 0) {
      return '這下你高興了!今天居然無事可做!!!'
    } else if (this.menuIndex === 1) {
      return '你今天居然什麼事都沒做完!'
    } else {
      return '人生就該勤奮做事!!'
    }
  }
  // TS methods 不用寫 methods: {}
  public async filterTodos(index: number): Promise<void> {
    if (index === 1) {
      await this.filterTodayTodos(true)
      this.menuIndex = index
    } else if (index === 2) {
      await this.filterTodayTodos(false)
      this.menuIndex = index
    } else {
      await this.filterTodayTodos()
      this.menuIndex = index
    }
  }
  // TS 生命週期函數,和原來一樣的寫法
  public created(): void {
    this.filterTodayTodos()
  }
}
</script>
<style lang="less" scoped>
@import '../common/main';
.today {
  .menu {
    display: flex;
    width: 100%;
    height: 12vh;
    background: @mainColor;
    .item {
      flex: 1;
      height: 12vh;
      line-height: 12vh;
      font-size: 1.2rem;
      box-sizing: border-box;
      color: rgb(178, 185, 190);
      // &:active {
      //   border-bottom: 3px solid #234; 
      // }
    }
    .active {
      border-bottom: 3px solid rgb(78, 54, 54);
      color: rgb(255, 255, 255);
    }
  }
}
</style>

5. 總結

1 這次實踐離真正熟練還差得很遙遠,但至少對強類型是有所理解了,也能感覺到TS的優勢,至少代碼提示比JS好太多了!
2 也遇見比較多的不適應

比如寫這個notify組件

notify.js

import Vue from 'vue'
import Notification from './Notify.vue'

// const NotificationConstructor = Vue.extend(Notification)
const notify = (options) => {
  if (Vue.prototype.$isServer) {
    return
  }
  const instance = new Notification({
    propsData: options,
  })
  instance.$mount()
  document.body.appendChild(instance.$el)
  // console.log(instance)
  return instance
}
export default notify
如果我這裏用TS,改爲 notify.ts,用ts的寫法。
執行 notify(options) 一定是報錯的,無奈只能用js的寫法,然後你用了JS,你又不得不寫個notify.d.ts來聲明這個東東。
至於錯誤原因留待自己的技術進步吧!

然後是這個 vue-chartjs

用TS的寫法也是不成功的,這個只能求助大佬了

JS寫法,完全沒問題

<script>
import { Line, Bar, PolarArea, Radar, Doughnut, Pie } from 'vue-chartjs'

export default {
  extends: Line,
  props: {
    chartdata: {
      type: Object,
      default: null,
    },
    options: {
      type: Object,
      default: null,
    },
  },
  mounted() {
    this.renderChart(this.chartdata, this.options)
  },
}
</script>

TS寫法,我也不知道錯在何處

<script lang="ts">
import { Line, Bar } from 'vue-chartjs'
import {Prop, Component, Vue} from 'vue-property-decorator'
@Component
export default class BarChart extends Bar {
  @Prop({default: null}) public chartdata!: any
  @Prop({default: null}) public options!: any
  public mounted() {
    this.renderChart(this.chartdata, this.options)
  }
}
</script>

最後github地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章