Composite function in Vue3

Digital management platform
Vue3+Vite+VueRouter+Pinia+Axios+ElementPlus tutorial
permission system-Mall
personal blog address

1. First acquaintance

Official explanation: "Composables" is a function that uses Vue's combined API to encapsulate and reuse stateful logic.

  • Stateful logic
    Stateful logic is responsible for managing state that changes over time. In the process of project development, such as: the realization of functions such as touch gestures and database connection status.
  • Stateless logic
    returns the expected value immediately after receiving some parameters, which is stateless logic. For example, when building front-end applications, some date formatting functions are often extracted into a separate time.js file for reuse in different components or scripts. Of course, there are many stateless logic libraries, such as: lodash, moment, etc.

Here we need to mention the concept of "non-rendering component" : it only includes reusable logic (data acquisition, paging, etc.) without rendering content by itself, and the view output is fully handed over to the consumer component through the scope slot.
Most of the functionality that can be achieved with renderless components can be achieved in another, more efficient way through the composition API, without incurring the overhead of additional component nesting. Therefore, if it is just a pure logic encapsulation (no view output is required), it is recommended to use a combined API implementation .
insert image description here

2. Comparison with Mixin

mixin is an api in Vue2 that also allows us to extract component logic into reusable units. However mixins have three main shortcomings:

  1. Unclear Data Origins
    When multiple mixins are used, it becomes unclear which mixin the data properties on an instance come from, making it difficult to trace implementations and understand component behavior. This is why we recommend using the ref + destructuring pattern in combined functions: to make the source of attributes clear at a glance when consuming components.
  2. Namespace conflicts
    Multiple mixins from different authors may register the same property name, causing naming conflicts. With composite functions, you can avoid identical key names by renaming variables when destructuring them.
  3. Implicit cross-mixin communication
    Multiple mixins need to rely on shared property names to interact, which makes them implicitly coupled together. And the return value of a composite function can be passed as an argument to another composite function, just like ordinary functions.
    Therefore, the official no longer recommends continuing to use mixin in Vue 3.

3. Flexibility

As the complexity of your components grows, you may end up with too many components to query and understand. The composition API will give you enough flexibility to split component code into smaller functions based on logical concerns. This is more conducive to code organization and reuse, thereby improving the code structure.

<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>

4. Case

Define the mouse follow case in the component

<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>

If you want to reuse this logic in multiple components, you need to extract this logic into an external file in the form of a composite function, as follows:

// 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 
}

Note: Composition function conventions are named in camelCase and start with "use".

Component reuse

<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>

Guess you like

Origin blog.csdn.net/qq_39335404/article/details/129808997