开发记录(切换上一页下一页)

有一个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

猜你喜欢

转载自blog.csdn.net/lwx931449660/article/details/88182332