Problem 1: Webpack vs. Vue

Vue-cli-service lint found some errors

My solution is to add /* eslint-disable */ to the error file

After use, the problem in vue.config.js was successfully solved

Error: ‘__WebpackModuleApi’ is not defined (no-undef)

I found a similar problem on the Internet, __webpack_public_path__ in vue. js

Js >module.exports I added globals in.eslintrc.js>module.exports and successfully submitted the code.

module.exports = {
    "globals": {"__WebpackModuleApi":"writable"}}Copy the code

Problem two: Split components

Money.vue has too much content, break it up. Create a new Money folder in Components, corresponding to several div blocks of money. vue, create the corresponding vue file.

Move the template and style from money.vue to the corresponding vue file and introduce them in money.vue.

Split into several components, the effect is the same as before.

Problem 3: Error encountered writing Vue component

How to write Vue components (single-file components)

  1. Write in a JS object
export default{data , props, methods, created, ... }Copy the code
  1. Write in TS class
@Componet
export default class XXX extends Vue{
    xxx: string = 'hi';
    @Prop(Number) xxx: number|undefined;
}
Copy the code
  1. Write in JS classes
@Compnent
export default class XXX extends Vue{
    xxx = 'hi'
}
Copy the code

Bug1: Prop is unavailable when the TS class is used to write vue components

Error 23 lines of code

Try to update typescript and still get an error

Refer to the Vue-property-Decorator document

@Prop(Number) xxx: number | undefined;
Copy the code

successful

Parse this code

In simple terms, the number | is undefined at compile time tell Vue, XXX compilation types. And the Number is telling Vue at runtime that XXX is a Number.

The essence of TS

Note: TSC =>TypeScript compiler: TS can be checked and compiled to JS.

Bug2: Error with selectType while writing vue component using TS class

Declare type: String

Problem four: v – model

<template>
  <div>
    <label class="notes">
      <span class="name">note</span>
      <input type="text"
      :value="x"
      @input="x = $event.target.value"
      placeholder="Click to enter remarks...">
    </label>
  </div>
</template>

<script lang="ts">
import  Vue from 'vue';
import {Component} from 'vue-property-decorator';
@Component
export default class Notes extends Vue{
  x = ' ';
}
</script>
Copy the code

I can write this for short

<template>
  <div>
    <label class="notes">
      <span class="name">note</span>
      <input type="text"
      x-model="x"
      placeholder="Click to enter remarks...">
    </label>
  </div>
</template>

<script lang="ts">
import  Vue from 'vue';
import {Component} from 'vue-property-decorator';
@Component
export default class Notes extends Vue{
  x = ' ';
}
</script>
Copy the code

Problem 5: Collecting data

Occupy the space and tidy it up later

Problem 6: Using LocalStorage to store data

After the data is collected, you want to implement the following functions: Press OK every time to place the data in LocalStorage.

– Added a listener @submit=”saveRecord” to NumberPad of parent money. vue

<template>
  <layout class-prefix="layout">
    <NumberPad @update:value="onUpdateAmount" @submit="saveRecord"/>.</layout>
</template>
Copy the code
<script lang="ts">...export default class Money extends Vue{
    tags = ['food'.'transportation'.'shopping'.'home'];
    recordList: Record[] = [];
    record: Record = {tags: [].notes: ' '.type: The '-'.amount: 0}; .// Add a new function
    saveRecord(){
      this.recordList.push(this.record)
    }
    @Watch('recordList')
    onRecordListChange(){
      window.localStorage.setItem('recordList'.JSON.stringify((this.recordList)))
    }
}
</script>
Copy the code

Add the code in the OK function in export Default in the child component numberpad.vue file

<script lang="ts">...export default class NumberPad extends Vue {...ok(){
    this.$emit('update:value'.this.output);
    this.$emit('submit'.this.output); / / new
  }
}
</script>
Copy the code

So every time the user clicks OK, the data will be uploaded to LocalStorae

But here’s an error:

The first time you type 1, click OK, print this. RecordList, amount is the number 1, correct.

But if you type 2 the second time, click OK, and print this. RecordList, amount, you get 2 both times.

Local Storage is as follows

Recordlist.push (this.record) is just a reference, so the first ok and the second OK only reference the address of record, the result is two 2.

Change the code, record2 is a deep copy, equivalent to save a copy of this.record so that the desired function can be achieved.

saveRecord(){
      const record2 = JSON.parse(JSON.stringify(this.record));
      this.recordList.push(record2)
      console.log(this.recordList);
    }
Copy the code

Problem 7: Js rewrite TS error

  1. Change filename suffixjsforts

  1. Create a newcustom.d.ts, global declarationRecordItemThat is assigned todataTo solve

  1. When I submit the code here, I’m reporting an error again.
error: 'RecordItem' is not defined (no-undef) at src\views\Money.vue:40:20: 38 | 39 | saveRecord() { > 40 | const record2: RecordItem = model.clone(this.record); | ^ 41 | record2.createdAt = new Date(); 42 | this.recordList.push(record2); 43 |}Copy the code

For the global RecordItem declared in cunstom.d.ts, ‘RecordItem’ is not defined in money. vue.

After trying many methods without success, we finally redeclared a RecordItem and introduced it into money.vue.

We will update later if there is a better solution.

Problem # 8: Directly modifying the value of the parent component with respect to the child component

The following code

<template> <div> <label class="formItem"> <span class="name">{{ this.fieldName }}</span> <input type="text" v-model="value" :placeholder="this.placeholder"> </label> </div> </template> <script lang="ts"> ... export default class FormItem extends Vue{ @Prop({default:''}) value! :string; . onValueChanged(value:string){ this.$emit('update:value',value) } } </script>Copy the code

Vue does not recommend changing the values of props from the parent component (formitem.vue).

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "value"
Copy the code

The solution:

Rewrite v-model=”value” so that value is no longer assigned.

Change the value with onValuechanged.

<template> <div> <label class="formItem"> <span class="name">{{this.fieldName}}</span> <input type="text" :value  = "value" @input = "onValueChanged=($event.traget.value)" :placeholder="placeholder"> </label> </div> </template> <script lang="ts"> ... export default class FormItem extends Vue{ @Prop({default:''}) readonly value! :string; . onValueChanged(value:string){ this.$emit('update:value',value) } } </script>Copy the code

Problem 9: Solve the ID generation problem

Problem description

For example, create the following in the component tagListModel.vue

type TagListModel = { ... create: (name: string) => 'success' | 'duplicated' ... } const tagListModel: TagListModel = { ... create(name) { const names = this.data.map(item => item.name) if(names.indexOf(name) >= 0) { return 'duplicated'; } this.data.push({ id:name, name: name }); this.save(); return 'success'; },... }Copy the code

When you create a label with the same name, you are prompted for duplication.

After adding a new function, you can change the name of the tag in the edit TAB page, and the following bug appears: change the name of the tag {ID :1, name:1}, and create a new tag again, you cannot recognize the duplicate tag.

solution

  1. First, an ID is assigned to the tag. Do not modify it because the route uses the ID as part of the ADDRESS of the URL.
 {
    path: '/labels/edit/:id',
    component: EditLabel
  },
Copy the code

If the ID changes, the refresh page does not exist.

  1. /label/edit/1 = /label/edit/1 = /label/edit/1

  2. What I do is every time I create a tag, I increment the id. It may blow up the stack, but it meets a large portion of the needs.

Basically, the code can access my Github.

Create a new TS component to implement the auto-increment of the ID. Introduce the auto-increment ID in the create method of the tagListModel.ts component.

Question 10: ISO 8601

Wikipedia – a combined representation of dates and times

The usage is as follows:

For the combined representation of date and time, add a capital letter T before the time. For the representation of May 3, 2004 5:30pm 8s, write 2004-05-03T17:30:08+08:00 or 20040503T173008+08.