下午正在看我们组大帅老湿写的composition 动画演示的文章。
就有一个产品小姐姐找我,单聊。
一、花里胡哨的需求
- 第一天 : 产品妹子突发奇想,让我把按钮字体随机变色。
- 两个小时后: 产品妹子又说是不是按钮的背景也可以随机变色。
两分钟后: 产品妹子又说 两个按钮的变色频率是不是可以不一样,或者随心组合。
我就问他要不要 按照手机壳变色呢
产品妹子说那样可能会被你们暴打。
二、解决思路
这个需求看起来花里胡哨实际上核心的逻辑只有一个就是随机变色。
至于后面提出的变态的变色频率自定需求可以考虑将逻辑函数升阶为函数工厂的方式解决。
难度在实现复杂的逻辑组合时很难保证代码的耦合度。这也是Vue2的一个明显的缺点。React在使用Hooks后这个问题得以很好的解决。
1. OptionAPI的不足
1.1 烦人反复横跳
在传统的Vue OptionsAPI中,新增或者修改一个需求,就需要分别在data,methods,computed里修改 ,滚动条反复上下移动,我称之为『反复横跳』
1.2 Mixin与继承之殇
想象一下如果我们想在所有的组件中都实现这样的花里胡哨的需求,又要考虑代码的耦合度。我们首先想到的是
- Mixins
- 高阶组件 (Higher-order Components, aka HOCs)
- Renderless Components (基于 scoped slots / 作用域插槽封装逻辑的组件
但三者都不是非常的理想,主要问题存在
- 模板数据来源不清晰, 譬如mixin光看模板很难分清一个属性是哪里来的。
- 命名空间冲突
- 性能问题。 譬如HOC需要额外的组件逻辑嵌套 会导致无谓的性能开销。
2. CompositionAPI横空出世
composition就是为了解决这个问题存在的,通过组合的方式,把零散在各个data,methods的代码,重新组合,一个功能的代码都放在一起维护,并且这些代码可以单独拆分成函数。
三、代码实现
- 编写一个变色的复合API工厂 首先将变色逻辑封装在一个复合API工厂中,这个API可以还可以保证用参数控制变色范围,和变色频率。你要怎么变我就怎么变。
function useColor(type, time) {
const state = reactive({
color: '#000000'
})
onMounted(() => {
setInterval(() => {
const r = type === 'r' ? Math.floor(Math.random() * 255).toString(16) : '00'
const g = type === 'g' ? Math.floor(Math.random() * 255).toString(16) : '00'
const b = type === 'b' ? Math.floor(Math.random() * 255).toString(16) : '00'
var color =
`#${ r + g + b}`
state.color = color
}, time)
})
return toRefs(state)
}
- 根据需求组装视图组件
我们只需要根据产品小姐姐的需求,调用原有的变色API去组装就可以了,你要怎样就怎样。由于输出的数据本身还是响应式的,其实你即使组合后也可以是响应式的。所以几乎是随心而变。
const MyComponent = {
template: `<button type="button" class="el-button" :style="{ background,color }"><span>按钮</span></button>`,
setup() {
const {
color
} = useColor('r', 100)
const {
color: background
} = useColor('b', 1000)
return {
color,
background
}
}
}
createApp(MyComponent).mount('#app')
四、总结
CompositionAPI我认为是Vue3中最香的功能,可以让我们的逻辑自由的组合。
本文使用 mdnice 排版
- 这是我们团队的开源项目 element3
- 一个支持 vue3 的前端组件库