返回

Vue3 Composables:让逻辑复用更顺手

前端

Vue3 Composables:实现逻辑复用的利器

在现代 Web 开发中,逻辑复用是一项至关重要的技术,可提升代码可维护性和开发效率。Vue2 中的 mixins 和高阶组件虽然能够实现逻辑复用,但它们存在一定的局限性。Vue3 引入了 Composables 特性,为我们提供了更强大、更灵活的逻辑复用解决方案。

什么是 Composables

Composables 是一种可重用的函数,可以包含任何类型的逻辑,例如数据获取、状态管理、事件处理等等。与 mixins 和高阶组件不同,Composables 不受组件层级的限制,可以跨组件共享和复用。

Composables 的优势

  • 可重用性: Composables 可以被多个组件复用,从而避免重复编写代码。
  • 解耦性: Composables 将逻辑与组件视图分离,提高了代码可维护性和灵活性。
  • 可组合性: Composables 可以相互组合,创建更复杂的逻辑。
  • 独立性: Composables 与组件无关,可以在任何地方使用。

Composables 的应用场景

Composables 可应用于各种场景,包括:

  • 列表查询: 抽象出通用的列表查询逻辑,方便在不同组件中复用。
  • 增删改查(CRUD)操作: 封装通用的 CRUD 操作逻辑,提高代码可维护性。
  • 状态管理: 使用 Composables 来管理共享状态,取代 Vuex 等第三方状态管理库。
  • 事件处理: 创建可复用的事件处理函数,提高代码的可读性和可维护性。

列表查询逻辑复用

假设我们有一个用户管理页面,需要展示所有用户列表。我们可以使用 Composables 将列表查询逻辑抽象成如下函数:

import { ref } from 'vue'

export default function useListQuery(url) {
  const loading = ref(false)
  const data = ref([])

  const fetchList = async () => {
    loading.value = true
    try {
      const res = await fetch(url)
      data.value = await res.json()
    } catch (error) {
      console.error(error)
    } finally {
      loading.value = false
    }
  }

  return {
    loading,
    data,
    fetchList,
  }
}

然后,我们可以在用户管理页面中复用此 Composables:

<template>
  <div>
    <button @click="fetchList">查询用户</button>
    <ul>
      <li v-for="user in data" :key="user.id">{{ user.name }}</li>
    </ul>
  </div>
</template>

<script>
import { defineComponent } from 'vue'
import useListQuery from './ListQuery.js'

export default defineComponent({
  setup() {
    const { loading, data, fetchList } = useListQuery('/api/users')

    return {
      loading,
      data,
      fetchList,
    }
  },
})
</script>

增删改查(CRUD)逻辑复用

同样,我们可以创建一个通用的 CRUD 操作 Composables:

import { ref } from 'vue'

export default function useCrud(url) {
  const loading = ref(false)
  const data = ref([])

  const create = async (data) => {
    loading.value = true
    try {
      const res = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(data),
      })
      data.value = await res.json()
    } catch (error) {
      console.error(error)
    } finally {
      loading.value = false
    }
  }

  const update = async (id, data) => {
    loading.value = true
    try {
      const res = await fetch(`${url}/${id}`, {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(data),
      })
      data.value = await res.json()
    } catch (error) {
      console.error(error)
    } finally {
      loading.value = false
    }
  }

  const remove = async (id) => {
    loading.value = true
    try {
      await fetch(`${url}/${id}`, {
        method: 'DELETE',
      })
    } catch (error) {
      console.error(error)
    } finally {
      loading.value = false
    }
  }

  return {
    loading,
    data,
    create,
    update,
    remove,
  }
}

此 Composables 可以复用在用户管理页面中:

<template>
  <div>
    <form @submit.prevent="createUser">
      <input v-model="newUser.name" placeholder="姓名" />
      <input v-model="newUser.age" placeholder="年龄" />
      <button type="submit">添加用户</button>
    </form>

    <ul>
      <li v-for="user in data" :key="user.id">
        {{ user.name }} - {{ user.age }}
        <button @click="updateUser(user.id)">修改</button>
        <button @click="removeUser(user.id)">删除</button>
      </li>
    </ul>
  </div>
</template>

<script>
import { defineComponent } from 'vue'
import useCrud from './Crud.js'

export default defineComponent({
  setup() {
    const { loading, data, create, update, remove } = useCrud('/api/users')
    const newUser = ref({ name: '', age: '' })

    const createUser = async () => {
      await create(newUser.value)
      newUser.value = { name: '', age: '' }
    }

    const updateUser = async (id) => {
      const user = data.value.find(user => user.id === id)
      await update(id, user)
    }

    const removeUser = async (id) => {
      await remove(id)
    }

    return {
      loading,
      data,
      newUser,
      createUser,
      updateUser,
      removeUser,
    }
  },
})
</script>

结语

Vue3 Composables 为前端开发人员提供了强大的逻辑复用机制。它们提高了代码的可维护性和可重用性,降低了开发复杂性。通过理解 Composables 的优势和应用场景,我们可以充分利用这一特性,提升 Web 应用的质量。

常见问题解答

  1. Composables 和 mixins 有什么区别?
    Composables 不受组件层级的限制,可以跨组件共享和复用,而 mixins 只作用于特定的组件层级。

  2. Composables 和高阶组件有什么区别?
    Composables 是函数,而高阶组件是组件。Composables 可以创建和返回组件,而高阶组件只能增强现有的组件。

  3. 什么时候应该使用 Composables?
    当我们需要复用跨组件的逻辑时,应该使用 Composables。

  4. Composables 是否比 mixins 或高阶组件更好?
    Composables 提供了更灵活和强大的逻辑复用机制,通常是首选。

  5. 如何学习 Composables?
    可以通过 Vue 官方文档、教程和社区资源学习 Composables。