el-table实现批量操作和表情显示

前言

大家好,这里是藤原豆腐-前端分店。店主是初入职场的前端小白,将在记录开发生涯的技术文章,刚好今天有时间摸鱼,记录一下后台开发使用el-table组件一些技术点,作为我的第一篇文章。后面还会继续更新小程序的弹幕和瀑布流的实现,如果感兴趣的话,麻烦点点关注!

文字的展开收起

第一个是实现文字的展开收起,这一块要求以下三点

  • 文字超出两行就显示展开按钮在末尾,同时隐藏溢出的文字
  • 点开展开就显示完全
  • 点击收起隐藏溢出文字

<el-table-column prop="content" label="内容" width="198">

    <template slot-scope="scope">
        <div class="text" :class="{ mhNone: isShow[scope.$index] == 2,fontEmoji: system=='windows' }">
            <span v-show="isShow[scope.$index] == 1" class="open" @click="open(scope)">展开</span>
            <span>{{ scope.row.content }}</span>
            <span v-show="isShow[scope.$index] == 2" class="putAway" @click="putAway(scope)">收起</span>
        </div>
    </template>
</el-table-column>

首先在data中定义数组isShow来判断显示展开、收起或者隐藏按钮,同时通过watch监听tableData数据的变化(切换下一页或者搜索时),当tableData数据的变化时,获取.text的dom数组,计算每一个数据项的行数,行数大于2就显示展开按钮。

data(){

  return{

    tableData: [],//接口返回的表格数据
    isShow: [], // 0:隐藏按钮,1:显示展开按钮,2:显示收起按钮
  }
},
watch: {
  tableData: {
      handler() {
          this.$nextTick(() => {
              const lineHeight = 21;
              const list = document.querySelectorAll(".text");
              for (let i = 0; i < list.length; i++) {
                  const line = list[i].scrollHeight / lineHeight;
                  if (line > 2) {
                      Vue.set(this.isShow, i, 1);
                  } else {
                      Vue.set(this.isShow, i, 0);
                  }
                 
              }
          });
      },
      immediate: true,
      deep: true,
  },
},

上面的代码判断是否显示展开按钮,接下来就要实现展开和收起的功能了,给展开跟收起按钮分别绑定点击事件,点击时切换isShow[i]的值

// 展开
open(scope) {
  Vue.set(this.isShow, scope.$index, 2);
},
// 收起
putAway(scope) {
  Vue.set(this.isShow, scope.$index, 1);
},

当然这一块最为关键的还是css的实现,这里通过max-height设定显示的最大高度,这里的行高为1.5,max-height设置3em代表显示两行,同时再通过overflow:hidden隐藏溢出的内容

.text {
  overflow: hidden;
  line-height: 1.5;
  max-height: 3em;
}

点击展开时,对应的isShow的值改为2,这里通过:class动态添加mhNone的类名,mhNone将max-height设置为none,无最大高度限制

<div class="text" :class="{ mhNone: isShow[scope.$index] == 2"></div>
.mhNone {
    max-height: none;
}

最后需要调整展开按钮的位置,把它显示在第二行的末尾,我们最先想到的肯定是设置右浮动

 .open {
        float: right;
        color: #2e6bd3;
  }

的确是在末尾显示,但只显示在第一行,想要显示在第二行末尾,可以给.text添加一个::before的伪元类,伪元素设置右浮动,高度设置为一个行高,宽度先随便设置一个值,方便调试。

.text::before {

  content: "";
  float: right;
  width: 5px;
  height: 21px;
  background: red;
}

再清除展开按钮浮动属性

.open {
    float: right;
    color: #2e6bd3;
    clear: both;
    cursor: pointer;
}

现在它就显示在第二行末尾了,这里可以通过调整伪元类的高度来调整展开按钮显示在哪一行,最后再把width设为0

.text::before {

    content: "";
    float: right;
    width: 0px;
    height: 21px;
    background: red;
}

到这里就实现了我们想要的效果(◦˙▽˙◦)

适配低版本系统的emoji显示

这里需要显示小程序发的带表情的评论,在测试过程中,发现win7系统下的浏览器无法正常显示emoji,会出现黑白emoji或者是完全显示不出来的情况,网上查阅原因后发现Windows 7系统需要更新补丁包才能正常显示。除了更新补丁包,前端这边可以通过引入字体包来适配低版本系统用户的表情显示

这里推荐使用google的noto-emoji,字体文件大概在10Mb以内,NotoColorEmoji.ttf下载地址,像平常一样引用web字体,然后为需要显示emoji的元素指定字体即可,或者可以设置给body,具体实现如下

@font-face {
    font-family: "NotomojiColor";
    src: url("./font/NotoColorEmoji.ttf") format("truetype");
    font-display: swap;
 }

这里的src需要改成相对于你项目的地址

在页面中引入该css,这里通过font-family设置了多个字体,可以避免数字也变成emoji

@import "../style/fix-emoji.css";
.fontEmoji {
    font-family: microsoft yahei, NotomojiColor;
}

样式的部分搞定了,接下来需要判断系统类型,只在window系统下加这个样式。

data(){

  return{

    system: "", //系统名
  }

}

created() {
    this.system = this.detectOS();
},

methods:{
// 判断当前系统类型
  detectOS() {
      var system = navigator.userAgent.toLowerCase();
      //判断android ios windows
      var android = system.indexOf("android");
      var iphone = system.indexOf("iphone");
      var ipad = system.indexOf("ipad");
      var windows = system.indexOf("windows")
      var isMac = /macintosh|mac os x/i.test(navigator.userAgent);
      if (android !== -1) {
          return "android";
      }
      if (iphone !== -1 || ipad !== -1 || isMac) {
          return "ios";
      }
      if (windows !== -1) {
          return "windows";
      }
      return "other";
  }
}

在created时调用这个方法,将值赋值给system,在需要显示的地方通过:class动态添加样式

<el-table-column prop="content" label="内容" width="198">

  <template slot-scope="scope">
    <div class="text" :class="{ mhNone: isShow[scope.$index] == 2,fontEmoji: system=='windows' }">
      <span v-show="isShow[scope.$index] == 1" class="open" @click="open(scope)">展开</span>
      <span>{{ scope.row.content }}</span>
      <span v-show="isShow[scope.$index] == 2" class="putAway" @click="putAway(scope)">收起</span>
    </div>
  </template>
</el-table-column>

表格的批量操作

这里表格需要支持批量操作,实现多选需要手动添加一个el-table-colum,设type属性为selection,同时添加这段js代码即可;

<el-table ref="multipleTable" :data="tableData" sortable="disabled" @selection-change="handleSelectionChange">
	<el-table-column type="selection" width="55"> </el-table-column>
</el-table>


data(){
  return{
		multipleList: [], // 多选框选中列表
  }
}
method:{
  // 控制多选框
  handleSelectionChange(val) {
      this.multipleList = val.map((item) => {
          return parseInt(item.id);
      });
  },

}

到这里只是第一步,table表单通常都会做分页处理,这里切换分页时需要保持其他页码数据的勾选状态不变。解决上诉问题需要用到table组件中的两个属性,下面是ElementUI文档对这两个属性的解释

这里给el-table添加:row-key=”getRowKey”,同时给多选框加上reserve-selection参数,用于保留勾选状态。

<el-table ref="multipleTable" :data="tableData" sortable="disabled" :row-key="getRowKey">
	<el-table-column type="selection" :reserve-selection="true" width="55"> </el-table-column>
</el-table>
method:{
  getRowKey(row) {
    	return row.id;
  },
}

接下来产品又提了个需求,这里的数据项有三种状态,只有待审核的数据项才启用多选框,其他两种情况禁用多选框。(抓狂?)

这里给el-table-column添加:selectable=”selectEnable”,通过获取数据项的状态来控制是否禁用

<el-table ref="multipleTable" :data="tableData" style="width: 100%; border: 1px solid #e6e6e6" sortable="disabled" :row-key="getRowKey" @selection-change="handleSelectionChange">
  <el-table-column type="selection" :reserve-selection="true" width="55" > </el-table-column>
</el-table>

method:{
 // 多选框是否可选
  selectEnable(row, index) {
      if (row.status == 0) {
          return true; // 不禁用
      } else {
          return false;
      }
  },
}

在点击批量操作后,将多选状态清空

// 批量审核通过
batchPass() {
  if (this.multipleList.length == 0) {
    alert("请先选择数据");
    return;
  }
  this.batchReview(1, this.multipleList);//	调用审核接口
  this.$refs.multipleTable.clearSelection(); //	清空表格选项
},

到这里基本就实现了多选框的禁用,但还有个问题,每一个数据项都可以进行操作,在勾选情况下对单个数据进行审核,会出现表单项状态变了,多选框也禁用了,但勾选状态没有变。(抓狂X2)

处理这种情况,需要在单项审核时,通过toggleRowSelection取消当前行的勾选状态

 // 单项审核
  onePass(scope, type) {
      this.idList = [];
      this.idList.push(parseInt(scope.row.id));
      this.batchReview(type, this.idList);
      if (type == 0) {
          // 取消审核不需要去除勾选状态
      } else {
          // 将当前行的勾选状态取消
          this.multipleList.forEach((item) => {
              if (item == parseInt(scope.row.id)) {
                  this.$refs.multipleTable.toggleRowSelection(this.tableData[scope.$index], false);
              }
          });
      }
  },

到这里总算实现了表单的批量操作!???

写在最后

看到这里的同学如果觉得文章还不错,可以给我点个赞吗???如果有什么建议,欢迎在评论区中交流。

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYwTAUWj' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片