复杂表格的前端处理
适用场景:element组件(ui及plus都可以,核心思路是一致的)
情况一:element+多选+翻页+勾选
关于已上的情况,网上的资源相对还是比较多的,本人受益于以下文这两篇文章:
需求定义
而本人这次的需求,相较于以往的要更加复杂一些:
具体需求: 用户初选择页面:是table嵌套table的模式,选择的是内部table的row;
仅显示已选择后,需要罗列出已选择的rows;返回查看全部数据的时候,需要将已选择的数据回显进内部的table里。
具体如下图所示,帮助大家理解需求:
- 选择第一页数据:
- 选择第二页数据
- 查看已选择数据
- 再次回看全部数据(回显打勾)
首先,会返回之前的第二页,显示了之前选择的第二页情况;点击进入第一页,一开始每个父table都是收起的状态,点击张开后,需要重新勾选上已选择的项目。
代码实现
由于本人的仅查看已选择和全部的table不一致,则写了两个vue的文件,如下:
其中需要注意以下几点:
1、< ComSubList >和 < ComChooseTask >为组件形式引用,目的一是为了代码清晰;二是< ComSubList >组件在每次点击的时候会根据父组件那行的id传值,生成新的table里的数据,以组件形式书写更易独立代码空间。
可以看出< ComSubList >组件向内传值了scope.row.taskGroupId,就是为了初始化的时候向后台申请数据。
2、使用了v-show而不是v-if
如果使用了v-if在切换已选择和全部的时候会重新加载一遍,增加了一些不必要的后台请求,用户体验也不是很好(翻页的后台请求是无法避免,但是不翻页情况下,且大量用户操作完一般不会再多次翻页查看回显,更可能去已选择那里查看已选择的,因此v-show的体验感会更好)
且v-show是放在了单独的div上的,这是因为v-show会和有flex属性产生冲突,因此尽量放在纯净的div上。
<template>
<div class="cards">
<div class="opt">
<div> </div>
<div>
<el-checkbox v-model="formModel.isUsed" @change="onIsUsedChanged">仅显示已选中</el-checkbox
>
<el-button type="primary" @click="onMerge">合并路线</el-button>
<el-button type="primary" @click="onDelete">删除</el-button>
<el-button type="primary" @click="onRouteLibrary">导入路线库</el-button>
</div>
</div>
// v-show="!formModel.isUsed"的为全部数据的情况
<div v-show="!formModel.isUsed">
<el-table
ref="multipleTableRef"
:data="list"
style="width: 100%"
border
@expand-change="expandChange"
>
<el-table-column type="expand">
<template #default="scope">
<ComSubList ref="rSublist" :taskGroupId="scope.row.taskGroupId"></ComSubList>
</template>
</el-table-column>
<el-table-column label="Operate" width="160">
<template #default="scope">
<el-button size="mini" @click="onTestResult(scope.row)">测试结果</el-button>
</template>
</el-table-column>
<el-table-column property="taskGroupId" label="Group ID" width="80" />
<el-table-column property="taskTypeValue" label="Test Type" />
<el-table-column property="taskName" label="Test Name" />
<el-table-column property="countryName" label="Test Nation" />
<el-table-column property="operatorName" label="carrier" />
<el-table-column property="projectName" label="Test Project" />
<el-table-column property="createTime" label="Test Time">
<template #default="scope">{{ time(scope.row.createTime) }}</template>
</el-table-column>
<!-- <el-table-column property="testResult" label="Test Result" /> -->
<el-table-column property="createOwner" label="owner" />
</el-table>
<el-pagination
v-model:current-page="page"
v-model:page-size="count"
:page-sizes="[10, 20, 500]"
small="small"
layout="total, sizes, prev, pager, next, jumper"
:total="totalCount"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
// v-show="formModel.isUsed"的为已选择数据的情况
<div v-show="formModel.isUsed">
<ComChooseTask ref="rChooseTask"></ComChooseTask>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, computed, reactive, nextTick } from 'vue'
import { Delete, Download } from '@element-plus/icons-vue'
import { useStore } from 'vuex'
import ComChooseTask from './chooseList.vue'
import ComSubList from './sublist.vue'
export default defineComponent({
props: {},
components: { Delete, Download, ComSubList, ComChooseTask },
beforeCreate() {},
setup() {
const store: any = useStore($key)
const state: any = reactive({
formModel: {},
formOpts: {
dialog: false
},
rChooseTask: null,
rSublist: null,
list: computed({
get() {
return store.state.imapList.list
},
set(val: string) {
store.commit(`imapList/list`, val)
}
}),
page: computed({
get() {
return store.state.imapList.page
},
set(val: string) {
store.commit(`imapList/page`, val)
}
}),
count: computed({
get() {
return store.state.imapList.count
},
set(val: string) {
store.commit(`imapList/count`, val)
}
}),
totalCount: computed({
get() {
return store.state.imapList.totalCount
},
set(val: string) {}
}),
time(val: any) {
return $func.time(val)
},
async handleSizeChange(val: any) {
await $store.dispatch('imapList/loadList')
},
async handleCurrentChange(val: any) {
await $store.dispatch('imapList/loadList')
},
onIsUsedChanged() {},
async expandChange(row: any) {},
async onTestResult(row: any) {
store.commit('taskList/detailVisable', false)
store.commit('taskList/groupId', row.taskGroupId)
await store.dispatch('taskList/loadSubList')
$router.push('/taskResult')
},
onTestLine() {
$router.push('/imap')
},
onDelete() {},
onMerge() {},
onRouteLibrary() {}
})
return state
},
created() {}
})
</script>
ComSubList组件
<template>
<div>
<el-table
ref="rTable"
:data="formModel.sublist"
style="width: 100%"
border
@selection-change="selectionChange"
@select="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="Operate" width="160">
<template #default="scope">
<el-button size="mini" @click="onTestLine(scope.row)">测试路线</el-button>
</template>
</el-table-column>
<el-table-column property="taskId" label="Task ID" width="80" />
<el-table-column property="deviceSn" label="Device SN" />
<el-table-column property="deviceStatus" label="Device Status" />
<el-table-column property="runState" label="Run State" />
<el-table-column property="createTime" label="Create Time">
<template #default="scope">{{ time(scope.row.createTime) }}</template>
</el-table-column>
<el-table-column property="assignTime" label="Assign Time">
<template #default="scope">{{ time(scope.row.assignTime) }}</template>
</el-table-column>
<el-table-column property="finishTime" label="Finish Time">
<template #default="scope">{{ time(scope.row.finishTime) }}</template>
</el-table-column>
<el-table-column property="testResult" label="Test Result" />
</el-table>
<el-dialog title="地图显示" width="80%" v-model="formOpts.dialog" draggable>
<ComMap></ComMap>
</el-dialog>
</div>
</template>
<script lang="ts">
import { defineComponent, computed, reactive, nextTick } from 'vue'
import { Delete, Download } from '@element-plus/icons-vue'
import ComMap from '../map/index.vue'
import { useStore } from 'vuex'
export default defineComponent({
props: {
taskGroupId: {
type: Number,
required: true
}
},
components: { Delete, Download, ComMap },
beforeCreate() {},
setup(props: any, ctx) {
const store: any = useStore($key)
const state: any = reactive({
formModel: {
sublist: []
},
formOpts: {
dialog: false
},
rTable: null,
chooseSublist: computed({
get() {
return store.state.imapList.chooseSublist
},
set(val: string) {}
}),
chooseListId: computed({
get() {
return store.state.imapList.chooseListId
},
set(val: string) {}
}),
time(val: any) {
return $func.time(val)
},
async selectionChange(val: any) {
if (val) {
// 将获取到的id存入tableAllSelectedId数组(点击某行前面的勾选、选中某行的勾选、全选。三种状态都能触发此功能)
let len = val.length
for (let i = 0; i < len; i++) {
if (val[i] === undefined) {
continue
} else {
if (state.chooseListId.indexOf(val[i].taskId) === -1) {
store.commit('imapList/addTask', val[i])
}
}
}
console.log('state.formOpts.tableAllSelectedId', state.chooseListId)
}
},
async handleSelectionChange(rows: any, row: any) {
// 判断是点击了表格勾选还是取消勾选
// true就是选中,0或者false是取消选中
const selected = rows.length && rows.indexOf(row) !== -1
if (!selected) {
// 如果点击取消勾选
store.commit('imapList/delTask', row)
}
console.log('selectes -> tableAllSelectedId', state.chooseListId)
},
tick(rows?: any[]) {
if (rows) {
nextTick(() => {
rows.forEach((row) => {
state.rTable.toggleRowSelection(
state.formModel.sublist.find((item: any) => {
return row.taskId == item.taskId // 注意这里寻找的字段要唯一,示例仅参考
}),
true
)
})
})
}
},
async load(row: any) {
let res = await store.dispatch(`imapList/loadSubList`, props.taskGroupId)
state.formModel.sublist = res
state.tick(state.chooseSublist)
},
onTestLine() {
state.formOpts.dialog = true
}
})
return state
},
created() {
this.load()
}
})
</script>
<style lang="less" scoped></style>
ComChooseTask组件
<template>
<el-table
ref="multipleTableRef"
:data="chooseSublist"
style="width: 100%"
border
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="Operate" width="160">
<template #default="scope">
<el-button size="mini" @click="onTestLine(scope.row)">测试路线</el-button>
</template>
</el-table-column>
<el-table-column property="taskId" label="Task ID" width="80" />
<el-table-column property="deviceSn" label="Device SN" />
<el-table-column property="deviceStatus" label="Device Status" />
<el-table-column property="runState" label="Run State" />
<el-table-column property="createTime" label="Create Time">
<template #default="scope">{{ time(scope.row.createTime) }}</template>
</el-table-column>
<el-table-column property="assignTime" label="Assign Time">
<template #default="scope">{{ time(scope.row.assignTime) }}</template>
</el-table-column>
<el-table-column property="finishTime" label="Finish Time">
<template #default="scope">{{ time(scope.row.finishTime) }}</template>
</el-table-column>
<el-table-column property="testResult" label="Test Result" />
</el-table>
<el-dialog title="地图显示" width="80%" v-model="formOpts.dialog" draggable>
<ComMap></ComMap>
</el-dialog>
</template>
<script lang="ts">
import { defineComponent, computed, reactive, nextTick } from 'vue'
import { Delete, Download } from '@element-plus/icons-vue'
import ComMap from '../map/index.vue'
import { useStore } from 'vuex'
export default defineComponent({
props: {
taskGroupId: {
type: Number,
required: true
}
},
components: { Delete, Download, ComMap },
beforeCreate() {},
setup(props: any, ctx) {
const store: any = useStore($key)
const state: any = reactive({
formModel: {},
formOpts: {
dialog: false
},
chooseSublist: computed({
get() {
return store.state.imapList.chooseSublist
},
set(val: string) {
store.commit(`imapList/chooseSublist`, val)
}
}),
chooseListId: computed({
get() {
return store.state.imapList.chooseListId
},
set(val: string) {
store.commit(`imapList/chooseListId`, val)
}
}),
time(val: any) {
return $func.time(val)
},
async handleSelectionChange() {},
onTestLine() {
state.formOpts.dialog = true
}
})
return state
},
created() {}
})
</script>
<style lang="less" scoped>
</style>
本人再附上vuex里的一些逻辑,里面可能有些没用到,你们自己省略就好,我就直接copy上来了。
import { ElMessage } from 'element-plus'
// imap list
const vx = {
namespaced: true,
state: {
// model
count: 10,
countryId: null,
endTime: null,
keyWord: null,
operatorId: null,
page: 1,
projectId: '',
startTime: null,
taskType: null,
testType: 0,
list: [],
//choose list
chooseSublist: [],
chooseListId: [],
// opts
totalCount: 0,
countryOperators: [],
projects: [],
taskTypes: [
{
value: 0,
label: 'APK'
},
{
value: 1,
label: 'Web'
}
],
testTypes: [
{
value: 0,
label: 'Itestplus'
},
{
value: 1,
label: 'Box'
}
]
},
mutations: {
reset(state: any) {
;(state.count = 10),
(state.countryId = null),
(state.endTime = null),
(state.keyWord = null),
(state.operatorId = null),
(state.page = 1),
(state.projectId = ''),
(state.startTime = null),
(state.taskType = null),
(state.testType = 0),
(state.countryOperators = []),
(state.projects = []),
(state.totalCount = 0),
(state.list = []),
(state.chooseSublist = []),
(state.chooseListId = [])
},
totalCount(state: any, val: any) {
state.totalCount = val
},
page(state: any, val: any) {
state.page = val
},
count(state: any, val: any) {
state.count = val
},
list(state: any, val: any) {
state.list = val
},
chooseSublist(state: any, val: any) {
state.chooseSublist = val
},
chooseListId(state: any, val: any) {
state.chooseListId = val
},
addTask(state: any, val: any) {
state.chooseSublist.push(val)
state.chooseListId.push(val.taskId)
},
delTask(state: any, val: any) {
let id = val.taskId
let index = state.chooseListId.findIndex((obj: any) => obj === id)
state.chooseListId.splice(index, 1)
let indexObj = state.chooseSublist.findIndex((obj: any) => obj.taskId === id)
state.chooseSublist.splice(indexObj, 1)
},
taskType(state: any, val: any) {
state.taskType = val
},
testType(state: any, val: any) {
state.testType = val
},
countryId(state: any, val: any) {
state.countryId = val
},
operatorId(state: any, val: any) {
state.operatorId = val
},
keyWord(state: any, val: any) {
state.keyWord = val
},
projectId(state: any, val: any) {
state.projectId = val
},
startTime(state: any, val: any) {
if (!val) {
state.startTime = null
} else {
state.startTime = val
}
},
endTime(state: any, val: any) {
if (!val) {
state.endTime = null
} else {
state.endTime = val
}
},
onlyFail(state: any, val: any) {
state.onlyFail = val
}
},
actions: {
async init({ commit, dispatch, state, rootState }: any) {
dispatch('loadProject')
dispatch('loadCountryOperator')
dispatch('loadList')
},
async loadCountryOperator({ commit, dispatch, state, rootState }: any) {
try {
let params: any = {
status: 1,
page: 1,
count: 99999
}
$func.jsonDelNull(params)
let res = await $ax.get($api.operator.get.searchOperatorRelationByFilter, { params })
let countryOperator: any = []
if (res.data.results && res.data.results.length > 0) {
res.data.results.forEach((item: any) => {
// 暂不配置运营商
let operator: any = []
if (item.operator && item.operator.length > 0) {
item.operator.forEach((itm: any) => {
operator.push({
value: itm.operatorId,
label: itm.operatorName
})
})
}
let countryOperatorItem = {
value: item.countryId,
label: item.countryName,
children: operator
}
countryOperator.push(countryOperatorItem)
})
}
state.countryOperators = countryOperator
} catch (e: any) {
console.log('e', e)
}
},
async loadProject({ commit, dispatch, state, rootState }: any) {
try {
let params: any = {
page: 1,
count: 99999
}
$func.jsonDelNull(params)
let res = await $ax.get($api.project.get.getallprojects, { params })
state.projects = res.data.results
} catch (e: any) {
console.log('e', e)
}
},
async loadList({ commit, dispatch, state, rootState }: any) {
try {
let params: any = {
page: state.page,
count: state.count,
countryId: state.countryId,
endTime: state.endTime,
keyWord: '',
operatorId: state.operatorId,
projectId: state.projectId,
startTime: state.startTime,
taskType: state.taskType,
testType: state.testType
}
$func.jsonDelNull(params)
if (!params.hasOwnProperty('startTime')) {
params.startTime = null
}
if (!params.hasOwnProperty('endTime')) {
params.endTime = null
}
let res = await $ax.post($api.task.post.getAllGroupTask, params)
if (res.data.results) {
res.data.results.forEach((item: any) => {
item.sublist = []
})
}
state.list = res.data.results
state.totalCount = res.data.total_count
} catch (e: any) {
console.log('e', e)
}
},
async loadSubList({ commit, dispatch, state, rootState }: any, groupId: any) {
try {
let params: any = {
page: 1,
count: 9999,
groupId: groupId
}
$func.jsonDelNull(params)
let res = await $ax.get($api.task.get.getTaskInfo, { params })
return res.data.results
} catch (e: any) {
console.log('e', e)
}
},
async loadTaskDetail({ commit, dispatch, state, rootState }: any) {
try {
let params: any = {
taskId: state.taskId
}
$func.jsonDelNull(params)
let res = await $ax.get($api.task.get.getTaskDetailInfo, { params })
state.detailMainInfo = res.data
} catch (e: any) {
console.log('e', e)
}
},
async loadTaskCaseDetail({ commit, dispatch, state, rootState }: any) {
try {
let params: any = {
taskId: state.taskId,
onlyFail: state.onlyFail,
page: 1,
count: 9999
}
$func.jsonDelNull(params)
let res = await $ax.get($api.task.get.getTaskCaseInfo, { params })
state.detailCaseInfo = res.data.results
} catch (e: any) {
console.log('e', e)
}
}
},
getters: {}
}
export { vx }
总结一下
我们整理一下大体思路:
其实核心就是element组件table的选择+翻页+回显的具体实现
主要依托于两个函数:@selection-change=“selectionChange”,@select=“handleSelectionChange”
还有table回显时,对已选择数据的打勾。
async selectionChange(val: any) {
if (val) {
// 将获取到的id存入tableAllSelectedId数组(点击某行前面的勾选、选中某行的勾选、全选。三种状态都能触发此功能)
let len = val.length
for (let i = 0; i < len; i++) {
if (val[i] === undefined) {
continue
} else {
if (state.chooseListId.indexOf(val[i].taskId) === -1) {
store.commit('imapList/addTask', val[i])
}
}
}
console.log('state.formOpts.tableAllSelectedId', state.chooseListId)
}
},
async handleSelectionChange(rows: any, row: any) {
// 判断是点击了表格勾选还是取消勾选
// true就是选中,0或者false是取消选中
const selected = rows.length && rows.indexOf(row) !== -1
if (!selected) {
// 如果点击取消勾选
store.commit('imapList/delTask', row)
}
console.log('selectes -> tableAllSelectedId', state.chooseListId)
},
情况二; element组件库 + 翻页 + 搜索 + 选择 + 仅查看已选择(最基础的功能,情况一的基础版本)
大概样式如下所示:
核心思路
我习惯于用两个table来记录完整数据(t1)和已选择的数据(t2)
t1表中对于选择 + 翻页 + 搜索的实现主要基于@selection-change=“selectionChange”,@select=“handleSelectionChange”
回显时需要将已选择的数据勾选上,我这里使用了watch去监听。
具体代码如下(vue2 elementUI实现):
<template>
<div class="container" :style="{ maxHeight: formOpts.show ? '1000px' : '30px' }">
<div class="hline" @click="onExpand">
<strong class="title-font">日志分析策略:</strong>
<div class="show"><i class="el-icon-arrow-right" /></div>
</div>
<div class="line"></div>
<div>
<div class="search-box">
<div>
<el-input
size="small"
class="input-search"
v-model="formModel.strategyName"
placeholder="策略名称"
/>
<el-input
size="small"
class="input-search"
v-model="formModel.submiiter"
placeholder="Owner"
/>
<el-button size="small" type="primary" @click="getList">搜索</el-button>
</div>
<el-checkbox v-model="formOpts.selected">仅查看已选中</el-checkbox>
</div>
<el-table
border
key="t1"
v-if="!formOpts.selected"
ref="multipleTable"
:data="formOpts.strategies"
style="width: 73%"
@select="handleSelectionChange"
@selection-change="selectionChange"
>
<el-table-column type="selection" width="55">
</el-table-column>
<el-table-column label="ID" width="40">
<template slot-scope="scope">{{ scope.row.analyStrategyId }}</template>
</el-table-column>
<el-table-column prop="analyStrategyName" label="名称" width="150"> </el-table-column>
<el-table-column prop="remark" label="描述"> </el-table-column>
<el-table-column prop="submitter" label="Owner" width="140"> </el-table-column>
</el-table>
<el-pagination
v-if="!formOpts.selected"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="formModel.page"
:page-sizes="[5, 10, 20]"
:page-size="formModel.count"
layout="total, sizes, prev, pager, next, jumper"
:total="formOpts.total"
>
</el-pagination>
<el-table
border
key="t2"
height="300"
v-if="formOpts.selected"
ref="multipleTable_selected"
:data="formOpts.selectedList"
style="width: 73%"
>
<!-- <el-table-column type="selection" width="55">
<template slot-scope="scope">
<el-checkbox
v-model="formOpts.selected && formOpts.trueFlag"
:disabled="formOpts.selected"
></el-checkbox>
</template>
</el-table-column> -->
<el-table-column label="ID" width="40">
<template slot-scope="scope">{{ scope.row.analyStrategyId }}</template>
</el-table-column>
<el-table-column prop="analyStrategyName" label="名称" width="150"> </el-table-column>
<el-table-column prop="remark" label="描述"> </el-table-column>
<el-table-column prop="submitter" label="Owner" width="140"> </el-table-column>
</el-table>
</div>
</div>
</template>
<script>
export default {
name: 'ulogsys',
props: {
value: Object,
isCopy: {
type: Boolean,
default: false,
},
},
data() {
return {
formOpts: {
show: false,
strategies: [],
total: 0,
selected: false,
selectedId: [],
selectedList: [],
trueFlag: true,
},
formModel: {
page: 1,
count: 5,
strategyName: '',
submitter: '',
ulogsys: {},
},
rules: {},
}
},
watch: {
'formOpts.strategies': {
async handler(val) {
val.forEach((item) => {
this.$nextTick(() => {
if (this.$refs.multipleTable) {
if (this.formOpts.selectedId.indexOf(item.analyStrategyId) > -1) {
this.$refs.multipleTable.toggleRowSelection(item, true)
} else {
this.$refs.multipleTable.toggleRowSelection(item, false)
}
}
})
})
},
deep: false,
immediate: true,
},
'formOpts.selected': {
async handler(val) {
this.formOpts.strategies.forEach((item) => {
this.$nextTick(() => {
if (this.$refs.multipleTable) {
if (this.formOpts.selectedId.indexOf(item.analyStrategyId) > -1) {
this.$refs.multipleTable.toggleRowSelection(item, true)
} else {
this.$refs.multipleTable.toggleRowSelection(item, false)
}
}
})
})
},
deep: false,
immediate: true,
},
},
methods: {
handleSizeChange(val) {
this.formModel.count = val
this.getList()
},
handleCurrentChange(val) {
this.formModel.page = val
this.getList()
},
async selectionChange(val) {
if (val) {
// 将获取到的id存入tableAllSelectedId数组(点击某行前面的勾选、选中某行的勾选、全选。三种状态都能触发此功能)
val.forEach((item) => {
if (this.formOpts.selectedId.indexOf(item.analyStrategyId) === -1) {
this.formOpts.selectedId.push(item.analyStrategyId)
this.formOpts.selectedList.push(item)
}
})
}
},
async handleSelectionChange(rows, row) {
// 判断是点击了表格勾选还是取消勾选
// true就是选中,0或者false是取消选中
const selected = rows.length && rows.indexOf(row) !== -1
if (!selected) {
// 如果点击取消勾选
let id = row.analyStrategyId
let index = this.formOpts.selectedId.findIndex((obj) => obj === id)
this.formOpts.selectedId.splice(index, 1)
let indexObj = this.formOpts.selectedList.findIndex((obj) => obj.analyStrategyId === id)
this.formOpts.selectedList.splice(indexObj, 1)
}
},
changeUlogsys() {},
onExpand() {
this.formOpts.show = !this.formOpts.show
},
async getList() {
let params = {
submitter: this.formModel.submitter,
strategyName: this.formModel.strategyName,
page: this.formModel.page,
count: this.formModel.count,
}
this.$func.jsonDelNull(params)
let res = await this.$api.newTest.getULogStrategy(params)
this.formOpts.strategies = res.data.data.results
this.formOpts.total = res.data.data.totalCount
},
load() {
this.getList()
},
},
mounted() {
this.load()
},
}
</script>
<style scoped lang="less">
.hline {
width: 73%;
display: flex;
justify-content: space-between;
cursor: pointer;
.show {
color: #c0c4cc;
}
}
.container {
max-height: 30px;
transition: max-height 1s;
overflow: hidden;
}
.title-font {
color: #35bd9e;
font-size: 18px;
}
.line {
width: 73%;
height: 2px;
border-top: solid #dcdfe6 1px;
margin-bottom: 15px;
}
.search-box {
width: 73%;
display: flex;
justify-content: space-between;
margin-bottom: 10px;
.input-search {
width: 200px;
margin-right: 10px;
}
}
.el-pagination {
margin: 10px 0;
}
</style>
情况三: 翻页 + 搜索 + 单选 + 进查看已选择
这种情况比多选的要容易一些
其中核心思路是把第一列里添加el-radio,再监听el-radio选择的id,将整行row的数据添加到已选择的数据表里
<template>
<div class="container" :style="{ maxHeight: formOpts.show ? '1000px' : '30px' }">
<div class="hline" @click="onExpand">
<strong class="title-font">日志分析策略:</strong>
<div class="show"><i class="el-icon-arrow-right" /></div>
</div>
<div class="line"></div>
<div>
<div class="search-box">
<div>
<el-input
size="small"
class="input-search"
v-model="formModel.strategyName"
placeholder="策略名称"
/>
<el-input
size="small"
class="input-search"
v-model="formModel.submiiter"
placeholder="Owner"
/>
<el-button size="small" type="primary" @click="getList">搜索</el-button>
</div>
<el-checkbox v-model="formOpts.selected">仅查看已选中</el-checkbox>
</div>
<el-table
border
key="t1"
v-if="!formOpts.selected"
ref="multipleTable"
:data="formOpts.strategies"
style="width: 73%"
>
<el-table-column width="75">
<template slot-scope="scope">
<el-radio v-model="formModel.checkedId" :label="scope.row.analyStrategyId"></el-radio>
</template>
</el-table-column>
<el-table-column prop="analyStrategyName" label="名称" width="150"> </el-table-column>
<el-table-column prop="remark" label="描述"> </el-table-column>
<el-table-column prop="submitter" label="Owner" width="140"> </el-table-column>
</el-table>
<el-pagination
v-if="!formOpts.selected"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="formModel.page"
:page-sizes="[5, 10, 20]"
:page-size="formModel.count"
layout="total, sizes, prev, pager, next, jumper"
:total="formOpts.total"
>
</el-pagination>
<el-table
border
key="t2"
height="300"
v-if="formOpts.selected"
ref="multipleTable_selected"
:data="formOpts.selectedList"
style="width: 73%"
>
<el-table-column label="ID" width="40">
<template slot-scope="scope">{{ scope.row.analyStrategyId }}</template>
</el-table-column>
<el-table-column prop="analyStrategyName" label="名称" width="150"> </el-table-column>
<el-table-column prop="remark" label="描述"> </el-table-column>
<el-table-column prop="submitter" label="Owner" width="140"> </el-table-column>
</el-table>
</div>
</div>
</template>
<script>
export default {
name: 'ulogsys',
props: {
value: Object,
isCopy: {
type: Boolean,
default: false,
},
},
data() {
return {
formOpts: {
show: false,
strategies: [],
total: 0,
selected: false,
selectedId: [],
selectedList: [],
trueFlag: true,
},
formModel: {
page: 1,
count: 5,
strategyName: '',
submitter: '',
ulogsys: {},
checkedId: null,
},
rules: {},
}
},
watch: {
'formModel.checkedId': {
async handler(val) {
if (val > 0) {
this.formOpts.selectedList = []
let temp = this.formOpts.strategies.filter((item) => {
return item.analyStrategyId == val
})
this.formOpts.selectedList = temp
console.log('this.formOpts.selectedList', this.formOpts.selectedList)
} else {
this.formOpts.selectedList = []
}
},
deep: false,
immediate: true,
},
},
methods: {
handleSizeChange(val) {
this.formModel.count = val
this.getList()
},
handleCurrentChange(val) {
this.formModel.page = val
this.getList()
},
changeUlogsys() {},
onExpand() {
this.formOpts.show = !this.formOpts.show
},
async getList() {
if (this.formModel.submitter || this.formModel.strategyName) {
this.formModel.page = 1
this.formModel.count = 5
}
let params = {
submitter: this.formModel.submitter,
strategyName: this.formModel.strategyName,
page: this.formModel.page,
count: this.formModel.count,
}
this.$func.jsonDelNull(params)
let res = await this.$api.newTest.getULogStrategy(params)
this.formOpts.strategies = res.data.data.results
? res.data.data.results.map((item) => {
let temp = {
checked: false,
}
return { ...item, ...temp }
})
: []
this.formOpts.total = res.data.data.totalCount
},
load() {
this.getList()
},
},
mounted() {
this.load()
},
}
</script>
<style scoped lang="less">
.hline {
width: 73%;
display: flex;
justify-content: space-between;
cursor: pointer;
.show {
color: #c0c4cc;
}
}
.container {
max-height: 30px;
transition: max-height 1s;
overflow: hidden;
}
.title-font {
color: #35bd9e;
font-size: 18px;
}
.line {
width: 73%;
height: 2px;
border-top: solid #dcdfe6 1px;
margin-bottom: 15px;
}
.search-box {
width: 73%;
display: flex;
justify-content: space-between;
margin-bottom: 10px;
.input-search {
width: 200px;
margin-right: 10px;
}
}
.el-pagination {
margin: 10px 0;
}
</style>
其他复杂表格后续继续增加。。。(敬请期待)