# 记账页面
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" />
Copied!
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 }
Copied!
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>
Copied!
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; }
Copied!
1
2
3
4
2
3
4
# 获取用户输入值
通过点击事件的e.target.textContent
可以获取键盘对应数值.
# 防御性编程
为防止用户做出一些非正常输入, 做防御性编程是很重要的.
# 输入数字的最大长度只能有 16 位
if (this.output.length === 16) { return; }
Copied!
1
2
3
2
3
# 初始为 0, 当输入数字后 0 应该消失
if (this.output === "0") { if ("0123456789".indexOf(input) >= 0) { this.output = input; } else { this.output += input; } return; }
Copied!
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
当我们输入的值是"0123456789"
里的任意一个, 那么原来的0
都会被替换, 否则累加, 在这里只有输入小数点才会累加.
# 只能输一个小数点
if (this.output.indexOf(".") >= 0 && input === ".") { return; }
Copied!
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" //归零 } }
Copied!
1
2
3
4
5
6
7
2
3
4
5
6
7