记录使用 element 过程中遇到的一些需求

在 github 上搭建自己的博客(参考资料):https://zhuanlan.zhihu.com/p/28321740

elementui tab标签管理路由页面:点我查看参考资料

1、vue+element 实现长度显示为 “…” 和 移动到文字上方显示详情 【使用自定义指令】

在这里插入图片描述

<el-table-column label="问卷名称" align="center">
  <template slot-scope="scope">
    <el-tooltip class="item" effect="dark" :content="scope.row.questionnaireName" placement="bottom-start">
      <span>{{ scope.row.questionnaireName | ellipsis }}</span>
    </el-tooltip>
  </template>
</el-table-column>
export default {
  // 超过8个字符隐藏后面的
  filters: {
    ellipsis(value) {
      if (!value) return ''
      if (value.length > 8) {
        return value.slice(0, 8) + '...'
      }
      return value
    }
  },
}

备注:
(1)el-table中使用el-popover点击取消按钮时popover框的显示与隐藏问题:https://blog.csdn.net/gladysdrea/article/details/110441891
(2)https://www.jianshu.com/p/598f0017ce8a

2、element 表格行 hover事件

<el-table :data="tableData" style="width: 100%" @cell-mouse-enter="enter" @cell-mouse-leave="leave">
</el-table>
enter(row, column, cell) {
  console.log(row)
},
leave(row,column,cell) {
	console.log(row)
}

3、表格的下拉滚动 触底加载

参考1:https://www.cnblogs.com/tabai/p/13552612.html
参考2:https://www.jb51.net/article/159033.htm

在 main.js 文件中注册全局事件:自定义指令 loadmore
解释:

scrollHeight:指元素的总高度,包含滚动条中的内容。只读属性。不带px单位。
scrollTop:当元素出现滚动条时,向下拖动滚动条,内容向上滚动的距离。可读可写属性。不带px单位。
clientHeight:元素客户区的大小,指的是元素内容及其边框所占据的空间大小,实际上就是可视区域的大小。
滚动条滚到底部的时候: scrollHeight-scrollTop-clientHeight=0
//表格滚动加载(自定义指令)
Vue.directive('loadmore', {
  bind(el, binding) {
    let p = 0
    let t = 0
    let down = true
    let selectWrap = el.querySelector('.el-table__body-wrapper')
    selectWrap.addEventListener('scroll', function() {
      //判断是否向下滚动
      p = this.scrollTop // if ( t < p){down=true}else{down=false}
      if (t < p) {
        down = true
      } else {
        down = false
      }
      t = p //判断是否到底
      const sign = 10
      const scrollDistance = this.scrollHeight - this.scrollTop - this.clientHeight
      if (scrollDistance <= sign && down) {
        binding.value()
      }
    })
  }
})

使用:在 template 中 v-loadmore="publicLoading"

<el-table
  :data="quotations"
  border
  v-loadmore="publicLoading"
  v-loading="loading_3"
  element-loading-text="拼命加载中"
  element-loading-spinner="el-icon-loading"
  style="width: 100%"
  :header-cell-style="headerBorder"
  :height="clientHeight"
  :row-style="tableLineHeight"
  :cell-style="borderleft1"
  @cell-mouse-enter="enter"
  @cell-mouse-leave="leave"
>
</el-table>

在data中定义当前页数 和总页数

data(){
	return{
		publicPage:0, //当前页数
		publicTotalPage:0 //总页数
	}
}

在 methods函数中:
注意:如果懒加载不能触发,则看一下第一页的数据是否将表格充满,固定表格高度,当数据充满表格时才可以滑动表格内容区

publicLoading() {
  // 当前页数 小于 总页数
  if (this.publicPage < this.publicTotalPage) {
    this.publicPage++
    this.loading_3 = true
    //调用请求
    this.getPublicGoodsList()
  } else {
    return false
  }
}

3-补充:select下拉框懒加载

目标:解决 Element-ui中 选择器(Select)因options 数据量大导致渲染慢、页面卡顿的问题
参考1:https://blog.csdn.net/ZYS10000/article/details/111822862
参考2:https://www.cnblogs.com/greatdesert/p/11696744.html
实现:
在main.js 中全局定义

// el-select下拉框数据懒加载
Vue.directive('el-select-loadmore',{
	bind(el, binding) {
    // 获取element-ui定义好的scroll盒子
    const SELECTWRAP_DOM = el.querySelector(
      ".el-select-dropdown .el-select-dropdown__wrap"
    );
    SELECTWRAP_DOM.addEventListener("scroll", function () {
      /**
       * scrollHeight 获取元素内容高度(只读)
       * scrollTop 获取或者设置元素的偏移值,常用于, 计算滚动条的位置, 当一个元素的容器没有产生垂直方向的滚动条, 那它的scrollTop的值默认为0.
       * clientHeight 读取元素的可见高度(只读)
       * 如果元素滚动到底, 下面等式返回true, 没有则返回false:
       * ele.scrollHeight - ele.scrollTop === ele.clientHeight;
       */
      // const condition = this.scrollHeight - this.scrollTop  <= this.clientHeight;
      const condition = this.scrollHeight - this.scrollTop - 1 <= this.clientHeight; 
        
      if (condition) {
        binding.value();
      }
    });
  },
})

在 template 中使用:

<el-select
  placeholder="请选择负责人"
  popper-class="myt-select"
  size="mini"
  class="width290"
  v-model="fHandleId"
  @change="getHandleVal"
  v-el-select-loadmore="loadmore"
>
  <el-option
    :label="item.personNameCn"
    :value="item.userId"
    v-for="(item, index) in staffList"
    :key="index"
  ></el-option>
</el-select>

在methods 中调用

data(){
	return{
		formData: {
			pageIndex: 1, // 当前页
			pageSize: 10, // 每页条数
			pages: 0,  // 总页数
		},
	}
},
methods:{
	loadmore() {
	  console.log("触底加载");
	  if (this.formData.pageIndex < this.formData.pages) {
	    this.formData.pageIndex++;
	    this.getPerson(this.chargeUnit, this.formData); // 调用请求
	  }
	},
}

4、列表布局

在这里插入图片描述
实现代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .msgbox-custom {
        position: relative;
        height: 60px;
        padding: 5px 120px 5px 60px;
        border-bottom: 1px solid #e2e2e2;
        margin-bottom: 10px;
      }
      .msgbox-avatar {
        width: 50px;
        height: 50px;
        display: block;
        position: absolute;
        top: 5px;
        left: 0;
        border-radius: 50%;
      }

      .msgbox-user,
      .msgbox-content {
        width: 100%;
        line-height: 25px;
      }
      .msgbox-user span {
        color: black;
      }
      .msgbox-btn {
        position: absolute;
        right: 0;
        top: 10px;
      }
    </style>
  </head>
  <body>
    <div class="msgbox-custom">
      <img src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3649178992,1821853682&fm=26&gp=0.jpg" alt class="msgbox-avatar" />
      <div class="msgbox-user">
        <span>名称</span>
      </div>
      <div class="msgbox-content"><span>内容2333333</span>&nbsp;</div>
      <div class="msgbox-btn">
        <el-button type="primary" size="mini">同意</el-button>
        <el-button size="mini">拒绝</el-button>
      </div>
    </div>
    <div class="msgbox-custom">
      <img
        src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201408%2F24%2F20140824154253_45Hay.png&refer=http%3A%2F%2Fcdn.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1621411740&t=ffd0d8b512381e2f1b79dfa173e92bd0"
        alt
        class="msgbox-avatar"
      />
      <div class="msgbox-user">
        <span>名称</span>
      </div>
      <div class="msgbox-content"><span>内容2333333</span>&nbsp;</div>
      <div class="msgbox-btn">
        <el-button type="primary" size="mini">同意</el-button>
        <el-button size="mini">拒绝</el-button>
      </div>
    </div>
  </body>
</html>

5、文件图片上传 - http-request 自定义上传

上传 excel 表格等其他文件

<el-upload class="avatar-uploader" action="#" :http-request="uploadImg" :show-file-list="false">
  <el-button size="small" type="primary">导入客户Excel表</el-button>
</el-upload>

上传图片

<el-upload v-model="ruleForm.avatar" class="avatar-uploader" action="#" :http-request="uploadImg" :show-file-list="false">
  <img v-if="imageUrl" :src="imageUrl" class="avatar" />
  <i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
uploadImg(file) {
  console.log('上传后的文件', file)
}

6、vue 重复点击路由导航,报错。

在这里插入图片描述
代码如下:

// 解决导航栏中的vue-router在3.0版本以上重复点菜单报错问题
Vue.use(VueRouter)
//获取原型对象上的push函数
const originalPush = VueRouter.prototype.push
//修改原型对象中的push方法
VueRouter.prototype.push = function push(location) {
  return originalPush.call(this, location).catch((err) => err)
}

7、防抖和节流

参考:https://blog.csdn.net/weixin_46016926/article/details/116045455

8、vue 海报:

参考:https://github.com/sunniejs/vue-canvas-poster/tree/0.1.16

9、websocket 实时通信(使用 node 做为服务端): https://github.com/Creator12333/WebSocketChatRoom

10、elementUI — el-select 下拉框样式覆盖

描述:
element UI 组件库中的 select 选择器 中下拉列表的样式,在页面渲染的时候,总是渲染为仅次于body级别的div ,这样子覆盖样子会影响全局其他的select选择器下拉框样式,试图通过给el-select加父标签来覆盖,然而并没有用。
控制台看到的渲染结果:
在这里插入图片描述
解决方法:
通过 popper-class 来自定义一个类,这样子在控制台可以看到,自定义的类渲染到页面上的效果,这样子,你就可以通过自定义的这个类,进行下拉框的样式覆盖了,这样子并不会影响全局了,覆盖样式时,要加 !important 提高优先级。
下面为自定义类后渲染的结果
在这里插入图片描述
在这里插入图片描述

11、element - switch 开关改变文字及按钮样式

原样式:
在这里插入图片描述
修改后
在这里插入图片描述
html代码 - template
1启用 0禁用

<el-table-column label="状态" min-width="6.94%">
  <template slot-scope="scope">
    <!-- :active-value="0" :inactive-value="1" -->
    <el-switch class="my_switch" v-model="scope.row.flag" @change="change(scope.row)" active-text="启用" inactive-text="禁用"> </el-switch>
  </template>
</el-table-column>

css代码

/* switch按钮样式--start */
.my_switch .el-switch__label {
  position: absolute;
  display: none;
  color: #fff !important;
}
/*打开时文字位置设置*/
.my_switch .el-switch__label--right {
  z-index: 1;
}
/* 调整打开时文字的显示位子 */
.my_switch .el-switch__label--right span {
  margin-left: 7px;
  font-size: 12px;
}
/*关闭时文字位置设置*/
.my_switch .el-switch__label--left {
  z-index: 1;
}
/* 调整关闭时文字的显示位子 */
.my_switch .el-switch__label--left span {
  // margin-left: 9px;
  margin-left: 20px;
  font-size: 12px;
}
/*显示文字*/
.my_switch .el-switch__label.is-active {
  display: block;
}
/* 调整按钮的宽度 */
.my_switch.el-switch .el-switch__core,
.el-switch .el-switch__label {
  width: 52px !important;
  height: 20px !important;
  line-height: 17px;
  margin: 0;
}
/* 调整开关圆圈的大小 */
.my_switch .el-switch__core:after {
  content: '';
  position: absolute;
  top: 2px;
  left: 3px;
  border-radius: 100%;
  transition: all 0.3s;
  width: 14px;
  height: 14px;
  background-color: #fff;
}
/* switch按钮样式--end */

12、媒体查询

@media pc端写法:

@media (max-width:1537px) {
    .all_div{
        padding-left: 80px;
    }   
    .all_div .left_logo_con{
        margin-right: 70px;
    } 
}

@media screen and 移动端写法:

@media screen and (max-width:1281px) {  
    .all_div{
        padding-left: 80px;
    }   
    .all_div .left_logo_con{
        margin-right: 70px;
    } 
    .all_div .left_logo_con img{
        width: 447.5px;
        height: 340px;
    }   
}

13、获取 select 下拉框选中内容的 name

// 方法一:
changeCustodian(val) {
  //传进来的val是select组件选中的value值,也就是一个fruitEnName
  var obj = {}
  obj = this.keepersOption.find(function (item) {
    return item.userId === val
  })
  this.custodianName = obj.userName
},
// 方法二:
changeSelectValue(val) {
  var i = 0
  // IE 11 及更早版本不支持 find() 方法
  var selectedList = this.options.filter((item, index) => {
    if (item[this.valueKey] === val) {
      i = index
      return item
    }
  })
  this.$emit('changeSelectValue', val, { item: selectedList[0], index: i })
},

14、表格前端分页

<el-table :data="tableData.slice((currentPage - 1) * pagesize, currentPage * pagesize)" border v-loading="loading" style="width: 100%" :cell-style="isCenter" :header-cell-style="isCenter"></el-table>

<el-pagination
	@size-change="handleSizeChange"
	@current-change="handleCurrentChange"
	:current-page="currentPage"
	:page-sizes="[5, 10, 20, 40]"
	:page-size="pagesize"
	layout="total, sizes, prev, pager, next, jumper"
	:total="tableData.length"
>
</el-pagination>
isCenter({ row, column, rowIndex, columnIndex }) {
	return 'text-align:center'
},
handleSizeChange: function(size) {
	this.pagesize = size //每页下拉显示数据
},
handleCurrentChange: function(currentPage) {
	this.currentPage = currentPage //点击第几页
},

15、数组的一些方法:forEach , map , filter , find

参考:https://blog.csdn.net/wzc_coder/article/details/104057848

16、element组件table里面通过popover嵌套table出现bug

参考:https://segmentfault.com/q/1010000020722534

17、Element-UI (Breadcrumb) 动态面包屑效果

参考:https://blog.csdn.net/JackieDYH/article/details/116752930

18、el-menu 组件:导航菜单中箭头方向问题(对默认的上下进行样式的修改)

参考:https://www.cnblogs.com/star-meteor/p/12719089.html

原先是element-ui中是默认上下
在这里插入图片描述
原代码:

/*菜单打开*/
.el-submenu.is-opened > .el-submenu__title .el-submenu__icon-arrow {
  -webkit-transform: rotateZ(180deg);
  transform: rotateZ(180deg);
}

改为右下
在这里插入图片描述
覆盖原来的样式

//菜单关闭
.el-submenu>.el-submenu__title .el-submenu__icon-arrow{
    -webkit-transform: rotateZ(-90deg); 
    -ms-transform: rotate(-90deg);
    transform: rotateZ(-90deg); 
}
//菜单展开
.el-submenu.is-opened>.el-submenu__title .el-submenu__icon-arrow{
    -webkit-transform: rotateZ(0deg); 
    -ms-transform: rotate(0deg);
    transform: rotateZ(0deg); 
}

19、element-ui 解决el-table表格错位问题

参考:https://blog.csdn.net/qq_35432904/article/details/110181982?spm=1001.2014.3001.5501

20、css修改el-date-picker中placeholder的颜色

参考:https://blog.csdn.net/qq_39218339/article/details/110916724

21、 Object.defineproperty 双向绑定属性**

应用defineProperty简单实现vue的双向数据绑定: https://www.cnblogs.com/junwu/p/7274034.html

Object.defineproperty在vue中的作用:
参考:https://www.jianshu.com/p/93ed87044ad8

应用: 属性保持组件稳定

22、两个页面传值

(1) 在vue中实现简单页面逆传值的方法
参考: https://www.jb51.net/article/129093.htm
(2)详解vuejs几种不同组件(页面)间传值的方式
参考: https://www.jb51.net/article/115152.htm

23、Upload 上传 - 上传图片组件自定义样式

效果:
在这里插入图片描述

<template>
  <div>
    <el-upload
      class="avatar-uploader"
      action="https://jsonplaceholder.typicode.com/posts/"
      list-type="picture-card"
      :on-preview="handlePictureCardPreview"
      :on-remove="handleRemove"
    >
      <div class="con-center">
        <div class="con-pic">
          <i class="el-icon-picture-outline"></i>
        </div>
        <div class="con-text">
          <span>上传图片</span>
        </div>     
      </div>
    </el-upload>

    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="dialogImageUrl" alt="" />
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: "base_search",
  props: ["label", "placeholder"],
  data() {
    return {
      dialogImageUrl: "",
      dialogVisible: false,
    };
  },
  methods: {
    // 上传附件
    handleRemove(file, fileList) {
      console.log(file, fileList);
    },
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
  },
};
</script>

<style scoped>
/* 图片 */
.avatar-uploader >>> .el-upload-list__item {
  width: 100px !important;
  height: 100px !important;
  border-radius: unset;
}
.avatar-uploader >>> .el-upload--picture-card {
  background-color: initial !important;
  border: 1px dashed #6da1c7;
  border-radius: 0px;
  width: 100px !important;
  height: 100px !important;
  line-height: 98px;
  vertical-align: top;
}
.avatar-uploader >>> .el-icon-picture-outline {
  color: #6da1c7;
  line-height: 40px;
  height: 40px;
}

.con-center {
  height: 40px;
  line-height: 40px;
 
}
.con-center .con-text {
  font-size: 14px;
  height: 20px;
  line-height: 20px;
  color: #6da1c7;
  text-align: center;
}

.con-center .con-pic {
 
  height: 36px;
  margin-top: 20px;
}
</style>

24、Upload 上传 - 上传文件组件封装

效果图:在这里插入图片描述
代码:

<template>
  <el-upload
    ref="uploadExcel"
    class="myt-uploader"
    action="#"
    :on-preview="handlePreview"
    :on-remove="handleRemove"
    :before-remove="beforeRemove"
    :on-change="handleChange"
    multiple
    :limit="limit"
    :on-exceed="handleExceed"
    :file-list="fileList"
    :http-request="myUpload"
    :before-upload="beforeAvatarUpload"
  >
    <slot>
      <div class="upload-ctx">
        <el-button class="common-btn" type="primary">{{
          uploadBtnText
        }}</el-button>
        <!-- <span class="tips" @click.stop="">{{ tips }}</span> -->
        <span class="tips" @click.stop="">
          {{ tips }}
          <span
            v-if="fileSuffixType === 'Excel'"
            class="excel-tips"
            @click.stop="uploadTemplate"
          >
            <i class="el-icon-download"></i>
            <!-- <el-link class="common-link">下载模板</el-link> -->
            <span>下载模板</span>
          </span>
        </span>
      </div>
    </slot>
  </el-upload>
</template>

<script>
import commonApi from "@/api/common.js";

export default {
  name: "MytUploader",
  props: {
    fileSuffixType: {
      type: String,
    },
    uploadBtnText: {
      type: String,
      default: "本地上传",
    },
    // tips: {
    //   type: String,
    //   default: "支持图片,文件(doc/docx/pdf),大小不超过10M",
    // },
    // action: {
    //   type: String,
    //   default: 'https://jsonplaceholder.typicode.com/posts/'
    // },
    limit: {
      type: Number,
      default: 10000,
    },
    defaultFileList: {
      type: Array,
      default() {
        return [];
      },
    },
  },

  watch: {
    defaultFileList: {
      deep: true,
      immediate: true,
      handler: function (newValue, oldValue) {
        if (newValue && newValue.length) {
          console.log("监听到上传文件的变化", newValue);
          // this.setFileList();
          this.fileList = newValue;
        }
      },
    },
    fileSuffixType: {
      deep: true,
      immediate: true,
      handler: function (newValue, oldValue) {
        console.log("newVal, oldVal", newValue, oldValue);
        if (newValue === "Excel") {
          this.tips = "支持excel文件";
        } else {
          this.tips = "支持图片,文件(doc/docx/pdf),大小不超过10M";
        }
      },
    },
  },
  methods: {
    handleRemove(file, fileList) {
      console.log(file, fileList);
    },
    handlePreview(file) {
      console.log(file);
    },
    handleExceed(files, fileList) {
      this.$confirm(
        `当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${
          files.length + fileList.length
        } 个文件`,
        "警告",
        { customClass: "myt-msg-box" }
      );
    },
    beforeRemove(file, fileList) {
      if (this.triggerStataus) {
        this.triggerStataus = false;
        return;
      }
      return this.$confirm(`确定移除 ${file.name}`, "提示", {
        customClass: "myt-msg-box",
      });
    },
    handleChange(file, fileList) {
      // this.$emit("input", fileList);
    },
    async myUpload(file) {
      console.log("上传11", file);
      if (!this.isLimit(file.file.type, file.file.size)) {
        return false;
      }
      this.triggerStataus = false;
      let formData = new FormData();
      formData.append("file", file.file);
      let info = await commonApi.getUploadFile(formData);

      if (info.succeed) {
        let obj = {
          key: info.data.fileKey,
          name: file.file.name,
          url: `https://xxxxxxxxxxxxxxxxxxxxx.com/mcloud/mag/ProxyForText/apiaccess/v1/file/fetch/${info.data.fileKey}`,
        };
        var fileList = this.fileList;
        fileList.push(obj);
        this.$emit("uploadFile", fileList);
      } else {
        // 清除文件上传失败回显
        let uid = file.file.uid; // 关键作用代码,去除文件列表失败文件
        let idx = this.$refs.uploadExcel.uploadFiles.findIndex(
          (item) => item.uid === uid
        ); // 关键作用代码,去除文件列表失败文件(uploadFiles为el-upload中的ref值)
        console.log(idx, "=======", this.$refs.uploadExcel.uploadFiles);
        this.$refs.uploadExcel.uploadFiles.splice(idx, 1); // 关键作用代码,去除文件列表失败文件
        this.$message({
          message: info.data.msg,
          type: "error",
        });
      }
    },
    clearFiles() {
      this.$refs["uploadExcel"].clearFiles();
    },
    beforeAvatarUpload(file) {
      console.log(file.size, file.type);
      var fileType = file.type;
      var size = file.size;
      var result = this.isLimit(fileType, size);
      if (!result) {
        this.triggerStataus = true;
        this.$message.error(this.tips);
      }
      return result;
    },
    isLimit_1(fileType, size) {
      // doc 文件 fileType得到的是application/msword docx文件, 得到的是 application/vnd.openxmlformats-officedocument.wordprocessingml.document
      const isLimitType =
        fileType.indexOf("image") > -1 ||
        fileType.indexOf("word") > -1 ||
        fileType.indexOf("pdf") > -1;
      const isLt2M = size / 1024 / 1024 < 10;
      return isLimitType && isLt2M;
    },
    isLimit(fileType, size) {
      // doc 文件 fileType得到的是application/msword docx文件, 得到的是 application/vnd.openxmlformats-officedocument.wordprocessingml.document

      if (this.fileSuffixType === "Excel") {
        console.log("Excel文件");
        const isLimitType = fileType.indexOf("xls") > -1;
        const isLt2M = size / 1024 / 1024 < 10;
        return isLimitType && isLt2M;
      } else {
        const isLimitType =
          fileType.indexOf("image") > -1 ||
          fileType.indexOf("word") > -1 ||
          fileType.indexOf("pdf") > -1;
        const isLt2M = size / 1024 / 1024 < 10;
        return isLimitType && isLt2M;
      }
    },
    uploadTemplate() {
      this.$emit("uploadTemplate");
    },
  },
  data() {
    return {
      fileList: [],
      triggerStataus: false, //是否达不到上传条件,被限制了
      tips: "",
    };
  },
  created() {},
};
</script>


<style>
.myt-uploader {
}

.myt-uploader .upload-ctx {
  display: flex;
  align-items: center;
}

.myt-uploader .tips {
  font-size: 14px;
  font-family: Source Han Sans CN;
  font-weight: 400;
  line-height: 24px;
  color: #6da1c7;
  padding-left: 10px;
  white-space: nowrap;
}

.myt-uploader .excel-tips {
  margin-left: 40px;
  color: #00b9ff;
}

.myt-uploader .excel-tips i {
  margin-right: 5px;
}

.myt-uploader .el-upload-list__item {
  margin-bottom: 10px;
  margin-top: 0 !important;
  line-height: 34px !important;
  height: 34px !important;
  background: rgba(81, 178, 255, 0.2) !important;
  display: flex;
  align-items: center !important;
  border-radius: 0 !important;
  padding-left: 10px;
  padding-right: 10px;
}

.myt-uploader .el-upload-list__item:first-child {
  margin-top: 10px !important;
}
.loading-uploader .el-upload-list__item:last-child {
  display: none !important;
}
.myt-uploader
  .el-upload-list__item.is-success
  .el-upload-list__item-status-label {
  flex: 1;
  line-height: 34px !important;
  height: 34px !important;
}

.myt-uploader .el-icon-circle-check {
  color: #4fe193 !important;
}

.myt-uploader .el-icon-circle-check:before {
  content: "\e79c" !important;
}

.myt-uploader .el-icon-close:before {
  content: "\e6d7" !important;
}

.myt-uploader .el-upload-list__item .el-icon-close {
  /*display: inline-block !important;*/
  line-height: 34px !important;
  width: 34px;
  height: 34px;
  text-align: center;
  color: #ffffff;
  background: transparent;
  align-items: center;
  position: absolute;
  top: 0;
  right: 0;
}

.myt-uploader .el-upload-list__item .el-icon-close:hover {
  line-height: 34px !important;
  width: 34px;
  height: 34px;
  text-align: center;
  color: #ffffff;
  background: rgba(81, 178, 255, 0.2);
  align-items: center;
  position: absolute;
  top: 0;
  right: 0;
}

.myt-uploader .el-icon-close-tip {
  display: none !important;
}

.myt-uploader .el-upload-list__item-name {
  font-size: 14px;
  font-family: Source Han Sans CN;
  font-weight: 400;
  line-height: 24px;
  color: #ffffff;
}

.myt-uploader .el-icon-document {
  display: none;
}

.myt-uploader .el-upload-list__item .el-progress {
  position: absolute;
  left: 0;
  top: 0;
  display: flex;
  align-items: flex-end;
  height: 34px;
}

.myt-uploader .el-progress__text {
  position: absolute;
  top: 0;
  font-size: 14px;
  font-weight: 400;
  line-height: 34px;
  color: #ffffff;
  padding-right: 10px;
}

.myt-uploader .el-progress-bar__outer {
  background-color: rgba(81, 178, 255, 0.2);
}
</style>

25、el-table 设置全选选中报错:

this.$refs.multipleTable.toggleRowSelection is not a function
需求是有两个 tab,每个 tab 下面都有一个表格 el-table
在这里插入图片描述
直接如下面这样设置是有问题的

this.pageInfo.rows.forEach((row) => {
  console.log('打印', this.$refs.multipleTable)
  this.$refs.multipleTable.toggleRowSelection(row, true)
})

然后打印了 this.$refs.multipleTable ,发现组件中有两个 table
在这里插入图片描述
此时设置 this.$refs.multipleTable[0].toggleRowSelection(val) 可解决

if (this.active === 'first') {
  this.$refs.multipleTable[0].toggleRowSelection(val)
} else if (this.active === 'second') {
  this.$refs.multipleTable[1].toggleRowSelection(val)
}

26、树形控件修改样式

(1)需求1: 给 el-tree 添加背景颜色
在这里插入图片描述
查看审查元素
在这里插入图片描述
使用下面这段代码会使该一级下对应的子级也相应改变了颜色,无法达到要求

.is-expanded .el-tree-node__content{
	color:green;
	background:red;
}

思路:获取父元素下面的第一个子元素,类名相同如何判断谁是父元素谁是子元素。
这里的父元素和子元素类名都是 el-tree-node__content,那再往上找一级,即
祖父 is-expanded 、父元素 el-tree-node__content 、子元素 el-tree-node__content
找到 is-expanded下的第一个子元素 el-tree-node__content

实现:
换成 > 选择器可实现是改变一级元素的样式

.is-expanded > .el-tree-node__content{
	color:green;
	background:red;
}

(2)需求2:给 el-tree 添加指示竖线
效果图:
请添加图片描述
实现:
调用 PlanTree 组件:

<plan-tree @handleClose="showPlanTree = false"></plan-tree>

封装 PlanTree 组件,PlanTree.vue 文件代码:

<template>
  <div class="plan-tree">
    <!--    icon-class="-"-->
    <el-tree class="tree" :data="data" :props="defaultProps" default-expand-all @node-click="nodeClick" ref="tree">
      <span class="custom-tree-node" slot-scope="{ node, data }">
        <span
          ><!--<i
              class="mgr10 expand-icon"
              :class="{
                'el-icon-remove-outline': node.expanded && !node.isLeaf,
                'el-icon-circle-plus-outline': !node.expanded && !node.isLeaf,
              }"></i
            >-->{{ data.label }}</span
        >
      </span>
    </el-tree>
  </div>
</template>
  
<script>
export default {
  name: "PlanTree",
  data() {
    return {
      data: [
        {
          id: 1,
          label: "一级 1",
          children: [
            {
              id: 4,
              label: "二级 1-1",
              children: [
                {
                  id: 9,
                  label: "三级 1-1-1",
                },
                {
                  id: 10,
                  label: "三级 1-1-2",
                },
              ],
            },
          ],
        },
        {
          id: 2,
          label: "一级 2",
          children: [
            {
              id: 5,
              label: "二级 2-1",
            },
            {
              id: 6,
              label: "二级 2-2",
            },
          ],
        },
        {
          id: 3,
          label: "一级 3",
          children: [
            {
              id: 7,
              label: "二级 3-1",
            },
            {
              id: 8,
              label: "二级 3-2",
            },
          ],
        },
      ],
      defaultProps: {
        children: "children",
        label: "label",
      },
    };
  },
  methods: {
    nodeClick(...arg) {
      console.log("nodeClick", arg);
    },
  },
};
</script>
  
<style lang="scss" scoped>
.plan-tree {
  background: #f8f9fb;
  border-radius: 6px;
  padding: 0 20px 20px;
  .tree-head {
    padding: 10px 0;
    display: flex;
    justify-content: space-between;
    align-items: center;
    .title {
      font-size: 14px;
      font-family: Microsoft YaHei-Regular, Microsoft YaHei;
      font-weight: 400;
      color: #333333;
    }
    .close {
      cursor: pointer;
      &:hover {
        color: #75a9ec;
      }
    }
  }
  .tree {
    background: unset !important;
  }
}

.custom-tree-node {
  font-size: 12px;
  font-family: Microsoft YaHei-Regular, Microsoft YaHei;
  font-weight: 400;
  color: #333333;
}

.mgl10 {
  margin-left: 10px;
}
.mgr10 {
  margin-right: 10px;
}

.el-tree {
  ::v-deep {
    .el-tree-node__expand-icon {
      //display: none !important;
    }

    .el-tree-node__content {
      //height: unset !important;
      padding-left: unset !important;
    }
    .el-tree-node__children {
      position: relative;
      &:before {
        position: absolute;
        content: "";
        top: 0;
        left: 6px;
        width: 1px;
        bottom: 0;
        background: #b1bac4;
      }
    }
    .el-tree-node {
      .el-tree-node {
        padding-left: 16px;
        position: relative;
        &:before {
          position: absolute;
          content: "";
          top: 13px;
          left: 6px;
          width: 16px;
          height: 1px;
          background: #b1bac4;
        }
      }
    }
  }
}
</style>
  

27、【ElementUI】日期选择器时间选择范围限制

参考:https://www.cnblogs.com/xjcjcsy/p/7977966.html

选择三个月到今天的日期:

<el-date-picker
       v-model="value1"
       type="date"
       placeholder="选择日期"
       :picker-options="pickerOptions">
</el-date-picker>
data (){
   return {
       pickerOptions: {
          disabledDate(time) {
            let curDate = (new Date()).getTime();
            let three = 90 * 24 * 3600 * 1000;
            let threeMonths = curDate - three;
            return time.getTime() > Date.now() || time.getTime() < threeMonths;;
          }
        },  
   }     
} 

JS获取一年的第一个月第二个月一直到最后一个月,第一天到最后一天:

const start = new Date(new Date().getFullYear(), 1);
//获取当前年份一月1日
const end = new Date(new Date().getFullYear(), 2);
//获取当前年份二月
end.setTime(end.getTime() - 3600 * 1000 * 24)
//获取end所在月最后一天
/* 括号里的1,2 代表需要拿到的月份*/

28、el-tooltip 自定义样式(背景颜色、箭头样式)

使用属性 popper-class 添加一个 class

<el-tooltip content="Top center" placement="top" popper-class="atooltip">
  <el-button>查看</el-button>
</el-tooltip>
.atooltip.el-tooltip__popper[x-placement^="top"] .popper__arrow {
  border-top-color: pink;
}
.atooltip.el-tooltip__popper[x-placement^="top"] .popper__arrow:after {
  border-top-color: pink;
}
.atooltip {
  background: pink !important;
}

注意:
(1)placement 的属性值有 top / top-start / top-end / bottom / bottom-start / bottom-end / left / left-start / left-end / right / right-start / right-end
(2)[x-placement^=??] 、 border-??-color 的上下左右 要与 placement 一致
(3)更改的样式代码 不能放到 scoped 中,要放到全局或者当前文件的 <style lang="scss"></style>

29、实现:hover 的颜色和选中的颜色不一致

效果图:
在这里插入图片描述

.item_sel.active_item {
  color: #ffffff;
  background-color: #0e989e;
  &:hover {
    background-color: #0e989e;
  }
}
.item_sel:hover {
  color: #ffffff;
  background-color: rgba(14, 152, 158, 0.2);
}

30、清除a标签之间的间隙

a{
  float: left;
}

element 中 <el-link> a标签的下划线是由伪类实现的

31、element-UI table 拿到 index 索引

表格:

<el-table
  :data="tableData"
  :row-class-name="rouClassNameFn"
  @row-click="onRowClick"
>
  <el-table-column prop="date" label="日期" width="180"> </el-table-column>
</el-table>

获取索引值:

rouClassNameFn({row, rowIndex}) {
	//把每一行的索引放进row
	row.index = rowIndex;
},
onRowClick (row, event, column) {
    // 打印该行的 index 索引值
	console.log(row.index)
}

32、el-table属性row-class-name用法及踩坑

需求:想要给表格的某一行加上不同的background,用来区分当前行的状态
在这里插入图片描述

  • 在el-table中绑定自定义属性row-class-name
<el-table
 :data="tableData"
 style="width: 100%"
 :row-class-name="tableRowClassName">
</el-table>
  • 在methods中定义方法,这里用来给某一行的状态加上class
methods: {
  tableRowClassName({row, rowIndex}) {
    if (rowIndex === 1) {
      return 'warning-row';
    } else if (rowIndex === 3) {
      return 'success-row';
    }
    return '';
  }
}
  • 给自己定义的class设置样式
 <style>
    .el-table .warning-row {
      background: oldlace;
    }
  
    .el-table .success-row {
      background: #f0f9eb;
    }
  </style>
踩坑笔记:

使用 row.userName 等变量时,值为 undefined,这时候要看看在 tableRowClassName 方法内,参数是个对象,所以要解构再使用啊!
在这里插入图片描述

  • 使用后没有效果的问题!!!!!
    • 第一步: 看看 class 有没有加上去
    • 第二步: 如果 class 都加上去了也没有效果,看一下有没有使用 stripe 这个属性,这个属性是带斑马纹的表格样式,它和 row-class-name 共存时是没有效果滴
    • 第三步:如果你也没有使用到 stripe 这个属性,那就要找样式的问题啦
      • 使用 scoped 设置了样式作用域,这个会影响到 class 的样式

      • 可以尝试使用 /deep/ 深度选择器,必须在 sass 或 less下

        /deep/ .el-table .warning-row {
            background: oldlace;
          }
        
        /deep/ .el-table .success-row {
            background: #f0f9eb;
          }
        
      • 使用 >>>深度选择器,只支持css

        .el-table >>> .warning-row {
          background: oldlace;
        }
        .el-table >>> .success-row {
          background: #f0f9eb;
        }
        

33、el-dialog 弹窗,默认点击遮罩层不关闭弹窗

Vue.use(ElementUI);
// 修改 el-dialog 默认点击遮罩不关闭
ElementUI.Dialog.props.closeOnClickModal.default = false;

34、el-dropdown 报错

出现报错
在这里插入图片描述
原因:使用了<el-dropdown></el-dropdown> 组件没有子组件会报错,一般不会故意不加子组件,往往是加了 v-if 时, false 状态时把子组件给消除了,所以找不到子组件而报的错。
在这里插入图片描述
那么需求就是要有该隐藏条件的话,加一个类名,然后给个样式 display:none 就行。

<template :class=" {'is-empty': tab.children && tab.children.length  }  ">
   <el-dropdown-menu>
     .....
   </el-dropdown-menu>
</template>

<style>
.is-empty{
   .el-dropdown-menu{
     display:none;
  }
}
</style>

35、表格嵌套 el-popover 多个 popover 切换时数据动态变化

https://blog.csdn.net/Windyluna/article/details/120273429

36、element 表格固定高度

https://blog.csdn.net/Windyluna/article/details/118764422

37、Element 多选表格前端分页 多选框回显

https://blog.csdn.net/Windyluna/article/details/120738368

39、Element动态表格 嵌套select 改变表格颜色 合并单元格

https://blog.csdn.net/Windyluna/article/details/119142543

40、el-tree 带竖线

在这里插入图片描述
参考:
https://blog.csdn.net/weixin_42490398/article/details/107942461

<el-tree
	class="tree-line"
	icon-class="el-icon-circle-plus-outline"
	:indent="0"
	:data="data"
></el-tree>
// 以下为scss,记得去掉scoped,或者使用/deep/
<style lang="scss">
.tree-line{
  .el-tree-node {
    position: relative;
    padding-left: 16px; // 缩进量
  }
  .el-tree-node__children {
    padding-left: 16px; // 缩进量
  }

  // 竖线
  .el-tree-node::before {
    content: "";
    height: 100%;
    width: 1px;
    position: absolute;
    left: -3px;
    top: -26px;
    border-width: 1px;
    border-left: 1px dashed #52627C;
  }
  // 当前层最后一个节点的竖线高度固定
  .el-tree-node:last-child::before {
    height: 38px; // 可以自己调节到合适数值
  }

  // 横线
  .el-tree-node::after {
    content: "";
    width: 24px;
    height: 20px;
    position: absolute;
    left: -3px;
    top: 12px;
    border-width: 1px;
    border-top: 1px dashed #52627C;
  }

  // 去掉最顶层的虚线,放最下面样式才不会被上面的覆盖了
  & > .el-tree-node::after {
    border-top: none;
  }
  & > .el-tree-node::before {
    border-left: none;
  }
	
  // 展开关闭的icon
  .el-tree-node__expand-icon{
    font-size: 16px;
    // 叶子节点(无子节点)
    &.is-leaf{
      color: transparent;
      // display: none; // 也可以去掉
    }
  }
}
</style>

Logo

前往低代码交流专区

更多推荐