最近在搞 Web 项目,用到 Vue ElementUI ,碰到了一些看似很简单的页面功能然后在实际开发中遇到了各种奇奇怪怪的问题,由于自己也是个Web方面的技术小白,就在这里把遇到的问题记录下来,方便自己回顾,也方便大家遇到相同问题的时候可以参考。

先说一下产品需求:
在一个表格中,车辆属性一栏有保存变更记录的数据,用“标签”标记,当鼠标悬停时显示变更记录,如下图:

当看到这个需求的时候觉得没有问题,小意思了,分分钟就可以搞定的。
当时脑子里想到的方法就是使用 el-table+el-popover , 通过解读官方文档也发现Popover非常符合要求。Popover的属性和Tooltip很类似都是弹出提示,如果是固定提示内容的话,使用Tooltip就可以了,但是这里我们需要从后台接口获取数据再更新,所以用Popover更合适,Popover有@show事件,当提示内容hover时,可以触发@show回调,这个时候去请求接口获取数据。
官方文档:

<template> 
    <el-popover 
        placement="top-start" 
        title="标题" 
        width="200" 
        trigger="hover" 
        content="这是一段内容,这是一段内容,这是一段内容,这是一段内容。"> 
        <el-button slot="reference">hover 激活</el-button> 
    </el-popover>
  </template>

好了,万事俱备只欠码代码,快速的把代码搞出来:

<el-table-column
  :align="center"
  label="车辆属性">
  <template slot-scope="scope">
  <div>  {{ scope.row.vehicleProperty == '0' ? '社会车辆' : scope.row.vehicleProperty == '1'? '自有车辆':'--' }}
    <el-popover
        placement="right"
        width="600"
        trigger="hover"
        @show="getTipData(scope.row, scope.$index)">
        <el-table
            v-if="scope.row.gridData"
            :data="scope.row.gridData">
            <el-table-column
                width="150"
                property="vehicleNo"
                label="车牌号"/>
            <el-table-column
                width="150"
                label="操作">
                <template slot-scope="scope">
                    {{ scope.row.opration == '0'? '移除常用车': scope.row.opration == '1'?'添加常用车' : '--' }}
                </template>
            </el-table-column>
            <el-table-column
                width="300"
                property="oprationTime"
                label="时间"/>
        </el-table>
            v-if="scope.row.ownFlag == '1'"
            slot="reference"
            class="el-icon-warning"
    </el-popover>
  </div>
  </template>
  </el-table-column>

完事,运行!
等待运行结果是最激动人心的时刻,仿佛又回到了考完试听成绩的时候~
终于,鼠标滑动到标签hover,变更记录和预想的一样成功显示出来了!!!
等下,别着急欢腾,问题马上来了

问题:table一般都是配合分页来使用的,当第一页第一条数据有标签,即第一条数据:scope.row.ownFlag == '1',这个时候第一页第一条数据标签是正常能hover出现变更记录的;当翻页后,第二页第二条数据是scope.row.ownFlag == '1'有标签,这个时候hover变更记录怎么也显示不出来;返回到第一页,结果第一页第一条数据也hover显示不出来了,标签是在的。

因为本身自己是搞android开发的,在android开发中这种列表会涉及到每个Item样式的复用,技术之间的原理都是相通的,所以联想到会不会这里table中的popover也涉及到复用呢?因为没有为每个popover指定一个key或者id,所以导致复用错乱了。

不知道猜想对不对,那就通过实践来检验一下。
于是,1、给每个popover加上ref
2、其次将判断条件v-if加到这里,v-if是先判断再创建的,当不满足if条件时,本身这个popover就不会创建,也就不存在复用的问题了。

<el-popover
    v-if="scope.row.ownFlag == '1'"
    :ref="`node-${scope.row.id}`"
    placement="right"
    width="600"
    trigger="hover"
    @show="getTipData(scope.row, scope.$index)">
    <el-table
        v-if="scope.row.gridData"
        :data="scope.row.gridData">
        <el-table-column
            width="150"
            property="vehicleNo"
            label="车牌号"/>
        <el-table-column
            width="150"
            label="操作">
            <template slot-scope="scope">
                {{ scope.row.opration == '0'? '移除常用车': scope.row.opration == '1'?'添加常用车' : '--' }}
            </template>
        </el-table-column>
        <el-table-column
            width="300"
            property="oprationTime"
            label="时间"/>
    </el-table>
        v-if="scope.row.ownFlag == '1'"
        slot="reference"
        class="el-icon-warning"
</el-popover>

代码更改完毕,喜大普奔运行结果符合预期。
虽然这个结果不是官方给的答案,但是经过一系列的猜测和实验,至少证明这个方式是可行的。

  • 最近两周出去面试遇到的面试题(前端初级、长更)
  •