赞
踩
官方给出的解释:“组合式函数”(Composables) 是一个利用 Vue 的组合式 API 来封装和复用有状态逻辑的函数。
组合式函数约定用驼峰命名法命名,并以“use”作为开头。
可以通过抽取组合式函数改善代码结构。
抽取组合式函数不仅是为了复用,也是为了代码组织。随着组件复杂度的增高,你可能会最终发现组件多得难以查询和理解。组合式 API 会给予你足够的灵活性,让你可以基于逻辑问题将组件代码拆分成更小的函数:
<script setup>
import { useFeatureA } from './featureA.js'
import { useFeatureB } from './featureB.js'
import { useFeatureC } from './featureC.js'
const { foo, bar } = useFeatureA()
const { baz } = useFeatureB(foo)
const { qux } = useFeatureC(baz)
</script>
在某种程度上,你可以将这些提取出的组合式函数看作是可以相互通信的组件范围内的服务。
数字化管理平台
Vue3+Vite+VueRouter+Pinia+Axios+ElementPlus教程
权限系统-商城
个人博客地址
mixin 是 Vue2 中的 api,它也让我们能够把组件逻辑提取到可复用的单元里。然而 mixins 有三个主要的短板:
随着组件复杂度的增高,你可能会最终发现组件多得难以查询和理解。组合式 API 会给予你足够的灵活性,让你可以基于逻辑问题将组件代码拆分成更小的函数。这更利于代码的组织和复用,从而改善代码结构。
<script setup>
import { useFeatureA } from './featureA.js'
import { useFeatureB } from './featureB.js'
import { useFeatureC } from './featureC.js'
const { foo, bar } = useFeatureA()
const { baz } = useFeatureB(foo)
const { qux } = useFeatureC(baz)
</script>
组件中定义鼠标跟随案例
<script setup>
import { onMounted, onUnmounted, reactive } from 'vue';
// 实现鼠标追踪器效果
const movePosi = reactive({ x: 0, y: 0 })
function MyMouseMove(e) {
movePosi.x = e.clientX
movePosi.y = e.clientY
}
onMounted(() => window.addEventListener('mousemove', MyMouseMove))
onUnmounted(() => window.removeEventListener('mousemove', MyMouseMove))
</script>
<template>
<div class="mouseRender" :style="{ top: movePosi.y + 'px', left: movePosi.x + 'px' }">
<div>x:{{ movePosi.x }}</div>
<div>y:{{ movePosi.y }}</div>
</div>
</template>
<style scoped>
.mouseRender {
position: fixed;
top: 0;
left: 0;
z-index: 1000;
}
</style>
如果想在多个组件中复用这个逻辑,需要把这个逻辑以一个组合式函数的形式提取到外部文件中,如下:
// event.js
import { onMounted, onUnmounted } from 'vue'
export function useEventListener(target, event, callback) {
// 如果你想的话,
// 也可以用字符串形式的 CSS 选择器来寻找目标 DOM 元素
onMounted(() => target.addEventListener(event, callback))
onUnmounted(() => target.removeEventListener(event, callback))
}
可以嵌套多个组合式函数:一个组合式函数可以调用一个或多个其他的组合式函数。这使得我们可以像使用多个组件组合成整个应用一样,用多个较小且逻辑独立的单元来组合形成复杂的逻辑。
import { ref,reactive } from 'vue'
import { useEventListener } from './event'
// 按照惯例,组合式函数以“use”开头
export function useMouse() {
const movePosi = reactive({ x: 0, y: 0 })
// 组合式函数可以随时更改其状态。
useEventListener(window, 'mousemove', (event) => {
movePosi.x = event.clientX
movePosi.y = event.clientY
})
// 通过返回值暴露所管理的状态
return movePosi
}
注:组合式函数约定用驼峰命名法命名,并以“use”作为开头。
<script setup>
import { useMouse } from './mouse.js'
const { x, y } = useMouse()
</script>
<div class="mouseRender" :style="{ top: y + 'px', left: x + 'px' }">
<div>x:{{ x }}</div>
<div>y:{{ y }}</div>
</div>
useMouse() 组合式函数可以接收一个参数。在做异步数据请求时,我们常常需要处理不同的状态:加载中、加载成功和加载失败。fetch请求返回Promise对象,想要获取数据需要做进一步处理。
// fetch.js
import { ref } from 'vue'
export function useFetch(url) {
const data = ref(null)
const error = ref(null)
fetch(url)
.then((res) => res.json())
.then((json) => (data.value = json))
.catch((err) => (error.value = err))
return { data, error }
}
<script setup>
import { useFetch } from './fetch.js'
const { data, error } = useFetch('...')
</script>
useFetch() 接收一个静态 URL 字符串作为输入——因此它只会执行一次 fetch 并且就此结束。如果我们想要在 URL 改变时重新 fetch 呢?
const url = ref('/initial-url')
// 1. 接收一个 ref
const { data, error } = useFetch(url)
// 这将会重新触发 fetch
url.value = '/new-url'
// 2. 接收一个getter
// 当 props.id 改变时重新 fetch
const { data, error } = useFetch(() => `/posts/${props.id}`)
为了实现这一点,我们需要将响应式状态传入组合式函数,并让它基于传入的状态来创建执行操作的侦听器。
用 watchEffect() 和 toValue() API 来重构 fetch.js
// fetch.js
import { ref, watchEffect, toValue } from 'vue'
export function useFetch(url) {
const data = ref(null)
const error = ref(null)
watchEffect(() => {
// 在 fetch 之前重置状态
data.value = null
error.value = null
// toValue() 将可能的 ref 或 getter 解包
fetch(toValue(url))
.then((res) => res.json())
.then((json) => (data.value = json))
.catch((err) => (error.value = err))
})
return { data, error }
}
toValue() 是一个在 3.3 版本中新增的 API。它的设计目的是将 ref 或 getter 规范化为值。如果参数是 ref,它会返回 ref 的值;如果参数是函数,它会调用函数并返回其返回值。否则,它会原样返回参数。它的工作方式类似于 unref(),但对函数有特殊处理。
注意 toValue(url) 是在 watchEffect 回调函数的内部调用的。这确保了在 toValue() 规范化期间访问的任何响应式依赖项都会被侦听器跟踪。
这个版本的 useFetch() 现在能接收静态 URL 字符串、ref 和 getter,使其更加灵活。watch effect 会立即运行,并且会跟踪 toValue(url) 期间访问的任何依赖项。如果没有跟踪到依赖项(例如 url 已经是字符串),则 effect 只会运行一次;否则,它将在跟踪到的任何依赖项更改时重新运行。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。