Vue2 Mixins与Vue3 Composables对比:迁移传参优化问询
Vue3 Composables 优化方案:减少参数传递,复用状态逻辑
1. 让Composables内部管理状态,暴露操作方法
不用在组件里维护状态再传给Composables,而是让Composable自己创建并管理状态,组件通过调用Composable返回的方法更新状态,直接使用返回的计算结果或状态。
示例:
// transformer.js import { ref, computed } from 'vue' export function useTransformer() { // Composable 内部维护状态 const listServiceGroup = ref({}) // 基于内部状态的转换逻辑 const transformedResult = computed(() => { // 这里写原transformData的转换逻辑,直接用listServiceGroup.value return Object.values(listServiceGroup.value).map(item => ({ ...item, processed: true })) }) // 提供更新状态的方法给组件调用 function updateList(data) { listServiceGroup.value = data } return { listServiceGroup, transformedResult, updateList } }
组件中使用:
// Home.vue import { useTransformer } from './transformer' const { listServiceGroup, transformedResult, updateList } = useTransformer() // 当需要更新数据时,直接调用方法 updateList({ group1: [{ id: 1, name: 'test' }] })
2. 用Provide/Inject共享跨层级状态
如果多个组件、Composables都依赖同一份状态,可在父组件(或根组件)通过provide提供状态,然后在需要的Composables里用inject获取,避免层层传递参数。
示例:
// App.vue 或 Home.vue(上层组件) import { provide, ref } from 'vue' // 提供需要共享的状态 const listServiceGroup = ref({}) provide('listServiceGroup', listServiceGroup)
Composable中注入使用:
// transformer.js import { inject, computed } from 'vue' export function useTransformer() { // 注入共享状态 const listServiceGroup = inject('listServiceGroup') const transformedResult = computed(() => { return /* 基于注入状态的转换逻辑 */ }) return { transformedResult } }
组件中使用:
// Home.vue import { useTransformer } from './transformer' // 无需传参,直接获取结果 const { transformedResult } = useTransformer()
3. 组合式函数链式调用,内部传递状态
如果多个Composables之间存在依赖关系,让上层Composable调用下层Composable并传递状态,组件只需要调用最上层的组合函数,不用关心内部的参数传递。
示例:
// useDataFetcher.js:负责获取数据的Composable export function useDataFetcher() { const listServiceGroup = ref({}) async function fetchData() { const res = await fetch('/api/service-groups') listServiceGroup.value = await res.json() } return { listServiceGroup, fetchData } }
// transformer.js:负责转换数据的Composable import { computed } from 'vue' export function useTransformer(listServiceGroup) { const transformedResult = computed(() => { return /* 转换逻辑 */ }) return { transformedResult } }
组合后的上层Composable:
// useHomeLogic.js:整合数据获取和转换 import { useDataFetcher } from './useDataFetcher' import { useTransformer } from './transformer' export function useHomeLogic() { const { listServiceGroup, fetchData } = useDataFetcher() const { transformedResult } = useTransformer(listServiceGroup) return { listServiceGroup, transformedResult, fetchData } }
组件中使用:
// Home.vue import { useHomeLogic } from './useHomeLogic' const { listServiceGroup, transformedResult, fetchData } = useHomeLogic() // 初始化调用数据获取 fetchData()
4. 封装相关状态与逻辑到同一Composable
把组件中关联的状态、计算逻辑、操作方法都封装到一个Composable里,组件只需要调用这个Composable获取需要的内容,彻底避免参数传递。
示例:
// useHomeData.js import { ref, reactive, computed } from 'vue' export function useHomeData() { // 组件需要的所有关联状态 const listServiceGroup = ref({}) const filterOptions = ref({ type: 'all' }) const pagination = reactive({ page: 1, size: 10 }) // 依赖多个状态的转换/计算逻辑 const filteredAndTransformedResult = computed(() => { let data = Object.values(listServiceGroup.value) // 应用过滤 if (filterOptions.value.type !== 'all') { data = data.filter(item => item.type === filterOptions.value.type) } // 应用分页 const start = (pagination.page - 1) * pagination.size return data.slice(start, start + pagination.size).map(item => ({ ...item, processed: true })) }) // 操作方法 async function fetchData() { const res = await fetch(`/api/service-groups?page=${pagination.page}&size=${pagination.size}`) listServiceGroup.value = await res.json() } function updateFilter(type) { filterOptions.value.type = type pagination.page = 1 // 过滤后重置页码 } return { listServiceGroup, filteredAndTransformedResult, fetchData, updateFilter, pagination } }
组件中使用:
// Home.vue import { useHomeData } from './useHomeData' const { filteredAndTransformedResult, fetchData, updateFilter, pagination } = useHomeData() // 初始化调用 fetchData()
内容的提问来源于stack exchange,提问作者Nguyen Duc Kien
相关产品推荐
相关产品推荐

