Moeny.vue读取各组件数据
<template>
<Layout class-prefix="layout">
<NumberPad @update:value="onUpdateAmount"/>
<Types :value.sync="record.type"/>
<!-- 如果想给一个组件初始值,然后在更新时拿到最新的值,就使用.sync-->
<!-- <Types :value="record.type" @update:value="onUpdateType"/>-->
<Notes @update:value="onUpdateNotes"/>
<Tags :data-source.sync="tags" @update:value="onUpdateTags"/>
</Layout>
</template>
<script lang="ts">
import Vue from 'vue';
import NumberPad from '@/components/Money/NumberPad.vue';
import Types from '@/components/Money/Types.vue';
import Notes from '@/components/Money/Notes.vue';
import Tags from '@/components/Money/Tags.vue';
import {Component} from 'vue-property-decorator';
type Record = {
tags: string[],
notes: string,
type: string,
amount: number
}
@Component({
components: {Tags, Notes, Types, NumberPad}
})
export default class Money extends Vue {
tags = ['衣服', '吃饭', '交通', '水电', '房租', '彩妆'];
record: Record = {
tags: [], notes: '', type: '-', amount: 0
};
onUpdateTags(value: string[]) {
this.record.tags = value;
}
onUpdateNotes(value: string) {
this.record.notes = value;
}
// onUpdateType(value: string) {
// this.record.type = value;
// }
onUpdateAmount(value: string) {
this.record.amount = parseFloat(value);
}
}
</script>
<style lang="scss">
.layout-content {
display: flex;
flex-direction: column-reverse;
}
</style>
.sync 修饰符
在有些情况下,我们可能需要对一个 prop 进行“双向绑定”。不幸的是,真正的双向绑定会带来维护上的问题,因为子组件可以变更父组件,且在父组件和子组件两侧都没有明显的变更来源。
这也是为什么我们推荐以 update:myPropName 的模式触发事件取而代之。举个例子,在一个包含 title prop 的假设的组件中,我们可以用以下方法表达对其赋新值的意图:
this.$emit('update:title', newTitle)
然后父组件可以监听那个事件并根据需要更新一个本地的数据 property。例如:
<text-document
v-bind:title="doc.title"
v-on:update:title="doc.title = $event"
></text-document>
为了方便起见,我们为这种模式提供一个缩写,即 .sync 修饰符:
<text-document v-bind:title.sync="doc.title"></text-document>
注意带有 .sync 修饰符的 v-bind 不能和表达式一起使用 (例如 v-bind:title.sync=”doc.title + ‘!’” 是无效的)。取而代之的是,你只能提供你想要绑定的 property 名,类似 v-model。
当我们用一个对象同时设置多个 prop 的时候,也可以将这个 .sync 修饰符和 v-bind 配合使用:
<text-document v-bind.sync="doc"></text-document>
这样会把 doc 对象中的每一个 property (如 title) 都作为一个独立的 prop 传进去,然后各自添加用于更新的 v-on 监听器。
将 v-bind.sync 用在一个字面量的对象上,例如 v-bind.sync=”{ title: doc.title }”,是无法正常工作的,因为在解析一个像这样的复杂表达式的时候,有很多边缘情况需要考虑。
使用 LocalStorage
<script lang="ts">
import Vue from 'vue';
...
import {Component, Watch} from 'vue-property-decorator';
type Record = {
tags: string[],
notes: string,
type: string,
amount: number,//数据类型
createdAt?: Date//类or构造函数
}
@Component({
components: {Tags, Notes, Types, NumberPad}
})
export default class Money extends Vue {
tags = ['衣服', '吃饭', '交通', '水电', '房租', '彩妆'];
recordList: Record[] = JSON.parse(window.localStorage.getItem('recordList') || '[]');
record: Record = {
tags: [], notes: '', type: '-', amount: 0
};
onUpdateTags(value: string[]) {
this.record.tags = value;
}
onUpdateNotes(value: string) {
this.record.notes = value;
}
// onUpdateType(value: string) {
// this.record.type = value;
// }
onUpdateAmount(value: string) {
this.record.amount = parseFloat(value);
}
saveRecord() {
const record2: Record = JSON.parse(JSON.stringify(this.record));//深拷贝保存副本,防止之前的记录被覆盖
record2.createdAt = new Date();
this.recordList.push(record2);
console.log(this.recordList);
}
@Watch('recordList')
onRecordListChange() {
window.localStorage.setItem('recordList', JSON.stringify(this.recordList));
}
}
</script>