有一个table,某一列渲染数据是可查看的,点击当前单元格,弹出模态框,模态框为子组件,table在父组件中,模态框渲染从父组件获取的数据,框架为vue
父组件
html
<template>
<el-container v-loading.body="listLoading" class="app-container">
<el-header class="header-plane" height="auto">
<el-form :inline="true" class="demo-form-inline">
<el-form-item label="报警类型">
<el-popover placement="bottom"
width="250">
<menu-type-tree ref="menuType" v-if="menus.length" selectedAll
style="height: 300px; overflow: auto"
:treeMenuData="menus"
:treeMenuProp="defaultProps"
:checkedKeys="defaultChecked"
@check-change="handleNodeChange"></menu-type-tree>
<el-input slot="reference"
placeholder="请选择报警类型"
v-model.trim="alarmTypeName"
style="width:150px;"
size="small" readonly></el-input>
</el-popover>
<span style="font-size: 14px">已选择{{count}}种</span>
</el-form-item>
<el-form-item>
<select-car-single ref="selectCarSingle" @selectedCar="selectedCar"></select-car-single>
</el-form-item>
<el-form-item label="处理状态">
<el-select v-model.trim="tableQuery.status"
placeholder="请选择"
style="width:90px;"
size="small">
<el-option v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="查询时间">
<data-pickers-day ref="dataPickers" @startEnd="checkDate"></data-pickers-day>
</el-form-item>
<el-form-item>
<el-button type="primary"
size="mini"
@click="initPage">查询
</el-button>
<el-button type="primary"
size="mini"
@click="resetPage">重置
</el-button>
<export-modular url="/statistical/excel" :totals="total" :params="exportParams" :parameter="exportFileName" file-type=".xls"></export-modular>
</el-form-item>
</el-form>
</el-header>
<el-main>
<charts :chartData="chartData"
:legendData="legendData" showCard
titleText='整车三电报警处理统计'
:stateIndex="stateIndex" chartType="bussinessBar" subText="处理数"
ref="bar"
:ratio=0.97 ></charts>
<el-fixed-height-table :tableData="tableData" class="main-table"
:pageSize="tableQuery.limit" :currentPage="tableQuery.page"
:columns="columns" border stripe>
<template slot="formatterTpl" slot-scope="scope">
<el-button v-if="scope.column.key === 'alarmType'" class="btn-text" type="text" @click="handleDetail(scope, tableData)">{{scope.rowData.row[scope.column.key]}}</el-button>
<span v-else-if="scope.column.key === 'handlerType'" v-text="handlerTypeformatter(scope.rowData.row[scope.column.key])"></span>
<span v-else-if="scope.column.key === 'Status'" v-text="handlerStatusformatter(scope.rowData.row[scope.column.key])"></span>
<span v-else-if="scope.column.formatter">{{scope.column.formatter(scope.rowData.row,scope.column.key,scope.rowData.row[scope.column.key])}}</span>
<span v-else>{{scope.rowData.row[scope.column.key]}}</span>
</template>
</el-fixed-height-table>
<!-- 分页区 -->
<el-pagination class="pagination-plane" background
@size-change="handleSizeChange"
@current-change="handleChange"
:current-page="tableQuery.page"
:page-sizes="[10, 20, 30, 50, 100, 300, 500]"
:page-size="tableQuery.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</el-main>
<!-- 模态框组件 通过父子传值从父组件获取数据 -->
<alarm-info ref="alarmMapInfo" :dialogTitle="dialogTitle" :is-show="isAalarm" @close="closeAlarm"
:getdata="tableData" :recordId="recordId"></alarm-info>
</el-container>
</template>
js代码
<script>
import mixins from '@/common/mixins'
import { getWarningTypes, getStatistical, getStatisticalCharts } from '@/api/report/reportApi'
import BMap from 'BMap'
import _ from 'lodash'
export default {
mixins: [mixins],
data() {
return {
btnType: 1,
menus: [],
count: 0,
alarmTypeName: '',
tableQuery: {
page: 1,
limit: 10,
alarmType: '',
plateNo: '',
startTime: '',
endTime: '',
status: ''
},
defaultChecked: [],
defaultProps: {
children: 'children',
label: 'label'
},
options: [
{
label: '全部',
value: ''
},
{
label: '已处理',
value: '1'
},
{
label: '未处理',
value: '0'
}
],
chartQuery: {
startTime: '',
endTime: '',
alarmType: '',
plateNo: '',
status: ''
},
legendData: ['已处理', '未处理'],
stateIndex: undefined,
allotDialogVisible: false,
tableData: [],
total: 0,
selectCars: [], // 已选择车辆
chartData: [],
data: [],
columns: [
{
key: 'plateNo',
title: '车牌号',
width: '150'
},
{
key: 'deptName',
title: '所属机构',
width: '150'
},
{
key: 'driver',
title: '司机',
width: '100'
},
{
key: 'phone',
title: '联系电话',
width: '200'
},
{
key: 'alarmType',
title: '报警类型',
width: '250'
},
{
key: 'alarmTime',
title: '报警时间',
width: '200'
},
{
key: 'handlerTime',
title: '处理时间',
width: '200'
},
{
key: 'Status',
title: '处理状态',
width: '100'
},
{
key: 'delay',
title: '处理时长',
width: '200'
},
{
key: 'handlerUser',
title: '处理用户',
width: '100'
},
{
key: 'handlerType',
title: '处理方式',
width: '150'
},
{
key: 'content',
title: '处理内容',
width: '400'
},
{
key: 'address',
title: '报警位置',
width: '400'
}
]
}
},
computed: {
exportParams() {
return {
startTime: this.tableQuery.startTime,
endTime: this.tableQuery.endTime,
alarmType: this.tableQuery.alarmType,
plateNo: this.tableQuery.plateNo,
status: this.tableQuery.status
}
},
exportFileName() {
return '整车三电报警处理统计' + this.tableQuery.startTime + '-' + this.tableQuery.endTime
}
},
async mounted() {
await this.getWarningTree()
// 初始化查询
// await this.initPage()
},
methods: {
/**
* 获取预警类型
* @returns {Promise<void>}
*/
async getWarningTree() {
const result = await getWarningTypes()
this.menus = [
_.get(result, 'data.整车三电报警')
]
const types = []
await this.initDefaultTypes(this.menus, types)
this.tableQuery.alarmType = types.join()
this.chartQuery.alarmType = types.join()
},
/**
* 预警类型的选择change方法
* @param val
*/
handleNodeChange(val) {
const codes = []
const labels = []
this.count = val.length
val.forEach(item => {
codes.push(item.code)
labels.push(item.label)
})
this.tableQuery.alarmType = codes.join()
this.chartQuery.alarmType = codes.join()
this.alarmTypeName = labels.join()
// 动态列
},
// 初始化页面
async initPage() {
this.listLoading = true
const the = this
if (_.isEmpty(_.get(the, 'tableQuery.alarmType'))) {
this.$message({
message: '至少选择一种预警类型',
type: 'warning',
duration: '1500'
})
this.listLoading = false
return false
}
this.tableQuery.page = 1
this.tableQuery.limit = 10
await this.initTableList()
await this.initCharts()
this.listLoading = false
},
resetPage() {
this.$refs.selectCarSingle.clearSelected()
this.$refs.menuType.selectAll()
this.tableQuery.page = 1
this.tableQuery.limit = 10
this.tableQuery.plateNo = ''
this.tableQuery.status = ''
this.chartQuery.plateNo = ''
this.$refs.dataPickers.resetDate()
},
selectedCar(id) {
this.tableQuery.plateNo = id
this.chartQuery.plateNo = id
},
// 初始化列表
async initTableList() {
const result = await getStatistical(this.tableQuery)
this.tableData = _.get(result, 'data.rows')
this.total = _.get(result, 'data.totalCount')
await this.initAddress()
},
// 调用百度地图API 翻译 address
async initAddress() {
var the = this
var theTableData = the.tableData
_.forEach(theTableData, function(v, i) {
const point = new BMap.Point(
_.get(v, 'longitude'),
_.get(v, 'latitude')
)
new BMap.Geocoder().getLocation(point, function(rs) {
the.$set(the.tableData[i], 'address', rs.address)
})
})
},
// 初始化图表
async initCharts() {
this.chartData = []
const the = this
var status = _.get(the.tableQuery, 'status')
this.stateIndex = _.eq(status, '1') ? 0 : (_.eq(status, '0') ? 1 : undefined)
const chartDatas = await getStatisticalCharts(this.chartQuery)
_.forEach(_.get(chartDatas, 'data'), function(v, i) {
the.chartData.push([_.get(v, 'startTime'), [_.get(v, 'hendlerNumber'), _.get(v, 'nohendlerNumber')]])
})
this.$refs['bar'].drawChart()
},
handleSizeChange(val) {
this.tableQuery.limit = val
this.initTableList()
},
handleChange(val) {
this.tableQuery.page = val
this.initTableList()
},
handlerStatusformatter(n) {
switch (n) {
case 0:
return '未处理'
case 1:
return '已处理'
}
}
},
watch: {
tableQuery: {// 深度监听,可监听到对象、数组的变化
handler(val, oldVal) {
this.chartQuery.status = val.status
},
deep: true
}
}
}
</script>
其中表格中预警类型这一列的点击事件为全局注册的一个通用方法,如下
// 点击查看详情
// 参数row从表格中传递过来,为当前行所有数据集,包括当前行在整个table数据集合中的位置 $index
handleDetail(row) { // 预警详情
console.log(row)
debugger
var indexId = row.rowData.$index
console.log('--------预警详情 当前点击对象在数组中的位置--------')
console.log(indexId)
// recordId赋值
this.recordId = _.get(row.rowData.row, 'id')
console.log('预警类型 当前点击的对象的id')
console.log(this.recordId)
if (_.get(row.rowData.row, 'device_type') === 'VEHICLE_QH_ADAS') {
this.deviceTypes = false
} else {
this.deviceTypes = true
}
// this.deviceTypes = _.get(row, 'device_type') === 'VEHICLE_QH_ADAS' ? 'false' : 'true'
const the = this
if (!_.isEmpty(the.recordId)) {
// this.$store.commit('SHOW_ALARM', true)
this.dialogTitle = _.get(row.rowData.row, 'plateNo')
this.$nextTick(() => {
this.$refs['alarmMapInfo'].getRecordInfo()
})
this.isAalarm = true
}
}
我在子组件alarm-info中编写的方法如下
// 子组件中部分data数据
data() {
return {
getnext: false,
code: 0,
rowIndex: 0,
num: 0, // 下一页点击次数
befornum: 0, // 上一页点击次数
fullscreenLoading: false,
currentPageData: [], // 表格中当前页面数据
}
// 点击方法如下
// 上一页
beforePage(befornum) {
console.log('上一页')
// debugger
if (this.befornum !== 0) {
if (this.rowIndex === 0) { // this.currentPageData.length
const getdate = this.currentPageData[this.currentPageData.length - 1].id
this.recordId = getdate
this.rowIndex = this.currentPageData.length - 1
} else {
const getdate = this.currentPageData[this.rowIndex - 1].id
this.recordId = getdate
console.log('333333333333333333333333333333333')
console.log(this.recordId)
this.rowIndex = this.rowIndex - 1
}
} else {
// 上一页按钮的第一次点击事件 只执行一次
for (var i = 0; i < this.currentPageData.length; i++) {
if (this.recordId === this.currentPageData[i].id) {
if (i === 0) { // this.currentPageData.length
const getdate = this.currentPageData[this.currentPageData.length].id
this.recordId = getdate
this.rowIndex = this.currentPageData.length
} else {
const getdate = this.currentPageData[i - 1].id // 有疑问 this.rowIndex
this.recordId = getdate
this.rowIndex = i - 1
}
break
}
}
}
this.$nextTick(() => {
this.getRecordInfo()
})
this.befornum = 1
},
// 下一页
nextPage(num) {
setTimeout(function() {
this.getnext = true
}, 1500)
// console.log('下一页')
if (this.num !== 0) {
console.log('第二次点击')
console.log(this.rowIndex)
if (this.currentPageData.length === this.rowIndex) {
const getdate = this.currentPageData[0].id
this.recordId = getdate
this.rowIndex = 0
} else {
const getdate = this.currentPageData[this.rowIndex + 1].id
this.recordId = getdate
console.log(this.recordId)
this.rowIndex = this.rowIndex + 1
}
} else {
// 下一页按钮的第一次点击事件 只执行一次
for (var i = 0; i < this.currentPageData.length; i++) {
if (this.recordId === this.currentPageData[i].id) {
if (i === this.currentPageData.length - 1) {
const getdate = this.currentPageData[0].id
this.recordId = getdate
this.rowIndex = 0
} else {
const getdate = this.currentPageData[i + 1].id // this.rowIndex
this.recordId = getdate
console.log('第一次点击')
console.log('当前id')
console.log(this.currentPageData[i].id)
console.log('下一个的id')
console.log(this.recordId)
this.rowIndex = i + 1
console.log('下一个的rowIndex')
console.log(this.rowIndex)
}
break
}
}
}
this.$nextTick(() => {
this.getRecordInfo()
})
this.getnext = false
this.num = 1
}
这里面应用到的一个数据渲染的方法,如下
// 该方法为异步执行的方法
async getRecordInfo() {
this.currentPageData = this.getdata
console.log('父组件穿过来的数据')
console.log(this.currentPageData)
if (isEmpty(this.recordId)) {
return false
}
await this.getMsg().catch(function(e) {
this.reload()
})
const result = await getRecordInfoById(this.recordId)
if (result.code === 0) {
this.monInfo = result.data
if (this.monInfo.mediaUrl) {
this.deviceTypesPl = true
}
this.realTimeData = JSON.parse(result.data.realTimeData)
if (this.realTimeData.tyreData) {
this.TyreData = this.realTimeData.tyreData
}
if (parseInt(result.data.handlerType) !== 0) {
this.isHandle = true
}
if (this.isDisable) {
this.isHandle = true
}
if (!this.deviceTypes) {
this.deviceTypesPl = true
}
this.mapInit.lat = result.data.latitude
this.mapInit.lng = result.data.longitude
this.markerInfo.platNo = result.data.plateNo
this.markerInfo.speed = result.data.speed
this.markerInfo.time = result.data.alarmStart
this.markerInfo.street = result.data.alarmAddress
this.$nextTick(() => {
this.isReady = true
this.isShow = true
})
this.waterPumpData = this.realTimeData.waterPumpData
} else {
this.$message.error(result.msg)
}
}
之前想要查看需要点击预警类型,弹出模态框查看,后关闭模态框,再点击下一个,
我实现的功能就是在不关闭模态框的前提下点击上一个或者下一个,依次查看预警类型。
上面图片为项目具体功能效果。
编写本方法过程中遇到的问题如下:
1 ,props高级定义方法
2,lodash工具库
官方文档见: https://www.lodashjs.com/
vue使用见 : https://www.jianshu.com/p/907e8a0ee5d7
3,vue nextTick方法(DOM异步更新)
详见vue官方文档: https://cn.vuejs.org/
或简书作者 : https://www.jianshu.com/p/a7550c0e164f
44444444444444, 非常重要的一点,虽然功能是实现了,但是有一个未解决的问题,希望大神指正,
问题: https://blog.csdn.net/u014520745/article/details/75455979