我们在vue mixin混入–基础中聊过mixins可以使我们的代码进行复用,非常的灵活方便。
但是在vue3中却不推荐使用了,因为它存在一些问题。
不清晰的数据来源:当使用了多个 mixin 时,实例上的数据属性来自哪个 mixin 变得不清晰,这使追溯实现和理解组件行为变得困难。
命名空间冲突:多个来自不同作者的 mixin 可能会注册相同的属性名,造成命名冲突。
隐式的跨 mixin 交流:多个 mixin 需要依赖共享的属性名来进行相互作用,这使得它们隐性地耦合在一起。
当然这些问题对于的程序员来说都是可以避免的,但最好的方法是换一种更好的方式。
组合式 API (Composition API) 是一系列 API 的集合,使我们可以使用函数而不是声明选项的方式书写 Vue 组件。它是一个概括性的术语,涵盖了以下方面的 API:
这段话完全来自官网 更多的内容还是需要看官网
抽离后台管理列表共用的逻辑,示例只是列表相关逻辑封装,你甚至可以将增删改查的逻辑封装进去。
// 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('接口执行成功后')
}
})
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
}