# 记账页面
Money 组件及布局如下:
# .sync
修饰符实现响应式
通过.sync
修饰符绑定则可以统一在父组件上收集各个子组件的状态.
<Panel :expression.sync="record.amount" />
<Tab :value.sync="record.type" />
<InputItem :notes.sync="record.notes" />
<Tag :labels.sync="labels" :selectedTags.sync="record.tags" />
1
2
3
4
2
3
4
# Tag
组件解析
此组件的看点只有switchTag
函数.当被触发时, 它首先根据传入的标签名判断已有的selectedTags
数组里是否包含这个标签, 有则删除, 没有则添加.从而影响样式的更新.其次,发射更新事件(以配合.sync
), 返回值是选中的标签组成的数组.
@Emit("update:selectedTags")
switchTag(label: string) {
const index = this.selectedTags.indexOf(label)
if (index >= 0) {
this.selectedTags.splice(index, 1)
} else {
this.selectedTags.push(label)
}
return this.selectedTags
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# InputItem
组件解析
该组件比较简单, 这里只提一个知识点, 在模板里的事件函数:
<template>
<input
:placeholder="placeholder"
:value="notes"
@input="handleChange($event.target.value)"
type="text"
/>
</template>
<script>
export default {
handleChange(val) {
this.$emit("update:notes", val);
}
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Tab
组件
该组件是我的Giao UI 里引用的组件, 具体实现在另一篇博客里.
# Panel
组件
# 布局
键盘是使用浮动来做的, 如图所示:
除 Ok 键以外的 button 都向左浮动, OK 键向右浮动. 每个 button 的width
为25%
. 而 0 键宽度单独设置为50%
. 最后要在浮动元素的父元素上清除浮动:
parentElement {
clear: both;
display: block;
}
1
2
3
4
2
3
4
# 获取用户输入值
通过点击事件的e.target.textContent
可以获取键盘对应数值.
# 防御性编程
为防止用户做出一些非正常输入, 做防御性编程是很重要的.
# 输入数字的最大长度只能有 16 位
if (this.output.length === 16) {
return;
}
1
2
3
2
3
# 初始为 0, 当输入数字后 0 应该消失
if (this.output === "0") {
if ("0123456789".indexOf(input) >= 0) {
this.output = input;
} else {
this.output += input;
}
return;
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
当我们输入的值是"0123456789"
里的任意一个, 那么原来的0
都会被替换, 否则累加, 在这里只有输入小数点才会累加.
# 只能输一个小数点
if (this.output.indexOf(".") >= 0 && input === ".") {
return;
}
1
2
3
2
3
当输入里有小数点时且输入中又含有小数点则返回.
# 退格
deleteNumber() {
const length = this.output.length
this.output = this.output.substr(0, length - 1) // 获取除了最后一个字符以外的新字符串
if (length === 1) {
this.output = "0" //归零
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7