旺财记账项目-Money.vue组件实现(下)

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 {
          
        }
  1. Component修饰符,在最上面加@Compo按下tab键,选择从vue-property-decorator引入
        import {Component} from "vue-property-decorator"
        @Component
        export default class Types extends Vue {
        
        }
  1. 必需制定参数type的类型
      selectType(type: string) { // type 只能是 '-' 和 ' ' 中的一个

      }
  1. 代码总结
        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,... }
  1. 用 TS 类
    <script lang="ts">
    @Component
    export default class XXX extends Vue{
      xxx: string = 'hi';
      @Prop(Number) xxx: number|undefined;
    }
  1. 用 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值