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, // 其他返回的状态、方法 } } })
相关产品推荐
相关产品推荐

