實戰項目:up2u記帳本總結

問題一:webpack與vue

提交代碼,提示vue-cli-service lint found some errorsjavascript

個人解決方法是在報錯文件添加/* eslint-disable */vue

使用後成功解決了vue.config.js中的問題java

可是Icon.vue仍是存在報錯,error: '__WebpackModuleApi' is not defined (no-undef)webpack

在網上搜索到了相似的問題,Vue.js中的__webpack_public_path__git

我在.eslintrc.js>module.exports添加globals,成功提交代碼。github

module.exports = {
    "globals":{
        "__WebpackModuleApi":"writable"
    }
}
複製代碼

問題二:拆分組件

Money.vue內容太多,對其進行拆分。在components新建Money文件夾,對應Money.vue的幾個div塊,建立相應的vue文件。web

image.png

Money.vue中的templatestyle移到相應vue文件中,並在Money.vue中引入。vue-cli

image.png

拆分爲幾個組件後,效果與原來一致。typescript

image.png

問題三:寫Vue組件遇到的錯誤

寫Vue組件的方式(單文件組件)

  1. 用JS對象寫
export default {data , props, methods, created, ...}
複製代碼
  1. 用TS類寫
@Componet
export default class XXX extends Vue{
    xxx: string = 'hi';
    @Prop(Number) xxx: number|undefined;
}
複製代碼
  1. 用JS類寫
@Compnent
export default class XXX extends Vue{
    xxx = 'hi'
}
複製代碼

bug1:在使用TS類寫vue組件時,prop沒法使用

23行代碼報錯

image.png

嘗試更新typescript後,依舊報錯markdown

參考vue-property-decorator文檔

@Prop(Number) xxx: number | undefined;
複製代碼

成功

解析一下這句代碼

image.png

簡單來講,number | undefined是在編譯時告訴Vue,xxx的編譯類型。而Number是在運行時告訴Vue,xxx是個number。

image.png

扯TS的本質

image.png

注:tsc=>TypeScript compiler,可檢查TS,可將TS編譯成JS。

bug2:在使用TS類寫vue組件時,selectType出錯

image.png

聲明type: String便可

image.png

問題四:v-model

<template>
  <div> <label class="notes"> <span class="name">備註</span> <input type="text" :value="x" @input="x = $event.target.value" placeholder="點擊輸入備註..."> </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>
複製代碼

能夠簡寫成

<template>
  <div> <label class="notes"> <span class="name">備註</span> <input type="text" x-model="x" placeholder="點擊輸入備註..."> </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>
複製代碼

問題五:收集數據

佔位,以後整理

問題六:用LocalStorage儲存數據

數據收集完以後,想實現如下功能:每次按ok,將數據放到LocalStorage

在父組件Money.vueNumberPad新加了一個監聽@submit="saveRecord"

<template>
  <layout class-prefix="layout"> <NumberPad @update:value="onUpdateAmount" @submit="saveRecord"/> ... </layout>
</template>
複製代碼
<script lang="ts">
...
  export default class Money extends Vue{
    tags = ['餐飲','交通','購物','居家'];
    recordList: Record[] = [];
    record: Record = {tags: [], notes: '', type: '-', amount: 0};
    ...
    // 新增函數
    saveRecord(){
      this.recordList.push(this.record)
    }
    @Watch('recordList')
    onRecordListChange(){
      window.localStorage.setItem('recordList',JSON.stringify((this.recordList)))
    }
}
</script>
複製代碼

在子組件NumberPad.vue文件中的export default中的ok函數中添加代碼

<script lang="ts">
...
export default class NumberPad extends Vue {
...
  ok(){
    this.$emit('update:value',this.output);
    this.$emit('submit',this.output); //新增
  }
}
</script>
複製代碼

這樣用戶每次點擊ok,都會將數據上傳至LocalStorae

可是這裏出了一個錯誤,以下:

第一次輸入1,點擊ok,打印this.recordListamount是數字1,正確。

image.png

但第二次輸入2,點擊ok,再打印this.recordListamount獲得兩次結果都是2,出現bug。

image.png

Local Storage以下

image.png

緣由是由於this.recordList.push(this.record)this.record只是引用,因此第一次ok和第二次ok,都只是引用了record的地址,結果是兩個2。

修改代碼,record2是一個深拷貝,至關於保存了this.record的副本這樣就能夠實現預想的功能了。

saveRecord(){
      const record2 = JSON.parse(JSON.stringify(this.record));
      this.recordList.push(record2)
      console.log(this.recordList);
    }
複製代碼

問題七: js改寫ts報錯

  1. 改文件名後綴jsts

image.png

  1. 新建一個custom.d.ts,全局聲明RecordItem,賦給data,解決

image.png

image.png

  1. 這裏提交代碼時,又報了錯(暈)
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 |   }
複製代碼

cunstom.d.ts中全局聲明的RecordItem,在Money.vue中卻提示'RecordItem' is not defined

嘗試了不少方法沒有成功,最後又從新聲明瞭一個RecordItem,引入Money.vue中。

image.png

後續若是有更好的解決辦法會更新。

問題八:關於子組件直接修改父組件的值

代碼以下

<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>
複製代碼

vue不推薦直接在子組件中修改父組件傳來的props的值,改寫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"
複製代碼

解決辦法:

改寫v-model="value",再也不給value賦值。

經過onValuechangedvalue進行變動。

// 改後
<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>
複製代碼

問題九:解決id生成問題

問題描述

舉個例子,在組件tagListModel.vuecreate以下

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';
  },
  ...
}
複製代碼

建立相同name的標籤,就會提示重複。

101.10.10.2.gif

後來添加了新功能,在編輯標籤頁面能夠改標籤名,就出現了以下bug——改變標籤{id:1, name:1}name,再次新建標籤時,不能識別標籤重複。

101.10.10.1.gif

解決思路

  1. 首先一個id賦給了標籤,就不要再修改了,由於路由用了id做爲url的地址的一部分。
{
    path: '/labels/edit/:id',
    component: EditLabel
  },
複製代碼

id若是變了,刷新頁面就不存在了。

  1. 其次,id是不能重複的,否則/label/edit/1到底對應哪個標籤頁?

  2. 個人作法是每新建一個標籤,id自增。雖然可能會爆棧,可是能知足很大一部分需求。

實現思路大體說一下,代碼能夠訪問個人github

新建一個ts組件實現id的自增功能,在tagListModel.ts組件的create方法引入這個自增id

問題十: ISO 8601

維基百科-日期和時間的組合表示法

用法以下:

日期和時間的組合表示法,要在時間前面加一大寫字母T,如要表示東八區時間2004年5月3日下午5點30分8秒,能夠寫成2004-05-03T17:30:08+08:00或20040503T173008+08。

image.png

相關文章
相關標籤/搜索