🗒️逻辑复用

来自官网 https://cn.vuejs.org

在 Vue 中重用代码的方式:

  1. 组件:主要的构建模块

  2. 组合式函数:侧重有状态的逻辑

  3. 自定义指令:主要是为了重用涉及普通元素的底层 DOM 访问的逻辑

    • 不推荐在组件上使用自定义指令

    • 只有当所需功能只能通过直接的 DOM 操作来实现时,才应该使用自定义指令

    • 其他情况下应尽可能地使用 v-bind 这样的内置指令来声明式地使用模板,更高效,也对服务端渲染更友好

  4. 插件:为 Vue 添加全局功能的工具代码

1. 组合式函数

作用:利用 Vue 的组合式 API 来封装和复用有状态逻辑。

1.1 封装+有状态

  1. 封装+复用(改善代码结构)

    1. 组合式函数 vs 作用域插槽

      • 组合式函数:纯逻辑复用

      • 作用域插槽:需同时复用逻辑和视图布局时

    2. 组合式函数和 React 的自定义 React hooks 非常相似

    3. Vue3 不再推荐使用 Vue2 的 mixins 选项

  2. 有状态逻辑

    • 无状态逻辑:在接收一些输入后,立刻返回所期望的输出

    • 有状态逻辑:负责管理会随时间而变化的状态

1.2 用法

把核心逻辑移到外部函数中,然后 return 要暴露的状态

  1. 函数名:约定用驼峰命名法,并以“use”开头

  2. 返回值:约定始终返回一个包含多个 ref 的普通的非响应式对象

    • 好处:该对象在组件中被解构为 ref 之后仍可以保持响应性

  3. 函数参数:可以是原始值,也可以是 ref 数据

    • 参数可统一用 unref() 来接收,或者手动判断 isRef()

    • 也可以针对 ref 手动显式地写 watch 逻辑

eg. useFetch(url) 来统一处理请求的不同状态:加载中、加载成功和加载失败

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

1.3 注意事项

  • 组合式函数:可嵌套

  • 建议组合式函数始终被同步地执行

  • 若执行了副作用:在服务端渲染场景时;确保在 onUnmounted() 时清理副作用

2. 自定义指令

一个自定义指令由一个包含类似组件生命周期钩子的对象来定义,钩子函数会接收到指令所绑定元素作为其参数。

eg1. 在 <script setup> 中,任何以 v 开头的驼峰式命名的变量都可以被用作一个自定义指令

<script setup>
  // 在模板中启用 v-focus
  const vFocus = {
    mounted: el => el.focus()
  };
</script>

<template>
  <input v-focus />
</template>

eg2. 在应用层级全局注册一个自定义指令

const app = createApp({});

// 使 v-focus 在所有组件中都可用
app.directive("focus", {
  /* ... */
});

3. 插件

插件 (Plugins) 是一种能为 Vue 添加全局功能的工具代码。

一个插件可以是一个拥有 install() 方法的对象,也可以直接是一个安装函数本身。

使用插件的几种常见场景:

  1. 通过 app.component()app.directive() 注册一到多个全局组件或自定义指令

  2. 通过 app.provide() 使一个资源可被注入进整个应用

  3. app.config.globalProperties 中添加一些全局实例属性或方法

  4. 一个可能上述三种都包含了的功能库,例如 vue-router

Last updated