You need to enable JavaScript to run this app. Vue3 Composition API 如何为可复用loading composable集中定义prop
优惠活动
大模型
产品
解决方案
定价
更多

Vue3 Composition API 如何为可复用loading composable集中定义prop

实现方案:完全可满足需求,且逻辑比原mixin更清晰

核心前提说明

Vue 3 不支持完全跳过组件定义层、自动给组件注入prop的无配置写法——prop是组件对外暴露的公开接口契约,写在组件定义层面是显式可追溯的,比mixin隐式注入的维护成本低很多。我们要做的是把重复的配置逻辑完全抽离,做到只写一次配置、所有组件复用,同时保持和原mixin完全一致的行为,迁移时不需要修改任何已有父组件的调用代码。

完整可复用的composable实现

新建文件src/composables/useLoading.js,把原mixin的所有逻辑、重复的prop配置全部抽离:

import { ref, computed, watch } from 'vue'

// 公共loading prop配置,所有组件复用同一份定义,无需重复编写
export const loadingProps = {
  loading: {
    type: Boolean,
    default: false
  }
}

// 公共loading相关的事件配置
export const loadingEmits = ['update:loading']

/**
 * 加载状态逻辑复用核心函数
 * @param {object} props 组件自身的props对象
 * @param {Function} emit 组件自身的emit方法
 * @returns 加载状态相关的响应式状态、方法
 */
export function useLoading(props, emit) {
  // 内部维护的加载状态,初始值与外部传入的prop保持同步
  const innerLoading = ref(!!props.loading)

  // 监听外部prop变化,同步到内部状态,与原mixin的watch逻辑对齐
  watch(() => props.loading, (newVal) => {
    innerLoading.value = !!newVal
  })

  const startLoading = () => {
    innerLoading.value = true
    // 触发事件通知父组件更新值,与原mixin的逻辑完全一致
    emit('update:loading', innerLoading.value)
  }

  const stopLoading = () => {
    innerLoading.value = false
    emit('update:loading', innerLoading.value)
  }

  const isLoading = computed(() => !!innerLoading.value)
  const isNotLoading = computed(() => !innerLoading.value)

  return {
    innerLoading,
    startLoading,
    stopLoading,
    isLoading,
    isNotLoading
  }
}

组件中的使用方式

匹配你最初的Options API + setup写法

你之前写的使用示例里引入语法有小错误(useLoading是具名导出,需要用花括号引入),调整后即可正常使用,只需要在props、emits部分展开抽离的公共配置,不需要重复写loading的三行prop定义:

// components/Table.vue
import { defineComponent } from 'vue'
// 注意是具名引入,不是默认引入
import { loadingProps, loadingEmits, useLoading } from 'src/composables/loading'

export default defineComponent({
  props: {
    // 组件自身独有的prop,比如表格的列配置、数据配置
    columns: { type: Array, default: () => [] },
    // 展开公共的loading prop配置,无需重复编写
    ...loadingProps
  },
  emits: [
    // 组件自身独有的事件,比如表格的行点击事件
    'row-click',
    // 展开公共的loading事件配置
    ...loadingEmits
  ],
  setup (props, { emit }) {
    const { startLoading, stopLoading, innerLoading, isLoading, isNotLoading } = useLoading(props, emit)

    // 组件自身的业务逻辑...

    return { 
      startLoading, 
      stopLoading, 
      innerLoading, 
      isLoading, 
      isNotLoading,
      // 其他返回的状态、方法
    }
  }
})

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.30 21:57:03