Vue:父组件传值的那些事以及父组件数据管理那些事

391 阅读2分钟


一、关于组件data的初始化

我们初始化一个组件,通常是用到外部传进来的数据,比如我的Note.vue中的输入框的默认值,如果由外部的Money.vue组件传进来,同时Money.vue组件还控制着类似于Notes.vue的多个组件的初始化。

怎么做到把数据存在数据库里面,原理就在于把record,同步地和每个组件结合(.sync),做到一个入口,即record里面写的就是每个组件的默认值而不是分别在每个组件里写默认值,做到一个出口,把所有数据放到record里面

这是一种控制力,只要改父组件的record那么所有组件的初始值都会更新

下面代码为例

<template>
  <div>

      <NumberPad :value.sync="record.amount" @submit="saverecord" />
      <Types :type.sync="record.type" />
      <Notes:value.sync="record.notes"/>
      <Tags @update:value="onUpdateTag" />

  </div>
</template>

  record: RecordItem = {
    tag: "住",
    notes: "",
    type: "-",
    amount: 0
  };

我们将数据很好的管理起来,通过.sync修饰符

二、使用v-model的bug

<Notes :value.sync="record.notes" />

<input type="text" v-model="valueInside" placeholder="写点备注吧~" />

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

@Component
export default class Notes extends Vue {
  @Prop() readonly value!: string;
  valueInside = this.value;
  @Watch("valueInside")
  onValueChanged(valueInside: string) {
     this.$emit("update:value", valueInside);
  }

}
</script>

但是我们通过prop把数据从父组件拿进来,v-model会直接修改prop的

解决办法:

以上代码解决了直接修改prop的问题,把外部传进来的prop(value),赋值给valueInside,v-model修改valueInside,我们监听,valueInside,当它改变时把它作为value传出去,传给父组件的record.notes,record.notes一改变就会使value改变

三、关于update:value

.sync修饰符会自动监听update:xxx事件,然后更新到外面的data,xxx取决于父组件传进来的变量名字。

但是我们传出去没必要和这个xxx名字一致

四、我们可以把一份东西传出去两次

我们可以把一份东西传出去两次

this.$emit("update:value", parseFloat(this.output));
this.$emit("submit",this.output)

把output变成两个东西传出去

五、关于$emit

组件没有事件,只能在里面用emit来传递事件

<Button @click="createTag">新建标签</Button>

<button class="newTag" @click="$emit('click',$event)">
    <slot/>
</button>

传递点击事件

<Button @click.native="createTag">新建标签</Button>

你可能有很多次想要在一个组件的根元 record: RecordItem = { tag: "住", notes: "", type: "-", amount: 0 };

六、经典bug

经典bug,为什么amount始终一样

  record: RecordItem = {
    tag: "住",
    notes: "",
    type: "-",
    amount: 0
  };

  saverecord() {
    this.recordList.push(this.record)
  }

因为每次push的都是同一个record,地址完全一样,此时我们需要深拷贝

  saveRecord() {
    const recordFake = JSON.parse(JSON.stringify(this.record));
    this.recordList.push(recordFake);
  }

七、数据库版本

开头提到了数据库,那么我们顺便提一下,用localStorage代替数据库

引入数据库版本以及数据库升级

window.localStorage.setItem("version", "0.0.1");

const version = window.localStorage.getItem("version") || '0';
const recordList: Record[] = JSON.parse(window.localStorage.getItem('recordList')|| '[]')
if (version<'0.0.2'){
  if (version === '0.0.1'){
    recordList.forEach(record => {
      record.createAt = new Date()
    })
  }
}

window.localStorage.setItem("version", "0.0.2");

数据库升级最好一个一个版本升级,不要试图在一个if里把你的数据库升级,即使你可以一下子从0.0.1=>8.00,