苹果记账反思:抽取公共组件
在写代码时一直牢记:我与重复不共戴天
在目前写的两个页面里,抽取了一些公共组件:
Tag
Type
Input
Button
遇到的问题有:
- 需要传的参数不同,
-
- 用props 父传子
- 用slot ,
比如Input组件 在money页的placeholder是“写点备注吧”
在editLabel页的placeholder是“限三个汉字”
做法是用prop 传递 placeholder变量
EdiltLabel <FormItem isNewTag="+" placeholder="限3个汉字或5个英文字母..." @update:tagName="onTagNameChange" ></FormItem> formItem <input :value="value" @input="onValueChange($event.target.value)" type="text" :placeholder="placeholder">
slot:
在labels页,Button是新建标签
在editLabel页, Button是保存标签
Button.vue
<button class="button" @click="$emit('click', $event)">
<slot></slot>
</button>
label.vue
<Button>新建标签</Button>
editLabel.vue
<Button>保存新标签</Button>
- 在不同位置的css不同:用props传一个参数进去,然后用该参数判断是否增加一个class
:class = 'a===1? 'newClass originalClass' : 'originalClass''
money页的tag:
editLabel页的tag:
css不一样,
所以就传递一个变量进去,通过这个变量判断当前组件用在哪一个页面,然后增加一个class修改css
- 点击事件传递
以input和button为例
EditLabel 里有 FormItem 组件, FormItem组件里有Input
EditLabel传递value进去
<FormItem isNewTag="+"
placeholder="限3个汉字或6个英文字母..."
:value="tag.name"
@update:tagName="onTagNameChange"
></FormItem>
FormItem 接受 value 参数
<div :class="isNewTag === '+'? 'notes-wrapper notes-wrapper-no-bg' : 'notes-wrapper '">
<label class="notes">
<input :value="value"
@input="onValueChange($event.target.value)"
type="text"
:placeholder="placeholder">
</label>
</div>
@Prop({default: ''}) value: string | undefined;
监听input事件,如果输入框内容变化,就调用onValueChange函数,把当前的值传给上层组件
onValueChange(value: string) {
if (this.isNewTag === '+') { // 如果在修改标签页
this.$emit('update:tagName', value);
} else { // 如果在money页记账,触发更新value事件
this.$emit('update:value', value);
}
}
这样的话, 实现了由父组件管理用户输入的内容, 子组件里的Input只是作为一个中间站,如果有数据更新,就立刻通知父组件
关于Button
如果直接在Button上设置点击事件会发现无法触发,因为用户点击的是里面的button, 而不是外面包裹的Button组件
解决思路是 当用户点击button时,button就通知Button用户需要做事情了
解决方法是 在button的click事件上触发click事件,通知Button,
Button.vue
<button class="button" @click="$emit('click', $event)">
<slot></slot>
</button>
Editabel.vue
<Button @click="saveTag">保存新标签</Button>
这时,里面的button被点击时,会立刻触发外面Button的点击事件,然后外面Button监听到之后,就执行saveTag保存新标签