1. 实现TypeScript的Vue组件。

  • 以Types组件为例改写

    • JS写法

      <template>
        <div>
          <ul class="types">
            <li :class="type === '-' && 'selected'"
            @click="selectType('-')">支出</li>
            <li :class="type === '+' && 'selected'"
            @click="selectType('+')">收入</li>
          </ul>
        </div>
      </template>
      
      <script lang="js">
        export default {
          name: "Types",
          props: ['xxx'],
          data() {
            return {
              type: '-' // '-'表示支出.'+'表示收入
            }
          },
          mounted() {
            console.log(this.xxx)
          },
          methods: {
            selectType(type) { // type 只能是 '-' 和 '+' 中的一个
              if(type !== '-' && type !== '+'){
                throw new Error('type is unknown')
              }
              this.type = type
            }
          }
        }
      </script>
    • TS写法,用class组件写data methods 和生命周期

      1. 起手

          export default class Types extends Vue {
            
          }
      2. Component修饰符,在最上面加@Compo按下tab键,选择从vue-property-decorator引入

          import {Component} from "vue-property-decorator"
          @Component
          export default class Types extends Vue {
          
          }
      3. 必需制定参数type的类型

        selectType(type: string) { // type 只能是 '-' 和 '+' 中的一个
        
        }
      4. 代码总结

          import Vue from 'vue'
          import {Component} from "vue-property-decorator"
            @Component
            export default class Types extends Vue {
              type = '-'  // '-'表示支出.'+'表示收入
              selectType(type: string) { // type 只能是 '-' 和 '+' 中的一个
                if(type !== '-' && type !== '+'){
                  throw new Error('type is unknown')
                }
                this.type = type
              }
              created(){}
              mounted(){}
            }
    • props用法
      1 查看一个包的最新版本,在终端输入

        npm info typescript version

2. TS 组件 @Prop装饰器

  • 用法

        // 左边Number是运行时的检查,右边number是编译时的检查,编译时的检查会在写代码的时候就给提示
        @Prop(Number) xxx: number | undefined;
        // Prop 告诉 Vue xxx 不是 data 是 prop
        // Number 告诉 Vue xxx 运行时类型 是个 Number
        // xxx 属性名
        // number | undefined 就是 告诉 TS xxx 的编译时类型
        // 为什么前面的Number是大些后面是小写,见3.编译时和运行时的区别
  • TS的好处

    1. html直接空格告诉你有哪些参数
    2. 如果声明了类型,代码写错了会提前告诉,编译报错,无法编程js
    3. 检查调用的方法到底能不能调用,你不能写.tostring

3. 编译时和运行时的区别

运行时和编译时区别.png

4. TS的本质

TS的本质.png

5. Vue但文件组件的三种写法

  1. 用JS对象

      export default { data,props,methods,created,... }
  2. 用 TS 类

     <script lang="ts">
     @Component
     export default class XXX extends Vue{
       xxx: string = 'hi';
       @Prop(Number) xxx: number|undefined;
     }
  3. 用 JS 类

     @Component
     <script lang="js">
     export default class XXX extends Vue{
       xxx = 'hi'
     }

6. 开始实现NumberPad组件

  • 在按钮上绑定事件,不加参数会默认传入事件

    <button @click="inputContent">1</button>
    inputContent(event: MouseEvent){
      if(event.target){
        console.log(event.target.textContent);
      }
    }
  • 强制指定类型,需要这么做的原因是Vue和Typescript不够好

    inputContent(event: MouseEvent){
      if(event.target){
        const button = (event.target as HTMLButtonElement)
        console.log(button.textContent);
      }
    }
  • 如果只是要排除空,也可以这么写

    const input = button.textContent!;
  • 基本完成NumberPad,NumberPad 组件所有代码

    import Vue from "vue"
    import {Component, Prop} from "vue-property-decorator"
    
    @Component // 如果如果这样写,就表示Class就有一个propMessage的props,类型为String
    export default class NumberPad extends Vue {
      output: string = '0';
      inputContent(event: MouseEvent){
        const button = (event.target as HTMLButtonElement);
        const input = button.textContent!;
        if(this.output.length === 16){return}
        if(this.output === '0'){
          if ('0123456789'.indexOf(input) >= 0) {
            this.output = input
          } else {
            this.output += input;
          }
          return
        }
        if (this.output.indexOf(".") >= 0 && input === ".") {return;}
        this.output += input;
      }
    
      remove(){
        if (this.output.length === 1){
          this.output = '0';
        } else {
          this.output = this.output.slice(0, -1);
        }
      }
    
      clear(){
        this.output = '0';
      }
      ok(){
    
      }
    }
    

67. 开始实现备注功能

  • 原生html input实现绑定数据
<input type="text" :value="value" @input="onInput" placeholder="在这里输入备注">
onInput(event: KeyboardEvent){
      const input = event.target as HTMLInputElement;
      this.value = input.value
    }
  • 对:value 和 @input绑定数据进行简写
<input type="text" v-model="value" placeholder="在这里输入备注">

8. 开始实现tags模块

  • 只能不能改外部数据的写法

    @Prop() readonly dataSource: string[] | undefined // 加readonly
  • 内部不能直接改外部数据

    // 内部
    // this.dataSource.push(name!); // 不能改外部数据,这种写法不推荐!
    this.$emit("update:dataSource", [...this.dataSource, name])
    // 外部,用.sync简写
    <Tags :data-source.sync="tags"/>

最后,个人微信,欢迎交流!

wechat0.jpg


codingories
9 声望2 粉丝

不想当制作人的rapper不是好程序员!