Vue 可组合项的良好实践和设计模式

19,786次阅读
没有评论

共计 3433 个字符,预计需要花费 9 分钟才能阅读完成。

按照一个系统的来说,可组合项负责存储主要业务逻辑(如计算、操作、流程),因此它们是应用程序的关键部分。

通过重构构建新可组合项的方法,使它们可维护、易于测试且真正有用。

在本文中,我将总结我们创建的想法,并将它们与我在几篇文章中读到的良好实践和设计模式相结合。

所以本文将分为三个部分:

  1. 通用设计模式

  2. 我的建议

  3. 进一步阅读

享受并且让我知道您在项目中使用的模式和实践🚀

通用设计模式

我认为了解构建可组合项模式的最佳来源实际上是 Vue.js 文档,您可以在此处查看(https://vuejs.org/guide/reusability/composables.html)

基本可组合

Vue 文档显示了以下 useMouse 可组合项的示例:

Vue 文档显示了以下 useMouse 可组合项的示例:// mouse.js
import {ref, onMounted, onUnmounted} from 'vue'

// 按照惯例,可组合函数名称以“use”开头
export function useMouse() {
  // 由可组合项封装和管理的状态
  const x = ref(0)
  const y = ref(0)

  // 可组合项可以随着时间的推移更新其托管状态。function update(event) {
    x.value = event.pageX
    y.value = event.pageY
  }

  // 可组合项还可以挂接到其所有者组件的
  // 设置和拆卸副作用的生命周期。onMounted(() => window.addEventListener('mousemove', update))
  onUnmounted(() => window.removeEventListener('mousemove', update))

  // 将托管状态公开为返回值
  return {x, y}
}

稍后可以在组件中使用它,如下所示:


异步可组合项

为了获取数据,Vue 建议使用以下可组合结构:

import {ref, watchEffect, toValue} from 'vue'

export function useFetch(url) {const data = ref(null)
  const error = ref(null)

  watchEffect(() => {
    // 获取之前重置状态..
    data.value = null
    error.value = null
    // toValue() 解开潜在的 refs 或 getters
    fetch(toValue(url))
      .then((res) => res.json())
      .then((json) => (data.value = json))
      .catch((err) => (error.value = err))
  })

  return {data, error}
}

然后可以在组件中使用它,如下所示:

可组合合约

根据上面的示例,以下是所有可组合项都应遵循的约定:

  1. 例如,可组合文件名应以 use 开头 useSomeAmazingFeature.ts

  2. 它可以接受输入参数,这些参数可以是字符串等基本类型,也可以接受 refs 和 getter,但它需要使用 toValue 帮助器

  3. 可组合项应该返回一个 ref 值,可以在解构可组合项后访问该值,例如 const {x, y} = useMouse()

  4. 可组合项可以保存可以在应用程序中访问和修改的全局状态。

  5. 可组合性可能会导致副作用,例如添加窗口事件侦听器,但在卸载组件时应清除它们。

  6. 可组合项可以调用内部的其他可组合项。

  7. 可组合项应在内部包装某些逻辑,当过于复杂时,应将它们提取到单独的可组合项中以便于测试。

我的建议

我已经为我的工作项目和开源项目构建了多个可组合项 – NuxtAlgolia、NuxtCloudinary、NuxtMedusa,因此基于这些,我想根据我的经验在上面的合同中添加一些要点。

> 有状态或 / 和纯函数可组合项

在代码标准化的某个时刻,您可能会得出这样的结论:您希望对可组合项中的状态保留做出决定。

最容易测试的函数是那些不存储任何状态的函数(即它们是简单的输入 / 输出函数),例如负责将字节转换为人类可读值的可组合函数。它接受一个值并返回一个不同的值 – 它不存储任何状态。

别误会我的意思,你不必做出决定 OR。您可以完全保留有状态和无状态可组合项。但这应该是一个书面决定,以便以后更容易与他们合作 🙂

可组合项的单元测试

我们希望使用 Vitest 为我们的前端应用程序实施单元测试。在后端工作时,进行单元测试代码覆盖率非常有用,因为您主要关注逻辑。然而,在前端,您通常使用视觉效果。

因此,我们认为对整个组件进行单元测试可能不是最好的主意,因为我们基本上将对框架本身进行单元测试(如果按下按钮,检查状态是否更改或模式是否打开)。

由于我们已将所有业务逻辑移至可组合项(基本上是 TypeScript 函数)内,因此它们很容易使用 Vitest 进行测试,并且允许我们拥有更稳定的系统。

可组合项的范围

不久前,在 VueStorefront 中,我们开发了自己的可组合方法(早在它们实际上像这样被调用之前)。在我们的方法中,我们使用可组合项来映射电子商务的业务领域,如下所示:

const {cart, load, addItem, removeItem, remove, ...} = useCart()

这种方法绝对有用,因为它允许将域包装在一个函数中。在诸如 useProduct 或 之 useCategory 类的更简单的示例中,实现和维护相对简单。然而,正如您在此处的示例中所看到的,useCart 当包装一个包含更多逻辑而不仅仅是数据获取的域时,这个可组合项正在发展成为一种非常难以开发和维护的形状。

此时,我开始为 Nuxt 生态系统做出贡献,其中引入了不同的方法。在这种新方法中,每个可组合项仅负责一件事。因此,useCart 我们的想法不是构建一个巨大的可组合项,而是为每个功能构建可组合项 useAddToCart,例如 useFetchCart,,,useRemovefromCart 等等。

因此,维护和测试这些可组合项应该更容易 🙂

进一步阅读

这将是我的研究的全部内容。如果您想了解有关此主题的更多信息,请务必查看以下文章:

  • https://vuejs.org/guide/reusability/composables.html

  • https://vueschool.io/articles/vuejs-tutorials/what-is-a-vue-js-composable/

  • https://blog.logrocket.com/getting-started-vue-composables/

  • https://macopedia.com/blog/news/how-can-vue-3-composables-make-your-life-easier

Vue 可组合项的良好实践和设计模式 文章来源地址 https://www.toymoban.com/diary/vue/339.html

到此这篇关于 Vue 可组合项的良好实践和设计模式的文章就介绍到这了, 更多相关内容可以在右上角搜索或继续浏览下面的相关文章,希望大家以后多多支持 TOY 模板网!

原文地址:https://www.toymoban.com/diary/vue/339.html

如若转载,请注明出处:如若内容造成侵权 / 违法违规 / 事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于1970-01-01发表,共计3433字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)