最近要做一个与颜色选择器有关功能:当用户在颜色面板里预选颜色时,需要同时更新当前画布的颜色;如果取消选择,则将画布背景重置为初始颜色;如果确定了颜色,则更新当前画布颜色。比较容易想到的方法是,用两个变量分别记录初始值 originValue 与当前值 value :如果只是选择,那就用去更新 value ;如果取消选择,重置为 originValue ;如果选中,将 originValue 更新为 value 。不过,除了颜色,还有背景图,也需要用到这个类似的功能。既然多个地方用到了,那就写的优雅一点,封装一个类来实现吧。
与上述逻辑相同,需要两个变量用来记录 originValue 和 value ,而且根据不同的操作,可以划分为三种更新方式:
- change :更新 value ;
- update :将 originValue 改为 value ;
- reset :将 value 改为 originValue 。
在实例化时,需要传入一个初始值,用以构造函数内部初始化。
大体思路有了,先来实现一个简单的版本。我给它起了一个高大上的名字:PseudoUpdate(伪更新) 。
// PseudoUpdate 1.0
class PseudoUpdate {
constructor(value) {
this.originValue = value
this.value = value
}
change(value) {
this.value = value
}
update(value) {
this.originValue = value
}
reset() {
this.value = this.originValue
}
}
用法也很简单。
const color = new PseudoUpdate("red")
// 当预选颜色时
function handleChange(newColor) {
color.change(newColor)
}
// 当确定颜色时
function handleUpdate(newColor) {
color.update(newColor)
}
// 当取消选择时
function handleReset() {
color.reset()
}
ViewDesign 中的 ColorPicker 刚好提供了三个 event :
两者搭配使用就是:
<color-picker
v-model="color.value"
@on-change="handleUpdate"
@on-active-change="handleChange"
@on-open-change="isOpen => !isOpen && handleReset()"
/>
而实际开发的时候,color 不一定是当前组件中的,有可能是从其他组件中传过来的,这时候,如果需要更新其他组件中的 color ,就需要监听 color.value
的值,然后通知其他组件去更新。
再或者,可以在类的构造函数中,再传入一个 callback 函数,当内部的 value 发生变化时,去执行这个 callback 方法。
// PseudoUpdate 2.0
class PseudoUpdate {
constructor(value, callback) {
this.originValue = value
this.value = value
this.callback = callback
}
change(value) {
this.value = value
this.callback(value)
}
update(value) {
this.originValue = value
}
reset() {
this.value = this.originValue
this.callback(value)
}
}
如果在 callback 内部使用到了 this ,这里需要额外谨慎!
两者其实差别不大,相比之下,第二种方法更清晰一点,只需要定义一个 callback 方法,其余的交给 PseudoUpdate 内部去做就可以了,无需关心其他问题。