编程知识 cdmana.com

Vue fruit bookkeeping - money.vue component

css And React The versions are almost the same except for the color distribution , Please refer to the previous article if necessary React Fruit bookkeeping -styled-components, The overall diagram is as follows ,css The specific code will not be repeated here .

image.png

Types.vue

The benefits of using a decorator image.png

TS The difference between compile time and run time image.png

The code uses '-' Means expenditure ,'+' Represents revenue ,selected Highlight when selected .

// Use TS To write 
<template>
  <div>
    <ul class="types">
      <li :class="type === '-' && 'selected'"
          @click="selectType('-')"> spending 
<!--           If type === '-', be class be equal to selected-->
      </li>
      <li :class="type === '+' && 'selected'"
          @click="selectType('+')"> income 
      </li>
    </ul>
  </div>
</template>

<script lang="ts">
  import Vue from 'vue';
  import {Component, Prop} from 'vue-property-decorator';

  @Component// The role of the modifier :type Will be automatically processed as data,selectType Will be automatically processed as methods
  export default class Types extends Vue {
    type = '-'; // '-' Means expenditure ,'+' Represents revenue 
    selectType(type: string) {
      if (type !== '-' && type !== '+') {
        throw new Error('type is unknown');
      }
      this.type = type;
    }
  }
</script>

<style lang="scss" scoped>
  .types {
    background: #fde3cc;
    ...
    > li {
      ...
      &.selected{
        background: #ffb13d;
      }
    }
  }

</style>
 Copy code 

Be careful :TS The code must be semicoloned , Can be in webstorm Set in

image.png

summary 1:TypeScript benefits

  1. Type tips : More intelligent tips
  2. Compile times error : You know you're wrong before you run the code
  3. Type checking : Unable to point out the wrong attribute

summary 2:TS The essence of

image.png

summary 3: Write Vue Three ways of components ( Single file component )

  1. use JS object

     export default { data, props, methods, created, ...}
     Copy code 
  2. use TS class <script lang="ts">

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

     @Component
     export default class XXX extends Vue{
         xxx = 'hi'
     }
     Copy code 

NumberPad.vue

<template>
  <div class="numberPad">
    <div class="output">{{output}}</div>
    <div class="buttons">
      <button @click="inputContent">1</button>
      <button @click="inputContent">2</button>
      <button @click="inputContent">3</button>
      <button @click="remove"> Delete </button>
      <button @click="inputContent">4</button>
      <button @click="inputContent">5</button>
      <button @click="inputContent">6</button>
      <button @click="clear"> Empty </button>
      <button @click="inputContent">7</button>
      <button @click="inputContent">8</button>
      <button @click="inputContent">9</button>
      <button @click="ok" class="ok">OK</button>
      <button @click="inputContent" class="zero">0</button>
      <button @click="inputContent">.</button>
    </div>
  </div>
</template>

<script lang="ts">
  import Vue from 'vue';
  import {Component} from 'vue-property-decorator';

  @Component
  export default class NumberPad extends Vue {
    output: string = '0';// Because there is input after ,ts You will guess that the type is string, So there can be no :string

    inputContent(event: MouseEvent) {
      const button = (event.target as HTMLButtonElement);
      const input = button.textContent!;//! amount to as string, Namely the null exclude 
      if (this.output.length === 16) { return; }// Enter up to 16 position 
      if (this.output === '0') {
        if ('0123456789'.indexOf(input) >= 0) {// If the input is in 0123456789 in 
          this.output = input;
        } else {
          this.output += input;
        }
        return;
      }
      if (this.output.indexOf('.') >= 0 && input === '.') {return;}// Prevent two decimal points in a string of numbers 
      this.output += input;
    }

    remove() {// Delete 
      if (this.output.length === 1) {
        this.output = '0';
      } else {
        this.output = this.output.slice(0, -1);
      }
    }

    clear() {// Empty 
      this.output = '0';
    }

    ok() {

    }
  }
</script>

<style lang="scss" scoped>
  @import "[email protected]/assets/style/helper.scss";
  .numberPad {
    .output {
      @extend %clearFix;
      @extend %innerShadow;
      font-size: 36px;
      font-family: Consolas, monospace;
      padding: 9px 16px;
      text-align: right;
      height: 72px;
    }
    .buttons {
      @extend %clearFix;
      > button {
        width: 25%;
        height: 64px;
        float: left;
        background: transparent;
        border: none;
        &.ok {
          height: 64*2px;
          float: right;
        }
        &.zero {
          width: 25*2%;
        }
        $bg: #ffb13d;
        &:nth-child(1) {
          background: lighten($bg, 4*6%);
        }
        &:nth-child(2), &:nth-child(5) {
          background: lighten($bg, 4*5%);
        }
        &:nth-child(3), &:nth-child(6), &:nth-child(9) {
          background: lighten($bg, 4*4%);
        }
        &:nth-child(4), &:nth-child(7), &:nth-child(10) {
          background: lighten($bg, 4*3%);
        }
        &:nth-child(8), &:nth-child(11), &:nth-child(13) {
          background: lighten($bg, 4*2%);
        }
        &:nth-child(14) {
          background: lighten($bg, 4%);
        }
        &:nth-child(12) {
          background: $bg;
        }
      }
    }
  }
</style>
 Copy code 

Notes.vue

<template>
  <div>
    <label class="notes">
      <span class="name"> remarks </span>
      <input type="text"
             v-model="value"
             placeholder=" Please enter comments ">
    </label>
  </div>
</template>

<script lang="ts">
  import Vue from 'vue';
  import {Component} from 'vue-property-decorator';

  @Component
  export default class Notes extends Vue {
    value = '';
  }
</script>

<style lang="scss" scoped>
  .notes {
    font-size: 14px;
    background: #f5f5f5;
    padding-left: 16px;
    display: flex;
    align-items: center;
    .name {
      padding-right: 16px;
    }
    input {
      height: 64px;
      flex-grow: 1;
      background: transparent;
      border: none;
      padding-right: 16px;
    }
  }
</style>
 Copy code 

review :v-model Form input binding

You can use it.  v-model  Instruction in form  <input><textarea>  And  <select>  Create two-way data binding on element . It automatically selects the correct method to update the element based on the control type . Even though it's magical , but  v-model  It's just grammar sugar in essence . It listens for user input events to update data , In addition, some special treatment is carried out for some extreme scenes .

v-model  All form elements will be ignored  valuecheckedselected attribute The initial value of will always be Vue Instance data as data source . You should go through JavaScript In the component's  data  Initial value declared in option .

v-model  Use different... Internally for different input elements property And throw out different events :

  • text and textarea Element usage  value property and  input  event ;
  • checkbox and radio Use  checked property and  change  event ;
  • select Fields will  value  As prop And will  change  As an event .

For the need to use typewriting  ( Such as Chinese 、 Japanese 、 Korean, etc ) Language , You'll find that  v-model  It will not be updated in the process of combining text with input method . If you want to deal with the process as well , Please use  input  event .

give an example :

<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
 Copy code 

Tags.vue

<template>
  <div class="tags">
    <div class="new">
      <button @click="create"> New label </button>
    </div>
    <ul class="current">
      <li v-for="tag in dataSource" :key="tag"
          :class="{selected: selectedTags.indexOf(tag)>=0}"
          @click="toggle(tag)">{{tag}}
      </li>
    </ul>
  </div>

</template>

<script lang="ts">
  import Vue from 'vue';
  import {Component, Prop} from 'vue-property-decorator';

  @Component
  export default class Tags extends Vue {
    @Prop() readonly dataSource: string[] | undefined;
    selectedTags: string[] = [];

    toggle(tag: string) {
      const index = this.selectedTags.indexOf(tag);
      if (index >= 0) {
        this.selectedTags.splice(index, 1);
      } else {
        this.selectedTags.push(tag);
      }
    }

    create() {
      const name = window.prompt(' Please enter a tag name ');
      if (name === '') {
        window.alert(' Tag name cannot be empty ');
      } else if (this.dataSource) {
        this.$emit('update:dataSource',
          [...this.dataSource, name]);
      }

    }
  }
</script>

<style lang="scss" scoped>
  .tags {
    ...
    > .current {
      display: flex;
      flex-wrap: wrap;
      > li {
        $bg: #ffb13d;
        background: #fde3cc;
        ...
        &.selected {
          background: $bg;
        }
      }
    }
    > .new {
      padding-top: 16px;
      button {
        ...
      }
    }
  }

</style>
 Copy code 

版权声明
本文为[Nine barrel mother]所创,转载请带上原文链接,感谢
https://cdmana.com/2021/09/20210909122358677j.html

Scroll to Top