Vue3 如何让代码变得清新优雅,代码洁癖患者进!(4)
列表页面 来啦!
温馨提示:
在 列表页面中,使用 若依的分页组件: Pagination,图片预览组件:ImagePreview,标签组件 DictTag ,还有公共方法 parseTime 等等 对若依 respect !
搜索 或 翻页时 通过 router.push 跳转路由,使用 onBeforeRouteUpdate 监听路由变化,然后获取页面数据 getList
注意,搜索条件里没有 pageNum 和 pageSize,把她放在列表页面更好。
只是举个栗子,大家别当真 list.vue:
<template>
<div class="app-container" v-hasPermi="actions['search'].permission">
<!-- 需求管理 -->
<!-- 搜索 -->
<Search ref="searchRef" @search="search" :showSearch="showSearch" :dicts="dicts"/>
<!-- 批量操作 -->
<BatchOperation
:actions="actions"
@create="handleCreate"
>
<template #rightToolbar>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</template>
</BatchOperation>
<el-table :data="list" row-key="demandId" @expand-change="expandChange" :expand-row-keys="expandRowKeys" scrollbar-always-on>
<el-table-column type="expand" fixed="left">
<template #default="{row}">
<el-descriptions class="margin-top" :column="2" border>
<el-descriptions-item label="封面图" :span="2" width="150px" label-align="right">
<ImagePreview :src="row.urlOss.map(z=>z.url).join(',')||defaultThumb" v-if="Array.isArray(row.urlOss)" height="100px"/>
</el-descriptions-item>
<el-descriptions-item label="需求说明" :span="2" width="150px" label-align="right">
<div v-html="row.content" class="ql-snow ql-editor"></div>
</el-descriptions-item>
<el-descriptions-item label="备注" :span="2" width="150px" label-align="right">
{{row.remark}}
</el-descriptions-item>
</el-descriptions>
</template>
</el-table-column>
<el-table-column label="需求名称" header-align="center" prop="name" width="260" fixed="left" ></el-table-column>
<el-table-column label="审核状态" prop="checkStatus" width="150" align="center">
<template #default="{row}">
<div style="display:flex;justify-content: center;">
<dict-tag :options="dicts.sys_checkStatus" :value="row.checkStatus" />
<span v-if="row.checkStatus == 2">
<el-divider direction="vertical"></el-divider>
<el-popover
placement="top"
width="200"
trigger="hover"
:content="row.checkMessage">
<template #reference>
<el-button link type="danger">原因</el-button>
</template>
</el-popover>
</span>
</div>
</template>
</el-table-column>
<el-table-column label="是否上架" prop="status" width="150" align="center">
<template #default="{row}">
<dict-tag :options="dicts.demand_status" :value="row.status" />
</template>
</el-table-column>
<el-table-column label="需求预算" prop="budget" width="150" align="center" >
<template #default="{row}">
<span>{{ moneyFormat(row.budget) }}</span>
</template>
</el-table-column>
<el-table-column label="需求类型" prop="category" width="150" align="center">
<template #default="{row}">
<dict-tag :options="dicts.demand_category" :value="row.status" />
</template>
</el-table-column>
<el-table-column label="交易数量" width="150" align="center">
<template #default="{row}">
<span>{{row.total || '--'}}</span>
</template>
</el-table-column>
<el-table-column label="截止时间" header-align="center" prop="deadline" width="120" show-overflow-tooltip>
<template #default="{row}">
<span>{{ row.deadline ? parseTime(row.deadline,'{y}-{m}-{d}') : '长期有效' }}</span>
</template>
</el-table-column>
<el-table-column label="联系人" header-align="center" prop="userName" width="180" show-overflow-tooltip>
<template #default="{row}">
<span>{{ row.customerName}}</span>
<br/>
<span>{{row.userName }}</span>
<el-divider direction="vertical"></el-divider>
<span>{{row.tel}}</span>
</template>
</el-table-column>
<el-table-column label="发布时间" align="center" prop="releaseTime" sortable="custom" :sort-orders="['descending', 'ascending']" width="180">
<template #default="{row}">
<span>{{ parseTime(row.releaseTime,'{y}年{m}月{d}日')}} </span>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" show-overflow-tooltip prop="createTime" width="180"></el-table-column>
<el-table-column label="操作" fixed="right" header-align="center" width="150px">
<template #default="{row}">
<BatchOperation
:inColumn="true"
:actions="initAction(false, false, row)"
@check="handleCheck(row)"
@edit="handleEdit(row)"
@delete="handleDelete(row.demandId)"
></BatchOperation>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination :hidden="total<=pager.pageSize" :total="total" v-model:page="pager.pageNum" v-model:limit="pager.pageSize" @pagination="pagination"></Pagination>
<!-- 审核 -->
<div v-hasPermi="actions['check'].permission"><Check ref="checkRef" @refresh="getList" /></div>
</div>
</template>
<script setup name="DemandIndex">
import { getPages, remove } from '@/api/demand'
import defaultThumb from '@/assets/images/diagrams/demand-default-thumb.jpg'
import Check from './components/check.vue'
import Search from './components/search.vue'
import initAction from './components/actions'
const { proxy } = getCurrentInstance()
// 字典
const dicts = ref({})
// 使用路由
const router = useRouter()
const route = useRoute()
// 列表相关
const list = ref([]) // 列表数据
const pager = ref({ // 列表数据页码
pageNum: Number(route.query.pageNum) || 1,
pageSize: Number(route.query.pageSize) || 20
})
const total = ref(0) // 列表总条数
// 默认展开行 keys
const expandRowKeys = ref([])
// 搜索相关
const searchRef = ref(null) // ref
const showSearch = ref(true)// 是否显示搜索
// 勾选
const multipleSelection = ref([])
// 非单个禁用
const single = computed(() => multipleSelection.value.length != 1)
// 非多个禁用
const multiple = computed(() => !multipleSelection.value.length)
// 当前选中
const selectedRow = computed(()=>{
if(multipleSelection.value.length == 1){
return list.value.find(z => z.demandId == multipleSelection.value[0])
}
return null
})
// 批量操作按钮
const actions = computed(()=>initAction(single.value, multiple.value, selectedRow.value))
// 审核 ref
const checkRef = ref(null)
// 点击 发布需求
const handleCreate =()=>{
router.push('/demand/create')
}
// 点击 审核
const handleCheck =(row)=>{
const current = row || selectedRow.value
checkRef.value.init(current)
}
// 点击 编辑
const handleEdit =(row)=>{
const current = row || selectedRow.value
router.push('/demand/edit/' + current.demandId)
}
// 展开详情
const expandChange = async (row,expandedRows)=>{
const index = expandedRows.findIndex(z=>z.demandId== row.demandId)
if(index == -1) return
row.urlOss = await proxy.getFileList(row.urlOss)
expandRowKeys.value = expandedRows.map(z=>z.demandId)
}
// 获取列表数据
const getList = () => {
proxy.$modal.loading("加载中...")
const { dateRange, ...search } = searchRef.value.form
const query = { ...pager.value, ...search }
const data = dateRange ? proxy.addDateRange(query, dateRange) : query
getPages(data).then(response => {
list.value = response.data.rows;
total.value = parseInt(response.data.total);
expandRowKeys.value = []
}).finally(() => {
proxy.$modal.closeLoading();
});
}
// 搜索
const search = () => {
pager.value.pageNum = 1
pagination()
}
// 翻页页面
const pagination = () => {
const { params, ...routeQuery } = searchRef.value.form
router.push({
path: route.path,
query: {
...pager.value,
...routeQuery
}
}).then((res1)=>{
// 路由及参数重复
if(res1 && res1.to.fullPath === res1.from.fullPath){
getList()
}
})
}
// 勾选
const handleSelectionChange = (val) => {
multipleSelection.value = val.map(z => z.demandId)
}
// 批量删除
const handleDelete = (id) => {
proxy.$modal.confirm('确定删除?')
.then(() => {
const ids = id || multipleSelection.value
remove(ids).then(res => {
if (res.code == 200) {
proxy.$modal.msgSuccess("操作成功")
getList()
} else {
proxy.$modal.msgError(res.msg || "请求发生错误,请稍后重试")
}
})
})
.catch(() => {
proxy.$modal.msg("已取消")
})
}
// 监听路由变化
onBeforeRouteUpdate((to, from, next) => {
const newVal = to.query
searchRef.value.setQueryData(newVal)
pager.value.pageNum = Number(newVal.pageNum) || 1
pager.value.pageSize = Number(newVal.pageSize) || 20
// 获取列表
getList()
next()
})
onMounted(()=>{
dicts.value = proxy.useDict('sys_checkStatus', 'demand_status','demand_category')
getList()
})
</script>
<style scoped lang="scss">
.input-with-select{
width: 480px;
::v-deep .el-select .el-input {
width: 150px;
}
}
</style>
作者:胡倩倩0903
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
posted on 2023-06-05 10:45 kitty20180903suzhou 阅读(211) 评论(0) 编辑 收藏 举报