vue中,el-table树形数据与懒加载【实例】(一)——重置resetFields& lazy属性、hasChildren子项& el-select封装下拉组件& 获取当前登录人-reduce用法
1、主页面
src\app\plan\views\organization\manageFormulates.vue
<template>
<div>
<el-form
ref="formRef"
class="inline-form"
:inline="true"
label-width="60"
:model="formInline"
>
<el-form-item label="名称:" prop="name">
<el-input
v-model="formInline.name"
maxlength="100"
@input="(e) => (formInline.name = replaceCommonText(e))"
/>
</el-form-item>
<el-form-item class="search_btn">
<el-button v-throttle="3000" type="primary" @click="onSubmit">
查询
</el-button>
<el-button
v-throttle="3000"
plain
type="primary"
@click="resetForm(formRef)"
>
重置
</el-button>
</el-form-item>
</el-form>
<el-divider border-style="dashed" />
<el-row v-if="orgLevel == '01'" class="action-btn">
<el-col>
<el-button
v-if="handelLimit('tp_btn_4101')"
type="primary"
@click="addDetail('add', { type: 0 }, 1)"
>
添加规划
</el-button>
<el-button
v-if="handelLimit('tp_btn_4102')"
type="primary"
@click="batchDelete"
>
批量删除
</el-button>
<el-button
v-if="handelLimit('tp_btn_4104')"
type="primary"
@click="() => (isShowPlanImport = true)"
>
导入
</el-button>
<customPlanImport
:show-dialog="isShowPlanImport"
:source="'approval'"
@close-dialog="handleCloseExport"
@submit-dialog="handleSubmitTopic"
/>
<el-button
v-if="false"
class="down-btn"
type="primary"
@click="fileDownload"
>
下载模板
</el-button>
<el-upload
ref="uploadRef"
:http-request="handlePlanUpload"
:limit="1"
multiple
:on-success="uploadSuccess"
:show-file-list="false"
>
<el-button v-if="false" class="up-btn" type="primary">导入</el-button>
</el-upload>
</el-col>
</el-row>
<!-- @expand-change="handleExpand" -->
<!-- @row-click="handleExpand" -->
<el-table
ref="crudRef"
border
class="table-style"
:data="tableData"
lazy
:load="treeLoad"
row-key="id"
stripe
style="width: 100%; margin-bottom: 20px"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
@selection-change="handleChange"
>
<el-table-column type="selection" />
<el-table-column label="名称" prop="name" />
<el-table-column label="类型" prop="typeName" width="180" />
<el-table-column v-if="false" label="排序" prop="sorts" width="180" />
<el-table-column
v-if="orgLevel == '01'"
label="操作"
prop="data"
width="260"
>
<template #default="scope">
<el-button
link
size="small"
type="primary"
@click="addDetail('edit', scope.row, 3)"
>
编辑
</el-button>
<el-button
v-if="scope.row.typeName !== '任务' && handelLimit('tp_btn_4101')"
link
size="small"
type="primary"
@click="addDetail('add', scope.row, 2)"
>
新增子项
</el-button>
<el-button
link
size="small"
type="danger"
@click="handleClickDelete(scope.row)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog v-model="dialogVisible" :title="titleShow" width="30%">
<div style="display: flex">
<el-form
class="inline-form"
:inline="true"
label-width="130px"
:model="formPlan"
>
<el-form-item label="类型:" prop="typeName">
<el-select v-model="formPlan.typeName" disabled />
</el-form-item>
<el-form-item label="名称:" prop="name">
<el-input
v-model="formPlan.name"
maxlength="100"
@input="(e) => (formPlan.name = replaceCommonText(e))"
/>
</el-form-item>
<el-form-item
v-if="formPlan.typeName == '规划'"
label="年份区间:"
prop="year"
>
<dictSelect v-model="formPlan.year" :dictid="'planYear'" />
</el-form-item>
</el-form>
</div>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="okSelect()">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup>
import {
// getFileDownload,
uploadPlanFileApi,
// fileDownloadData,
// getPrjSelect,
getPrjData,
addPrjPlan,
updatePrjPlan,
removePrjPlan,
} from '@/api/organization/project'
import dictSelect from '@src/components/dictSelect'
import { handelLimit } from '@src/utils/limits'
import customPlanImport from '@src/components/customPlanImport'
import { downFile } from '@src/utils/util'
import { getOrgLevel } from '@src/utils/getOrgLevel'
import { replaceCommonText } from '@src/utils/validate'
const orgLevel = getOrgLevel()
const formRef = ref()
const crudRef = ref()
const uploadRef = ref()
const mark = ref(0)
const maps = new Map()
const dialogVisible = ref(false)
const isShowPlanImport = ref(false)
const titleShow = ref('')
const rowVal = ref({})
const rowParam = ref({})
const formInline = reactive({
name: '',
})
const formPlan = reactive({
type: 0,
name: '',
typeName: '规划',
year: '',
})
const tableData = ref([])
const handleCloseExport = () => {
isShowPlanImport.value = false
}
const handleSubmitTopic = (params) => {
isShowPlanImport.value = false
if (!params) {
tableData.value = []
getqueryByPage()
// window.location
}
}
// 列表数据
const getqueryByPage = async () => {
const params = {
name: formInline.name,
id: '',
type: 0,
current: 1,
size: 99999,
}
await getPrjData(params).then((res) => {
if (res.code === '00000') {
const result = res.data.data.map((item, index) => {
return {
index: index,
...item,
}
})
tableData.value = result
}
})
}
//重置
const resetForm = (formEl) => {
if (!formEl) return
formEl.resetFields()
getqueryByPage()
}
//查询
const onSubmit = () => {
tableData.value = []
getqueryByPage()
}
// 下载模板
const fileDownload = async () => {
// await fileDownloadData().then((res) => {
// downLoadxls(res)
// getqueryByPage()
// })
downFile('Plan-Import.xlsx')
}
getqueryByPage()
// 批量删除
const ids = ref([])
const handleChange = (val) => {
ids.value = val.map((item) => item.id)
}
// 规划计划上传
const handlePlanUpload = (options) => {
const param = new FormData()
param.append('file', options.file)
uploadPlanFileApi(param).then((res) => {
const { code } = res
if (code === '00000') {
ElMessage({
type: 'success',
message: '上传成功',
})
getqueryByPage()
} else {
ElMessage({ type: 'error', message: res.message })
}
})
}
const uploadSuccess = (response) => {
const { code } = response
if (code === '00000') {
uploadRef.value.clearFiles()
ElMessage({
type: 'success',
message: response.message,
})
}
}
// 批量删除
const batchDelete = async () => {
if (ids.value.length === 0) {
ElMessage.error(`请至少勾选一条`)
} else {
deletePlan(ids.value)
}
}
// 懒加载
const treeLoad = (tree, treeNode, resolve) => {
setTimeout(() => {
const params = {
name: '',
id: tree.id,
type: tree.type + 1,
}
const dataList = ref([])
maps.set(tree.id, { tree, treeNode, resolve })
getPrjData(params).then((res) => {
const data = res.data.data || []
data.forEach((el) => {
if (el.hasChildren) {
el.children = []
}
})
dataList.value = data
resolve(dataList.value)
})
}, 200)
}
// 在删除或者添加操作成功之后,调用此函数
const updateTable = () => {
maps.forEach((item, key) => {
const { tree, treeNode, resolve } = maps.get(key)
treeLoad(tree, treeNode, resolve)
})
}
// 删除当前行
const handleClickDelete = (row) => {
deletePlan([row.id])
}
// 删除
const deletePlan = (ids) => {
ElMessageBox.confirm('是否确认删除?若包含子项,将会同步删除子项').then(
() => {
removePrjPlan(ids).then(() => {
tableData.value = []
updateTable()
getqueryByPage()
})
}
)
}
const addDetail = (type, row, num) => {
dialogVisible.value = true
// if (row.sort == '0') {
// rowParam.value = {
// planId: row.id,
// sort: row.sort,
// }
// }
// if (row.sort == '1') {
// rowParam.value = {
// planId: row.planId,
// sort: row.sort,
// parentId: row.id,
// }
// }
// if (row.sort == '2') {
// rowParam.value = {
// fieldId: row.parentId,
// sort: row.sort,
// childFieldId: row.id,
// childFieldName: row.name,
// }
// }
if (type == 'add') {
formPlan.name = ''
formPlan.year = ''
if (num == 2) {
if (row.type == 0) {
formPlan.typeName = '规划领域'
formPlan.type = 1
titleShow.value = '添加规划领域'
}
if (row.type == 1) {
formPlan.typeName = '规划子领域'
formPlan.type = 2
titleShow.value = '添加规划子领域'
}
if (row.type == 2) {
formPlan.typeName = '规划研究任务'
formPlan.type = 3
titleShow.value = '添加规划研究任务'
}
rowParam.value = { id: row.id }
} else {
formPlan.type = 0
formPlan.typeName = '规划'
titleShow.value = '添加规划'
}
}
if (type == 'edit') {
rowVal.value = row
formPlan.typeName = row.typeName
formPlan.name = row.name
if (row.type == 0) {
formPlan.year = row.year
}
titleShow.value = '编辑' + row.typeName
}
mark.value = titleShow.value.indexOf('添加')
}
// 添加规划
const okSelect = () => {
if (mark.value == 0) {
console.log(333, titleShow.value)
const params =
titleShow.value === '添加规划'
? { ...formPlan }
: {
...formPlan,
...rowParam.value,
}
if (titleShow.value === '添加规划') {
if (!params.year) {
ElMessage.error(`请填写完整信息`)
return
}
}
if (!params.name) {
ElMessage.error(`请填写完整信息`)
return
}
console.log(params, rowParam.value)
addPrjPlan(params).then((res) => {
const { code } = res
if (code === '00000') {
ElMessage.success('添加成功')
dialogVisible.value = false
updateTable()
getqueryByPage()
}
})
} else {
rowVal.value.type = formPlan.type
rowVal.value.name = formPlan.name
rowVal.value.year = formPlan.year
const data = rowVal.value
updatePrjPlan(data).then((res) => {
const { code } = res
if (code === '00000') {
dialogVisible.value = false
updateTable()
getqueryByPage()
}
})
}
}
</script>
<style lang="scss" scoped>
.main-content {
.action-btn {
position: relative;
right: 0px;
float: right;
.up-btn {
position: absolute;
top: 2px;
left: 300px;
}
}
}
.dialog-table {
display: block;
margin: 20px 0;
overflow: hidden;
}
.dialog-button {
margin-top: 20px;
}
:deep() {
.ym-input__wrapper {
width: 124%;
}
}
</style>
2、封装的el-select下拉组件
src\components\dictSelect.vue
<template>
<el-select
v-model="dictValue"
class="m-2"
placeholder="请选择"
@change="selectDictEvent"
@click="clickSelectDict"
>
<el-option
v-for="item in dictData"
:key="item.codeClsVal"
:label="item.codeClsValName"
:value="item.codeClsVal"
/>
</el-select>
</template>
<script setup>
// import { queryId } from '@/api/project/couny'
import { queryDict } from '@src/api/common/base'
import { watch } from 'vue'
const props = defineProps({
modelValue: {
default: null,
type: String,
},
dictid: {
default: null,
type: String,
},
})
const emit = defineEmits(['update:modelValue', 'dict-callback', 'dict-lable'])
const dictData = ref()
const { modelValue } = toRefs(props)
const queryDictList = () => {
queryDict({ codeClsTypes: [props.dictid] }).then((res) => {
dictData.value = res.data[props.dictid]
})
}
const clickSelectDict = () => {
if (!dictData.value) {
queryDictList()
}
}
watch(
() => props.modelValue,
() => {
// val
if (!dictData.value) {
queryDictList()
}
}
)
const dictValue = toRef(props, 'modelValue')
const selectDictEvent = (val) => {
emit('update:modelValue', val)
emit('dict-callback', dictData.value)
emit('dict-lable', val)
}
onMounted(() => {
nextTick(() => {
if (modelValue.value) {
queryDictList()
} else {
return
}
})
})
</script>
3、获取当前登录人-reduce用法
src\utils\limits.js
// 使用说明
// v-if="handelLimit('opt0003')"
// import {handelLimit}from "@src/utils/limits"
const menuInfos = sessionStorage.getItem('menuInfo')
const getFlatArr = (arr) => {
return arr.reduce((val, item) => {
let flatArr = [...val, item]
if (item.children && item.children.length !== 0) {
flatArr = [...flatArr, ...getFlatArr(item.children)]
}
return flatArr
}, [])
}
// 控制页面按钮
export const handelLimit = (btnId) => {
if (process.env.VUE_APP_ENV === 'development') return true
if (menuInfos === null || menuInfos === '') return false
const menuInfoArr = JSON.parse(menuInfos)
const data = getFlatArr(menuInfoArr)
return data.some((item) => item.busicode == btnId)
}
//获取当前登录人
export const getSystemUserId = (createUser) => {
const loginUserInfo = JSON.parse(sessionStorage.getItem('loginUserInfo'))
if (
loginUserInfo === null ||
loginUserInfo === '' ||
!loginUserInfo.systemUserId ||
loginUserInfo.systemUserId === null
)
return false
return loginUserInfo.systemUserId === createUser
}