一:a-checkbox-group多选框的赋值与取值
效果
如图所示,这是一个弹窗,弹窗中是多选框。而且不仅包含了多选框,还包含了时间组件
实现代码
页面
<template>
<c-modal
title="资质"
centered
:destroyOnClose="true"
:visible="visible"
:loading="loading"
:confirmLoading="confirmLoading"
@ok="handleSubmit"
@cancel="handleClose"
>
<a-form-model
:label-col="{ span: 24 }"
:wrapper-col="{ span: 24 }"
ref="StaffQualification"
:model="form"
:rules="rules"
:validate-messages="validateMessages"
>
<a-row :gutter="24">
<a-col :span="24">
<a-form-model-item label="资质" prop="qualification">
<a-checkbox-group v-model="form.qualification">
<a-row>
<a-col style="margin-bottom: 10px" v-for="item in qualificationOptions" :key="item.qualification.id">
<a-checkbox style="width: 200px" :value="item">{{ item.qualification.name }}</a-checkbox>
<a-date-picker :default-value="item.qualificationStartAt" v-model="item.qualificationStartAt" :format="dateFormat" placeholder="开始日期" style="margin-left: 10px"/>
<a-date-picker :default-value="item.qualificationEndAt" v-model="item.qualificationEndAt" :format="dateFormat" placeholder="结束日期" style="margin-left: 10px"/>
</a-col>
</a-row>
</a-checkbox-group>
</a-form-model-item>
</a-col>
</a-row>
</a-form-model>
</c-modal>
</template>
js
import moment from 'moment'
import 'moment/locale/zh-cn'
moment.locale('zh-cn')
export default {
data () {
return {
loading: false,
visible: false,
confirmLoading: false,
form: {
qualification: []
},
qualificationDate: null,
rules: {},
qualificationOptions: [],
dateFormat: 'YYYY-MM-DD'
}
},
methods: {
async edit (record) {
this.visible = true
this.loading = true
try {
this.form.id = record.id
// 从后台取到资质列表
const arr = await xxx.query(
{},
{ showLoading: false, showSuccess: false, showFailure: false }
)
// 定义两个list分别存下拉框的选项 和 绑定的选项
this.qualificationOptions = []
this.form.qualification = []
arr.forEach(optionsMap => {
const optionsNode = {
id: null,
qualification: {
id: optionsMap.id,
name: optionsMap.name
},
qualificationEndAt: null,
qualificationStartAt: null
}
// 回显
record.staffQualifications.forEach(map => {
if (optionsNode.qualification.id === map.qualification.id) {
optionsNode.id = map.id
optionsNode.qualificationEndAt = moment(map.qualificationEndAt, 'YYYY-MM-DD')
optionsNode.qualificationStartAt = moment(map.qualificationStartAt, 'YYYY-MM-DD')
this.form.qualification.push(optionsNode)
}
})
this.qualificationOptions.push(optionsNode)
})
} catch (error) {
console.error(error)
}
this.loading = false
},
handleSubmit () {
this.confirmLoading = true
const staffQualifications = []
this.form.qualification.forEach(item => {
const qualification = {
id: item.qualification.id
}
const staffQualification = {
qualification: qualification,
qualificationStartAt: item.qualificationStartAt !== undefined ? item.qualificationStartAt.format('YYYY-MM-DD HH:mm:ss') : null,
qualificationEndAt: item.qualificationEndAt !== undefined ? item.qualificationEndAt.format('YYYY-MM-DD HH:mm:ss') : null
}
staffQualifications.push(staffQualification)
})
const requestModel = {
id: this.form.id,
staffQualifications: staffQualifications
}
try {
// 提交
await xxx.updateQualification(requestModel, { showLoading: false })
this.confirmLoading = false
this.handleClose()
this.$emit('ok')
} catch (error) {
this.confirmLoading = false
}
} else {
return false
}
},
handleClose () {
if (this.$refs['StaffQualification'] !== undefined) {
this.$refs['StaffQualification'].resetFields()
}
this.visible = false
}
}
}
</script>
二:# a-select复选框的搜索与样式优化
效果
如图所示,在antdv的表格中,有涉及到下拉多选的需求,并且将选中的结果在单元格内一行展示,鼠标滑动观之。
代码
表格单元格的代码
<template slot="editMorning" slot-scope="node">
<a-select :dropdownMatchSelectWidth="true" :filter-option="filterOption" @change="onCellChange(node.AM, $event)" mode="multiple" :showArrow="false" :options="node.AM.staffOptions" :default-value="node.AM.staffChooses" style="width: 110px"/>
</template>
上面的属性稍微解释一下:
属性 | 释义 |
---|---|
mode="multiple" | 多选 |
:dropdownMatchSelectWidth="true" | 下拉菜单和选择器同宽 |
:filter-option="filterOption" | 对输入的内容进行筛选过滤,filterOption是方法名 |
@change="onCellChange(node.AM, $event)" | 下拉框值改变事件,$event是下拉框已选择的值(包括本次点击选中) |
:showArrow="false" | 是否显示下拉小箭头(我这里写的否,因为我感觉下拉箭头不美观) |
:options="node.AM.staffOptions" | 下拉框中的选项,一般是[{label:姓名,value:1}]格式的 |
:default-value="node.AM.staffChooses" | 已选中的值,一般是[1,2,3]格式的 |
// 下拉框赋值等常规操作就不说了
// 下拉框值改变事件
onCellChange (node, value) {
const dataSource = [...this.queryResult]
// 找到表格中这一行这一个单元格的值
let target
dataSource.forEach(record => {
if (record[node.date][(node.timeInterval === 'AM' ? 'AM' : 'PM')].index === node.index) {
target = record[node.date][(node.timeInterval === 'AM' ? 'AM' : 'PM')]
}
})
if (target) {
// 值替换
target['staffIds'] = value
this.queryResult = dataSource
}
},
// 下拉框搜索过滤
filterOption (input, option) {
return (
option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
)
},
将选中的值显示在一行
<style>
.ant-select-selection--multiple .ant-select-selection__rendered {
margin-left: 5px;
margin-bottom: -3px;
height: auto;
max-height: 30px;
max-width: 200px;
overflow: auto;
overflow-y: hidden;
}
.ant-select-selection--multiple .ant-select-selection__choice {
overflow: initial;
}
.ant-select ul,
.ant-select ol {
display: flex;
}
.ant-select-selection--multiple > ul > li,
.ant-select-selection--multiple .ant-select-selection__rendered > ul > li {
margin-top: 3px;
height: 22px;
line-height: 22px;
font-size: 14px;
width: auto;
max-height: 200px;
}
.ant-select-search--inline .ant-select-search__field__wrap {
max-width: 50px !important;
}
.ant-select-selection__rendered::-webkit-scrollbar {
height: 5px;
}
.ant-select-selection__rendered::-webkit-scrollbar-thumb {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
background: lightskyblue;
}
.ant-select-selection__rendered::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, .1);
border-radius: 10px;
background: #ededed;
}
</style>
三:a-table表格的行列合并
效果
代码
表头列合并
columns = {
title: node.date,
dataIndex: node.date,
key: node.date,
width: 260,
children: [
{
title: '上午',
dataIndex: node.date,
key: node.AM,
width: 130,
scopedSlots: { customRender: 'editMorning' }
},
{
title: '下午',
dataIndex: node.date,
key: node.PM,
width: 130,
scopedSlots: { customRender: 'editAfternoon' }
}
]
}
表头列合并的关键就是这个 children 字段。
行合并
// data中定义
columns: {
title: '生产批号/任务编号',
width: 100,
dataIndex: 'taskName',
key: 'taskName',
fixed: 'left',
customRender: (text, record, index) => {
const obj = {
children: text !== null ? text : '',
attrs: {}
}
obj.attrs.rowSpan = this.mergeCells(text, this.queryResult, 'taskName', index)
return obj
}
}
// methods中定义,合并表格
mergeCells (text, data, key, index) {
// 上一行该列数据是否一样
if (index !== 0 && text === data[index - 1][key]) {
return 0
}
let rowSpan = 1
// 判断下一行是否相等
for (let i = index + 1; i < data.length; i++) {
if (text !== data[i][key]) {
break
}
rowSpan++
}
return rowSpan
},
四:DatePicker 日期选择框和Calendar日历的使用
日期选择器的赋值与取值
效果
实现方式
如图所示日期选择框的实现代码如下所示 html代码如下:
<a-date-picker v-model="form.taskStartAt" :format="dateFormat" style="width: 100%" />
js代码如下
import moment from 'moment'
import 'moment/locale/zh-cn'
moment.locale('zh-cn')
export default {
data () {
return {
form: {
taskStartAt: null
}
}
},
methods: {
async init (record) {
// ...
// 赋值
this.form.taskStartAt = moment(record.taskStartAt, 'YYYY-MM-DD')
},
submit () {
//取值
const taskStartAt = this.form.taskStartAt.format('YYYY-MM-DD')
}
}
}
四:日历的实现
效果
实现方式
html
<a-calendar>
<ul slot="dateCellRender" slot-scope="value" class="events">
<li v-for="item in getListData(value)" :key="item.date">
<template v-if="item != null&&item.status === 'WORK'">
<span>
<a-tag color="green">上班</a-tag>
</span>
</template>
<template v-if="item != null&&item.status === 'REST'">
<span>
<a-tag color="red">休息</a-tag>
</span>
</template>
</li>
</ul>
</a-calendar>
js
import moment from 'moment'
import 'moment/locale/zh-cn'
moment.locale('zh-cn')
export default {
data () {
return {
calendarDataList: []
}
},
methods: {
async init () {
// 以下的值是模拟的,真实的值可以从后台取
const scheduleList = [
{scheduleDate: "2021-07-01", status: "WORK"},
{scheduleDate: "2021-07-02", status: "WORK"},
{scheduleDate: "2021-07-03", status: "REST"},
{scheduleDate: "2021-07-04", status: "REST"},
{scheduleDate: "2021-07-05", status: "WORK"}
]
this.calendarDataList = scheduleList
})
},
getListData (value) {
const listData = []
this.calendarDataList.forEach(node => {
if (node.date === value.format('YYYY-MM-DD')) {
listData.push(node)
}
})
return listData || []
}
}
}