需求
我们在开发过程中有时候会遇到列表里面会有多选,然后列表样式也要进行自定义。这里我们如果直接使用ElementUI组件el-table表格的时候这里实现起来可能比较复杂不方便,我们这里手写自定义一下列表里面多选的功能。
实现效果如下图所示:
具体实现代码如下
1- 我们这里先建一个子组件LiteratureTable.vue
<template>
<div class="mainComponent">
<div v-if="tableData.length" class="allCheck">
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" v-if="$_has('documentDatabase:download')" @change="handleCheckAllChange">全选</el-checkbox>
</div>
<div style="text-align: center;padding: 20px 0;" v-else>
<el-tag type="warning">暂无数据</el-tag>
</div>
<div class="tableList">
<el-checkbox-group v-model="checkedCities" @change="handleCheckedCitiesChange">
<el-checkbox class="tableItem" v-for="item in tableData" :label="item.literatureId" :key="item.literatureId">
<div class="itemPart">
<div class="TopPart">
<div class="TopLeft">
<div class="title">
<span class="centerTitle">{{item.title || '无'}}</span>
<span class="centerNumber">{{item.code || '无'}}</span>
</div>
</div>
<div class="topRight" v-if="!followupSelectvalue">
<template v-if="$_has('documentDatabase:edit')">
<i class="iconFont el-icon-edit" @click.prevent="editHandel(item)">编辑</i>
<el-divider direction="vertical"></el-divider>
</template>
<!-- <i class="iconFont el-icon-download" @click.prevent="downloadHandel(item.literatureId)">下载</i> -->
<!-- <i class="iconFont el-icon-download"></i>
<DownloadFileForInspection
style="margin: 0 -10px;"
textColor="#67C23A"
btnName="下载"
type="text"
:url="'/literature/literature/downloadUrl'"
:data="{ literatureId: item.literatureId }"
method="post"
/> -->
<!-- <el-divider direction="vertical"></el-divider> -->
<i v-if="$_has('documentDatabase:delete')" class="iconFont el-icon-delete" @click.prevent="deleItem(item.literatureId)">删除</i>
</div>
<div class="topRight" v-else>
<el-button type="primary" @click="addselectLiteratureId(item)" size="mini">选中</el-button>
</div>
</div>
<div class="BottomText">
<div class="text-tag">
<!-- <span>{{ Projectnamepocket(item.projectId, 'allProject') }}</span>
|
<span>{{ tagListPocket(item.derivation, 'Derivation') }}</span>
|
<span>{{ tagListPocket(item.type, 'Type') }}</span>
|
<span>{{ item.publishYear }}</span>
|
<span>{{ tagListPocket(item.lang, 'Lang') }}</span>
|
<span>{{ item.provenance || '无' }}</span>
|
<span>{{ item.downloadCount || '无' }}</span> -->
{{ item.tagName || '无' }}
</div>
<div>
{{ item.created_at }}
</div>
</div>
</div>
</el-checkbox>
</el-checkbox-group>
</div>
<el-dialog title="编辑" :visible.sync="editVisible" width="460px">
<el-form
:inline="false"
class="edit-form"
ref="editForm"
:model="editForm"
label-width="145px">
<el-form-item
:rules="{ required: true, message: '请输入标题', trigger: 'blur' }"
label="标题"
prop="title">
<el-input v-model="editForm.title" placeholder="请输入标题" clearable></el-input>
</el-form-item>
<el-form-item
:rules="{ required: true, message: '请选择项目', trigger: 'change' }"
label="项目"
prop="projectId">
<SelectGeneric
@change="projectValueChange(editForm.projectId)"
:select.sync="editForm.projectId"
filterable
multiple
:options="'allProject' | pocketOptions"
placeholder="请选择项目"
>
</SelectGeneric>
</el-form-item>
<el-form-item
:rules="{ required: true, message: '请选择年限', trigger: 'change' }"
label="发表年限"
prop="publishYear">
<el-date-picker
v-model="editForm.publishYear"
:picker-options="pickerOptions"
type="year"
format="yyyy"
value-format="yyyy"
placeholder="请选择年限">
</el-date-picker>
</el-form-item>
<el-form-item label="来源" prop="provenance">
<el-input v-model="editForm.provenance" placeholder="请输入来源" clearable></el-input>
</el-form-item>
<el-form-item label="影响因子" prop="influence">
<!-- <el-input type="number" v-model="editForm.influence" placeholder="请输入影响因子" clearable></el-input> -->
<MyInputNumber style="width: 200px;" v-model="editForm.influence" :min="0" :max="1000" :precision="3" placeholder="请输入影响因子" clearable></MyInputNumber>
</el-form-item>
<el-form-item
v-if="derivationOptions.length > 0"
:rules="{ required: true, message: '请选择出处', trigger: 'change' }"
label="出处"
prop="derivationId">
<SelectGeneric
:select.sync="editForm.derivationId"
:options="derivationOptions"
placeholder="请选择出处"
multiple
collapse-tags
clearable
>
</SelectGeneric>
</el-form-item>
<el-form-item
v-for="(activeFormItem, i) in activeFormItems"
:key="i"
:label="activeFormItem.label"
:prop="activeFormItem.shortName"
:rules="{ required: !!activeFormItem.required, message: '请选择' + activeFormItem.label, trigger: 'change' }"
>
<el-cascader
v-if="activeFormItem.type === 'cascader'"
:options="activeFormItem.ch"
v-model="editForm[activeFormItem.shortName]"
:show-all-levels="false"
:props="cascaderProps"
:placeholder="'请选择' + activeFormItem.label"
clearable
filterable>
</el-cascader>
<SelectGeneric
v-else
collapse-tags
filterable
clearable
:multiple="activeFormItem.type === 'multiple'"
:select.sync="editForm[activeFormItem.shortName]"
:options="activeFormItem.ch"
:placeholder="'请选择' + activeFormItem.label"
>
</SelectGeneric>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="editVisible = false">取 消</el-button>
<el-button type="primary" @click="editConfirm">确 定</el-button>
</div>
</el-dialog>
<el-dialog title="下载文献" :visible.sync="downloadVisible" width="460px" @closed="downloadClose">
<el-form
class="communication-form"
ref="downloadForm"
:model="downloadForm"
label-width="80px">
<el-form-item
label="文献目的"
prop="Goals"
:rules="{ required: true, message: '请选文献目的', trigger: 'change' }">
<el-radio-group v-model="downloadForm.Goals">
<el-radio label="DoctorNeeds">医生需求</el-radio>
<el-radio label="SelfLearning">自我学习</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label="医生编号"
prop="DoctorNo"
v-if="downloadForm.Goals === 'DoctorNeeds'"
:rules="{ required: true, message: '请输入医生编号', trigger: 'blur' }">
<el-input v-model="downloadForm.DoctorNo" placeholder="请输入医生编号" clearable></el-input>
</el-form-item>
<el-form-item
label="项目"
prop="ProjectId"
:rules="{ required: true, message: '请选择项目', trigger: 'change' }">
<SelectGeneric
:select.sync="downloadForm.ProjectId"
:options="'allProject' | pocketOptions"
placeholder="请选择项目"
filterable
>
</SelectGeneric>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="downloadVisible = false">取 消</el-button>
<el-button type="primary" @click="downloadConfirm">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { downloadByUrl } from '@utils/index'
export default {
props: ['tableData', 'followupSelectvalue'],
data () {
return {
downloadVisible: false,
downloadForm: {
Goals: 'DoctorNeeds',
DoctorNo: undefined,
ProjectId: undefined
},
selectLiteratureId: null,
cascaderProps: {
multiple: true,
emitPath: false,
checkStrictly: false,
label: 'label',
value: 'value',
children: 'ch'
},
editVisible: false,
editForm: {
relationId: [],
derivationId: []
},
derivationOptions: [],
pickerOptions: {
disabledDate: (val) => {
var date = new Date()
if (val.getFullYear() >= 2010 && val.getFullYear() <= date.getFullYear()) {
return false
} else {
return true
}
}
},
checkAll: false,
checkedCities: [],
cities: [
{
literatureId: '1',
name: '1'
},
{
literatureId: '2',
name: '2'
},
{
literatureId: '3',
name: '3'
}
],
isIndeterminate: false,
activeFormItems: [],
activeFormField: {}
}
},
watch: {
},
methods: {
projectValueChange (val) {
if (val !== null && val !== '') {
// this.editForm.derivationId = []
this.$store.dispatch('scholarlyLiterature/getDerivationList', { ProjectId: val }).then(res => {
this.derivationOptions = res.data
})
} else {
this.editForm.derivationId = []
this.derivationOptions = []
}
},
// 获取项目名称
Projectnamepocket (value, type, defalult) {
var pocketLabel = []
for (const i in this.$store.state.tool.pocket) {
if (i === type) {
if (Array.isArray(value)) {
for (const item of value) {
for (const v of this.$store.state.tool.pocket[type]) {
if (item === v.value) {
pocketLabel.push(v.label)
}
}
}
} else {
for (const v of this.$store.state.tool.pocket[type]) {
if (value === v.value) {
pocketLabel.push(v.label)
}
}
}
break
}
}
return pocketLabel.length > 0 ? pocketLabel.join('、') : (defalult || '无')
},
tagListPocket (value, type, defalult) {
if (!value) return '无'
var pocketLabel = []
const tagList = this.$store.state.tool.pocket.tagList || []
for (let i = 0; i < tagList.length; i++) {
const element = tagList[i]
if (element.shortName === type) {
if (Array.isArray(value)) {
for (const item of value) {
for (const v of element.ch) {
if (item === v.value) {
pocketLabel.push(v.label)
}
}
}
} else {
for (const v of i.ch) {
if (value === v.value) {
pocketLabel.push(v.label)
}
}
}
break
}
}
return pocketLabel.length > 0 ? pocketLabel.join('、') : (defalult || '无')
},
editHandel (row) {
this.$store.dispatch('scholarlyLiterature/getDerivationList', { ProjectId: row.projectId }).then(res => {
this.derivationOptions = res.data
this.editForm = row
this.editVisible = true
this.$refs.editForm && this.$refs.editForm.clearValidate()
})
},
editConfirm () {
const options = this.editForm
// options.relation = this.editForm.relationId.map(e => e[1])
this.$refs.editForm.validate((valid) => {
if (valid) {
this.$store.dispatch('scholarlyLiterature/LiteratureEdit', options).then(res => {
if (res.data) {
this.editVisible = false
this.$message.success('编辑成功')
this.$emit('refreshCurrentPage')
}
})
} else {
return false
}
})
},
handleCheckAllChange (val) {
console.log(val)
var arr = []
for (var i = 0; i < this.tableData.length; i++) {
arr.push(this.tableData[i].literatureId)
}
this.checkedCities = val ? arr : []
this.$emit('change', this.checkedCities)
this.isIndeterminate = false
},
handleCheckedCitiesChange (value) {
const checkedCount = value.length
this.checkAll = checkedCount === this.tableData.length
this.isIndeterminate = checkedCount > 0 && checkedCount < this.tableData.length
this.$emit('change', value)
},
downloadConfirm () {
this.$refs.downloadForm.validate((valid) => {
if (valid) {
const options = {
...this.downloadForm,
LiteratureId: this.selectLiteratureId
}
this.$store.dispatch('scholarlyLiterature/GetLiteratureDownloadUrl', options).then(res => {
downloadByUrl(res.data.url)
this.downloadVisible = false
this.downloadForm = {
Goals: 'DoctorNeeds',
DoctorNo: undefined,
ProjectId: undefined
}
})
} else {
return false
}
})
},
deleItem (literatureId) {
this.$confirm('确定删除吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$store.dispatch('scholarlyLiterature/LiteratureDel', { literatureId }).then(res => {
if (res.data) {
this.$message.success('删除成功')
this.$emit('refreshCurrentPage')
}
})
}).catch(() => {})
},
addselectLiteratureId (row) {
console.log(row)
this.$emit('selectliteratureData', row)
}
}
}
</script>
<style lang="scss" scoped>
.mainComponent {
.tableList {
::v-deep .el-checkbox {
user-select: auto;
cursor: default;
}
.tableItem {
display: block;
width: 100%;
position: relative;
::v-deep .el-checkbox__input {
position: absolute;
top: 50%;
margin-top: -23px;
}
::v-deep .el-checkbox__label {
width: 100%;
padding-left: 23px;
.itemPart {
border-bottom: 1px solid #ededed;
padding: 10px 0px;
.TopPart {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
.TopLeft {
display: flex;
align-items: center;
.topLeftCheck {
padding-right: 20px;
display: flex;
}
.title {
cursor: pointer;
}
.centerTitle {
font-size: 16px;
font-weight: 600;
padding-right: 15px;
color: #333;
}
.centerNumber {
display: inline-block;
width: 130px;
height: 17px;
font-weight: 600;
background-color: rgb(242, 242, 243);
border-color: rgb(155, 157, 163);
border-width: 1px;
border-style: solid;
color: rgb(133, 136, 142);
border-radius: 3px;
font-size: 12px;
padding: 0px;
text-align: center;
line-height: 17px;
}
.centerTime {
color: #9999;
font-size: 14px;
line-height: 28px;
}
}
.topRight {
color: #6666;
font-size: 14px;
padding-right: 50px;
.iconFont {
cursor: pointer;
color: #60a4e7;
&.el-icon-download {
color: #67C23A;
}
&.el-icon-delete {
color: orange;
}
}
}
}
.BottomText {
display: flex;
justify-content: space-between;
align-items: center;
padding-right: 50px;
color: #636363;
font-size: 14px;
.text-tag {
min-width: 1000px;
white-space: normal;
word-break: break-all;
word-wrap: break-word;
white-space: pre-wrap;
line-height: 1.5;
margin-right: 35px;
}
&.noPadding {
padding-left: 0;
padding-right: 0;
}
}
}
}
}
}
}
::v-deep .edit-form {
.MyInputNumber {
width: 200px;
}
}
</style>
2-父组件引入子组件LiteratureTable 如下:
<template>
<section>
<el-form :inline="true" class="communication-form" :model="formData">
<el-form-item>
<SelectGeneric
:select.sync="formData.ProjectId"
:options="'allProject' | pocketOptions"
placeholder="请选择项目"
filterable
>
</SelectGeneric>
</el-form-item>
<el-form-item>
<SelectGeneric
:select.sync="formData.derivationId"
:options="'derivation' | pocketOptions"
placeholder="请选择出处"
filterable
>
</SelectGeneric>
</el-form-item>
<el-form-item>
<el-date-picker
v-model="formData.PublishYear"
:picker-options="pickerOptions"
value-format="yyyy"
type="year"
placeholder="选择年限">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-date-picker
v-model="formData.Date"
type="daterange"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
range-separator="至"
start-placeholder="更新开始日期"
end-placeholder="更新结束日期">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-input v-model="formData.Keyword" placeholder="请输入关键字" clearable></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="search('searchForm')">搜索</el-button>
<DownloadFileForInspection
v-if="$_has('documentDatabase:download')"
btnName="下载"
type="primary"
:url="'/literature/literature/downloadPackage'"
:data="{ literatureIds: selectBatchDownloadIds }"
method="post"
/>
<el-button type="primary" v-if="$_has('documentDatabase:upload')" @click="addLiterature" style="margin-left: 10px;">上传</el-button>
<el-button type="primary" v-if="$_has('documentDatabase:create')" @click="creatRequire">新建需求</el-button>
</el-form-item>
</el-form>
<LiteratureTable
@change="costPlannedAmountChange($event)"
:tableData="tableData"
@refreshCurrentPage="search">
</LiteratureTable>
<Pagination
:total="pagination.totalCount"
:pageSize="pagination.pageSize"
:pageNumber.sync="pagination.pageNumber"
@sizeChange="handleSizeChange"
@currentChange="handleCurrentChange"
layout="total, sizes, prev, pager, next, jumper"
>
</Pagination>
</section>
</template>
<script>
import { PageSearch } from '@/mixins'
import LiteratureTable from '../components/LiteratureTable'
export default {
name: 'DocumentDatabase',
components: { LiteratureTable },
mixins: [PageSearch],
data () {
return {
cascaderProps: {
multiple: true,
emitPath: false,
checkStrictly: false,
label: 'label',
value: 'value',
children: 'ch'
},
formData: {
ProjectId: '',
derivationId: '',
PublishYear: '',
Date: '',
Keyword: ''
},
tableData: [],
addLiteratureVisible: false,
selectBatchDownloadIds: [],
pickerOptions: {
disabledDate: (val) => {
var date = new Date()
if (val.getFullYear() >= 2010 && val.getFullYear() <= date.getFullYear()) {
return false
} else {
return true
}
}
},
activeFormItems: [],
activeFormField: {}
}
},
activated () {
this.search()
},
watch: {
},
methods: {
// 接收selectBatchDownloadIds
async costPlannedAmountChange (value) {
this.selectBatchDownloadIds = value
},
addLiterature () {
this.addLiteratureVisible = true
},
addLiteratureConfirm () {
this.$refs.addLiteratureRef.$refs.addLiteratureForm.validate((valid) => {
if (valid) {
// console.log(this.$refs.addLiteratureRef.literatureData)
const options = JSON.parse(JSON.stringify(this.$refs.addLiteratureRef.literatureData.literatureList))
if (options.length <= 0) return
// options.forEach(e => {
// e.relation = e.relation.map(e => e[1])
// })
const fileNameList = options.map(e => e.fileName)
this.$store.dispatch('scholarlyLiterature/CheckName', { fileNameList }).then(res => {
if (res.data.length <= 0) {
// 校验成功
this.submitFileList(options)
}
if (res.data.length > 0) {
this.$confirm('文献库中已有重复文件:' + res.data[0], '提示', {
confirmButtonText: '忽略',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.submitFileList(options)
}).catch(() => {})
}
})
} else {
return false
}
})
},
submitFileList (data) {
this.$store.dispatch('scholarlyLiterature/UploadLiterature', { literatureList: data }).then(res => {
if (res.data) {
this.addLiteratureVisible = false
this.$message.success('上传成功')
this.search()
this.$refs.addLiteratureRef.literatureData.literatureList = []
}
})
},
addLiteratureClose () {
this.addLiteratureVisible = false
this.$refs.addLiteratureRef.literatureData.literatureList = []
},
creatRequire () {
this.$router.push({ name: 'CreatRequire' })
},
literatureRetrieval () {
this.$router.push({ name: 'LiteratureRetrieval' })
},
search (type) {
if (type === 'searchForm') {
this.pagination.pageNumber = 1
}
const { pageSize, pageNumber } = this.pagination
const options = {
...this.formData,
// Relation: this.formData.Relation.map(e => e[1]),
StartTime: this.formData.Date && this.formData.Date[0],
EndTime: this.formData.Date && this.formData.Date[1],
pageSize,
pageNumber
}
this.$store.dispatch('scholarlyLiterature/GetLiteratureList', options).then(res => {
const { list, page } = res.data
this.tableData = list
this.pagination = page
})
}
}
}
</script>
<style lang="scss" scoped>
.el-alert {
margin-bottom: 20px;
}
</style>