官网地址:cn.vuejs.org/guide/reusa…
“组合式函数”(Composables) 是一个利用 Vue 的组合式 API 来封装和复用有状态逻辑的函数。
有状态逻辑的函数:请记住这 有状态逻辑 5个字
无状态逻辑的函数:即平常抽离出的那些可复用的函数
个人认为:其实就是普通函数。正常的普通函数调用就是了,只不过里面的变量用 reactive/ref 等包装过后就可以用在模板和其他watch的钩子函数。
为什么会出现 “组合式函数”
Vue2 关于代码的复用使用的是 mixins。而 mixins 存在如下问题:
-
不清晰的数据来源:当使用多个 mixins 时,确切知道数据属性来自哪个 mixin 变得困难。
// 定义一个名为 mixinA 的 mixin const mixinA = { data() { return { message: 'Mixin A', }; }, }; // 定义另一个名为 mixinB 的 mixin const mixinB = { data() { return { message: 'Mixin B', }; }, }; // 使用两个 mixin new Vue({ mixins: [mixinA, mixinB], created() { console.log(this.message); // 这里不清楚 `message` 属性来自哪个 mixin }, }); -
命名空间冲突:多个 mixin 可能会注册相同的属性名,导致命名冲突
// 定义一个名为 mixinA 的 mixin const mixinA = { data() { return { message: 'Mixin A', }; }, }; // 定义另一个名为 mixinB 的 mixin,不知不觉中重复了属性名 const mixinB = { data() { return { message: 'Mixin B', }; }, }; // 使用两个 mixin new Vue({ mixins: [mixinA, mixinB], created() { console.log(this.message); // 这里的 `message` 冲突了 }, }); -
隐式的跨 mixin 交流:多个 mixin 需要依赖共享的属性名进行相互作用,这使得它们隐式地耦合在一起。
// 定义 mixinA,依赖另一个 mixinB 的属性 const mixinA = { computed: { reversedMessage() { return this.message.split('').reverse().join(''); }, }, }; // 定义 mixinB,提供一个属性 const mixinB = { data() { return { message: 'Hello from mixin B', }; }, }; // 使用两个 mixin,mixinA 隐式依赖 mixinB 的属性 new Vue({ mixins: [mixinA, mixinB], created() { console.log(this.reversedMessage); // mixinA 隐式依赖 mixinB 的属性 }, });
那来看看 Vue 的组合式函数是如何解决上面出现的三种问题?
-
不清晰的数据来源:在组合式函数中,可以通过使用
ref和解构模式明确指定数据属性的来源。import { ref } from 'vue'; function useMixinA() { const message = ref('Mixin A'); return { message }; } function useMixinB() { const message = ref('Mixin B'); return { message }; } // 在组件中使用组合式函数 export default { setup() { const { message: messageA } = useMixinA(); const { message: messageB } = useMixinB(); console.log(messageA.value); // 明确知道来自 useMixinA console.log(messageB.value); // 明确知道来自 useMixinB }, }; -
命名空间冲突:组合式函数允许将属性明确命名,避免不同 mixin 之间的属性名冲突。
function useMixinA() { const messageA = ref('Mixin A'); return { messageA }; } function useMixinB() { const messageB = ref('Mixin B'); return { messageB }; } // 在组件中使用组合式函数 export default { setup() { const { messageA } = useMixinA(); const { messageB } = useMixinB(); console.log(messageA.value); // 不会冲突 console.log(messageB.value); // 不会冲突 }, }; -
隐式的跨 mixin 交流:组合式函数可以更明确地处理不同函数之间的交流,可以将一个组合式函数的返回值作为另一个组合式函数的参数传递,从而更清晰地定义和管理依赖关系。
function useMixinA(message) { const reversedMessage = computed(() => message.value.split('').reverse().join('')); return { reversedMessage }; } function useMixinB() { const message = ref('Hello from mixin B'); return { message }; } // 在组件中使用组合式函数 export default { setup() { const { message } = useMixinB(); const { reversedMessage } = useMixinA(message); console.log(reversedMessage.value); }, };