简介
“组合式函数”(Composables) 是一个利用 Vue 的组合式 API 来封装和复用有状态逻辑的函数。
我们可以把一些可以复用的逻辑封装成组合式函数放到js文件中,在vue文件中通过import来使用这些逻辑,使vue文件更瘦,逻辑更清晰。
一个小栗子,通过计数器改变x、y的值,并使用组合式函数处理add的过程,代码如下:
import { toValue } from 'vue'// x、y为ref响应式的number类型
export function useAdd(x, y) {let xVal = toValue(x)let yVal = toValue(y)let num = xVal + yValreturn num;
}
<template><div class="box"><div class="row"><div class="intro">x = {{ x }}</div><el-input-number style="height: 44px; margin-top: 10px;" v-model="x" @change="handleChange" :min="0" :max="100" label="描述文字"></el-input-number></div><div class="row"><div class="intro">y = {{ y }}</div><el-input-number style="height: 44px; margin-top: 10px;" v-model="y" @change="handleChange" :min="0" :max="100" label="描述文字"></el-input-number></div><div class="row"><div class="intro">add = {{ addResult }}</div></div></div>
</template>
<script setup>
import { ref } from 'vue'
import { useAdd } from './utils/add'const x = ref(0);
const y = ref(0);
const addResult = ref(0);
const handleChange = () => {addResult.value = useAdd(x, y)
}
</script>
<style scoped lang="less">
.box {display: flex;flex-direction: column;margin: 20px;padding: 10px;background-color: antiquewhite;.row {display: flex;flex-direction: row;.intro {margin-right: 30px;padding-left: 30px;padding-right: 30px;background-color: bisque;}}
}
</style>
在js文件中可以引入vue的模块,在处理ref或者reactive响应式数据时,我们这里是用了vue中的toValue做了处理。
优势
以下内容摘抄自vue的官方文档
和 Mixin 的对比
Vue 2 的用户可能会对 mixins 选项比较熟悉。它也让我们能够把组件逻辑提取到可复用的单元里。然而 mixins 有三个主要的短板:
-
不清晰的数据来源:当使用了多个 mixin 时,实例上的数据属性来自哪个 mixin 变得不清晰,这使追溯实现和理解组件行为变得困难。这也是我们推荐在组合式函数中使用 ref + 解构模式的理由:让属性的来源在消费组件时一目了然。
-
命名空间冲突:多个来自不同作者的 mixin 可能会注册相同的属性名,造成命名冲突。若使用组合式函数,你可以通过在解构变量时对变量进行重命名来避免相同的键名。
-
隐式的跨 mixin 交流:多个 mixin 需要依赖共享的属性名来进行相互作用,这使得它们隐性地耦合在一起。而一个组合式函数的返回值可以作为另一个组合式函数的参数被传入,像普通函数那样。
基于上述理由,我们不再推荐在 Vue 3 中继续使用 mixin。保留该功能只是为了项目迁移的需求和照顾熟悉它的用户。
和无渲染组件的对比
在组件插槽一章中,我们讨论过了基于作用域插槽的无渲染组件,我们甚至用它实现了一样的鼠标追踪器示例。
组合式函数相对于无渲染组件的主要优势是:组合式函数不会产生额外的组件实例开销。当在整个应用中使用时,由无渲染组件产生的额外组件实例会带来无法忽视的性能开销。
我们推荐在纯逻辑复用时使用组合式函数,在需要同时复用逻辑和视图布局时使用无渲染组件。