Vue3 中使用组合式API替换mixins,实现代码复用并解决隐患

我们在vue mixin混入–基础中聊过mixins可以使我们的代码进行复用,非常的灵活方便。
但是在vue3中却不推荐使用了,因为它存在一些问题。

mixins问题

不清晰的数据来源:当使用了多个 mixin 时,实例上的数据属性来自哪个 mixin 变得不清晰,这使追溯实现和理解组件行为变得困难。

命名空间冲突:多个来自不同作者的 mixin 可能会注册相同的属性名,造成命名冲突

隐式的跨 mixin 交流:多个 mixin 需要依赖共享的属性名来进行相互作用,这使得它们隐性地耦合在一起。

当然这些问题对于的程序员来说都是可以避免的,但最好的方法是换一种更好的方式。

vue3组合式API

组合式 API (Composition API) 是一系列 API 的集合,使我们可以使用函数而不是声明选项的方式书写 Vue 组件。它是一个概括性的术语,涵盖了以下方面的 API:

  • 响应式 API:例如 ref()reactive(),使我们可以直接创建响应式状态、计算属性和侦听器。
  • 生命周期钩子:例如 onMounted()onUnmounted(),使我们可以在组件各个生命周期阶段添加逻辑。
  • 依赖注入:例如 provide()inject(),使我们可以在使用响应式 API 时,利用 Vue 的依赖注入系统

这段话完全来自官网 更多的内容还是需要看官网

案例

抽离后台管理列表共用的逻辑,示例只是列表相关逻辑封装,你甚至可以将增删改查的逻辑封装进去。

table.ts文件(公共内容)

// table.ts  该文件主要封装了 列表请求数据--可抽离的交互逻辑

import { ref,reactive } from 'vue'
// 对于参数的特殊处理,例如 数据为空的key 就不传了。 下面有sortParams具体代码
import { sortParams } from '@/utils/handleData'

/**
 * @description usePage 接收一个 opts 参数,返回列表所需数据
 * @param {Object} opts.screenData - 默认查询参数
 * @param {Array} opts.dateArr - 时间查询参数
 * @param {Function} opts.getListApi  - 获取列表数据的接口
 * @param {Function} opts.customQueryParameters  - 自定义查询参数
 * @param {Function} opts.getListFunc  - 执行完 getListFunc 成功后执行的逻辑有一个opts参数
 * @param {Function} opts.searchFunc  - 执行完 search 后执行的逻辑
 * @param {Function} opts.getPerPageFunc  - 执行完 getPerPage 后执行的逻辑
 * @param {Function} opts.getCurrentPageFunc  - 执行完 getCurrentPage 后执行的逻辑
 */

export default function (opts?: any) {

  const {
    screenData = {},
    dateArr = [],
    getListApi,
    customQueryParameters = () => {},
    getListFunc = (opts: any) => {},
    searchFunc = () => {},
    getPerPageFunc = () => {},
    getCurrentPageFunc = () => {}

  } = opts




  const page = reactive({
    // 每页多少数据
    perPage: 10,
    // 当前页
    currentPage: 1,
    // 总条数
    total: 0
  })

  const load = ref(false)


  // 表格数据
  const tableData:any = ref([])


  // 获取当前页码
  const getCurrentPage = (num?:any) => {
    page.currentPage = num
    getPerPageFunc()
    getTableData()
  }

  // 改变每页展示数据的条数
  const getPerPage = (num?:any) => {
    page.perPage = num
    page.currentPage = 1
    getCurrentPageFunc()
    getTableData()
  }


  // 筛选
  const search = () => {
    searchFunc()
    getCurrentPage(1)
  }

  // 处理后的请求参数
  const paramsFn = () => sortParams({
    ...screenData,
    page: page.currentPage,
    perPage: page.perPage,
    // ...customQueryParameters()
  }, [...dateArr])


  // 列表请求
  const getTableData = () => {
    load.value = true
    const params = paramsFn()


    getListApi(params).then((res:any) => {
      tableData.value = res.data.list
      page.total = res.data.page.total
      load.value = false

      getListFunc(params)
    }, () => {
      load.value = false
    })
  }


  return{
    load,
    page,
    tableData,
    getCurrentPage,
    getPerPage,
    search,
    paramsFn
  }
}

组件内使用

<template>
  <div class="wrap">
    <el-table
	    :data="tableData"
	    style="width: 100%"
	    border
	    min-width="100"
	  >
	  
	     <el-table-column  prop="name" label="姓名" />
	     <el-table-column  prop="phone" label="手机号" />
   </el-table>
   <el-pagination
      background
      :layout="layout"
      :page-sizes="[10, 20, 50, 100, 150, 200]"
      :page-size="page.perPage"
      :total="page.total"
      :pager-count="page.currentPage"
      @size-change="getPerPage"
      @current-change="getCurrentPage"
    >
    </el-pagination>

  </div>
</template>

<script setup lang="ts">

import { reactive, onMounted, ref } from 'vue'
// vite.config 中 resolve 配置了 $mixins 路径 
import mixTable from '$mixins/table'

import { dealerSettlementData } from '$api/query'

const screenData = reactive({
  dealerName: '',
  purchase: ''
})

const {
  page,
  tableData,
  getCurrentPage,
  getPerPage,
  search
} = mixTable({
  getListApi: dealerSettlementData,
  screenData
})

onMounted(() => {
  search()
})

</script>

回调方法的使用

如果请求接口后,我们需要一些特殊操作怎么办?

相信大家仔细看table,就能发现我们在初始化、页码、页数、接口等方法里,都执行了回调方法

// 接口请求后
const {
  page,
  tableData,
  getCurrentPage,
  getPerPage,
  search
} = mixTable({
  getListApi: dealerSettlementData
  screenData,
  searchFunc () {
    console.log('初始化执行后')
  },
  getPerPageFunc () {
    console.log('调整当前第几页后')
  },
  getCurrentPageFunc () {
    console.log('调整可返回多少数据后')
  },
  getListFunc () {
    console.log('接口执行成功后')
  }
})

sortParams逻辑

 export function sortParams (obj:object,arr:Array<string> = []) {

  const newObj = obj
  for (const item in newObj) {
    if (newObj[item] === null || newObj[item] === '' || newObj[item] === undefined || (Array.isArray(newObj[item]) && newObj[item].length == 0) || (newObj[item] instanceof Object && JSON.stringify(newObj[item]) == '{}')) {
      delete newObj[item]
    }
  }

  if(arr.length){
    for (const item in newObj) {
      arr.map(m =>{
        if( m == item){
          newObj[`${item}StartTime`] = newObj[item][0]
          newObj[`${item}EndTime`] = newObj[item][1]
          delete newObj[item]
        }
      })
    }
  }

  return newObj
}

你可能感兴趣的:(mixins,组合式API,vue3)