elment ui 组件bug总结

一、. element-ui dialog设置为点击弹窗以外的区域不关闭弹窗

第一种:
在el-dialog标签中添加:close-on-click-modal="false"即可

<el-dialog title="标题" :close-on-click-modal="false"  :visible.sync="dialogEnrol" width="30%">
  弹窗内容
</el-dialog>

第二种:全局设置

在mian.js里面:
import ElementUI from 'element-ui';
// 修改 el-dialog 默认点击遮照为不关闭
ElementUI.Dialog.props.closeOnClickModal.default = false

二、. select 里面的option 的宽度跟最外的下拉框宽度不一致解决办法, 在select标签里面加style:100%

三、.全局设置 size  ,button、input  等 我不想要那么大的size就可以全局设置一个尺寸:

全局配置

在引入 Element 时,可以传入一个全局配置对象。该对象目前支持 size 与 zIndex 字段。size 用于改变组件的默认尺寸,zIndex 设置弹框的初始 z-index(默认值:2000)。按照引入 Element 的方式,具体操作如下:

1.完整引入 Element: 在main.js 里面

import Vue from 'vue';
import Element from 'element-ui';
Vue.use(Element, { size: 'small', zIndex: 3000 });

2.或者用按需引入:

按需引入 Element:

import Vue from 'vue';
import { Button } from 'element-ui';
 
Vue.prototype.$ELEMENT = { size: 'small', zIndex: 3000 };
Vue.use(Button);

 按照以上设置,项目中所有拥有 size 属性的组件的默认尺寸均为 'small',弹框的初始 z-index 为 3000。

//在index.js文件中 设置size
Vue.use(Element, { size: 'small'});

四、.element-ui表单验证时需要number类型

解决方式

在v-model的时候加个number修饰符就可以了。

五、.element设置表格el-table表头的颜色

使用header-cell-style可以修改它 的背景及其他

<!--内容表格-->
    <el-table
        :data="tableData"
        border
        :header-cell-style="{background:'#000', color:'#fff'}"
        style="width: 95%;margin: 40px;">

效果如下: 

在这里插入图片描述

六、.element-ui 表格的某一列的字段字体变颜色2种方法

方法①:  :cell-style="cellStyle"

        //修改单元格样式的方法
        cellStyle(row, column, rowIndex, columnIndex){
            if (row.row.errorMsg == "已存在相同记录"){
                if (row.columnIndex === 3){
                    return 'color: red'
                }
            }
        },

方法② 用卡槽的方法去解决

<el-table-column label="ciName" prop="ciName" width="180" show-overflow-tooltip>
                    <template slot-scope="scope">
                        <span v-if="scope.row.errorMsg" style="color: red">{
     
     {scope.row.ciName}}</span>
                        <span v-else>{
     
     {scope.row.ciName}}</span>
                    </template>   
                </el-table-column>

效果如下:

注: 表格数据在渲染的时候, 建议使用深拷贝的方法,赋值一下。否则会出现,表格数据更新延迟。 深拷贝方法: this.excelData = JSON.parse(JSON.stringify(this.excelData));

七、.vue项目控制台报警告:

sockjs.js?9be2:2999 WebSocket connection to 'ws://localhost:8083/sockjs-node/264/g0wa1uvw/websocket' failed: WebSocket is closed before the connection is established

解决办法:webpack热部署导致的问题
注释掉
node_modules\sockjs-client\dist\sockjs.js

里面
1604行这个就可以了

八、.element中table单元格添加tooltip  并且根据后台返回的数据判断,tooltip是否显示

废话不多说,直接贴代码:

 <el-table-column label="ciName" prop="ciName" width="180">
                    <template slot-scope="scope">
                        <el-tooltip placement="top" effect="light" v-if="scope.row.errorMsg">
                            <div style="color:red">{
     
     {scope.row.ciName }}</div>
                            <div slot="content" style="color:red">{
     
     {scope.row.errorMsg}}</div>
                        </el-tooltip>
                        <div v-else>{
     
     {scope.row.ciName }}</div>
                    </template>   
                </el-table-column>

分析: 这种一般肯定用的卡槽的方法显示数据,slot-sope

可以把条件写在  el-tooltip  标签里面 v-if  
然后还要一个 v-else  不需要   el-tooltip  的,只显示数据的。

九、.elment-ui  搜索条件太多,可以做一个收起/展开的功能,比较好

先上效果图:
展开:

 收起:

代码如下:

          <a style="margin-left:10px" @click="toggleAdvanced">
            {
    
    { advanced ? '收起' : '展开'}}
            <i :class="advanced ? 'el-icon-arrow-up' : 'el-icon-arrow-down' "></i>
          </a>

在你要隐藏的部分加上  v--show=“advanced"  

<el-row :gutter="24" v-show="advanced">
要隐藏的内容。。。
</el-row>

js 定义变量:  advanced: false, //展开/收起

方法:

    // 展开/收起
    toggleAdvanced(){
      this.advanced = !this.advanced;
    },

十、.elment-ui 表格数, 默认是第一列展开的,我想从第二列开始,

解决办法:只需要:你把第一列的el-table-column的type设置为type=“”,下拉就到第二列去了

十一、.element-ui  el-radio-group for循环时取值,老是label的值???

错误写法:

                <el-radio-group v-model="formData.type" @change="onChangeType">
                    <el-radio v-for="(item, index) in menuTypeList" :value="item.value" :label="item.label" :key="index">
                        {
    
    { item.label}}
                    </el-radio>
                </el-radio-group>

正确写法: 把::label="item.value"  就可以了

                <el-radio-group v-model="formData.type" @change="onChangeType">
                    <el-radio v-for="(item, index) in menuTypeList" :value="item.value" :label="item.value" :key="index">
                        {
    
    { item.label}}
                    </el-radio>
                </el-radio-group>


        //改变类型
        onChangeType(type){
            // console.log("type++", type);
            if (type){
                this.formData.type = type;
            }
        },

十二、.在使用 npm run build 打包时 移除console
 

    随着项目功能的不断完善 代码的累积 项目中的庞大代码数量
    造成我们打包时的长时间等待 尤其是我们在开发阶段留下的过多的测试代码
    例如最常见不过的console 消耗我们的时间 并且占有一定的内存

1、使用 babel中 的一个插件,因为webpack 打包时会使用 babel 进行代码降级,所以babel 插件可以在打包过程中将 console 移除

      安装插件
      
      npm install babel-plugin-transform-remove-console --save-dev

2、配置babel.config文件

const prodPlugins = []
if (process.env.NODE_ENV === 'production') {
  prodPlugins.push('transform-remove-console')
}
module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ],
  plugins: ['transform-remove-console']
}

这样配置后 再次打包 包中就没有console了
问题:当运行npm run serve时 也会删除console 但是开发阶段我们需要
改善babel.config文件:

现在 只有在打包时会删除console

十三、.computed 和 watch 区分使用场景


computed:是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值;
watch:更多的是「观察」的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作

 

运用场景:
   1.  当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed,
因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算;

   2.当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,
 使用 watch 选项允许我们执行异步操作 ( 访问一个 API ),
 限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。
 这些都是计算属性无法做到的。


十四、. 兼容IE11

用过vue的同学们应该都比较清楚,vue其实是可以兼容ie9的,但是这种兼容并不是说,你写了一个项目,打开ie9就能兼容了,是需要用工具将代码进行转换的。我之前也是这样以为的,直到近期一个项目完成之后,打开ie11,发现页面显示正常的,但是所有的http请求都是无效的,经过了一番查找,才知道这个babel-polyfill的包的用处,当然知道的同学可以略过啦,不知道的话,跟着我继续往下看

我们使用现代浏览器的话,很多像是es7、es8的语法,可能都是已经支持了,但是放在ie上,这些方法都是通通不认识的,因此我们就需要一个工具来将这些ie浏览器不认识的语法转换成ie所认识的,那么知道了这个babel的包,其实就很简单了,我们直接这样在vue中的main.js中引入这个包即可
 

import "babel-polyfill";

然后我们需要在babel.config.js中进行按需加载的配置

presets: [
    '@vue/app',
    [
      '@babel/preset-env',
      {
        'useBuiltIns': 'entry'
      }
    ]
]

注意这个@babel/preset-env是一个有关环境变量的包,这个包在你使用vue脚手架3.0创建项目时就会自带这个包了,所以是不需要下载的,最后在main.js中引入我们之前下载的包就可以了。

import "@babel/polyfill";

这样就大功告成了,打包的话也可以看到打包体积变小了

对比可以看到体积小了20kb,但是问题来了,明显在主包中文件体积过大,已经1.5M了,这个体积页面首次打开的时候,可能会需要3-10秒的时间,用户体验肯定是极差的,所以下面我们也说到如何按需加载我们的组件,注意我们vue项目使用的是ant-design-vue的ui框架,所谓按需加载组件,就是我们项目中用到了这个组件才导入这个组件,没有用到的话,就不要将这个组件的内容打包进去,也包括组件的样式。

按需打包组件


其实关于按需打包我们需要的组件,很多组件也介绍如何按需使用,ant-design-vue也提供了这些内容,想要详细了解的同学可以点开链接查看文档,这里也是简单说一下,首先需要下载babel-plugin-import的插件,然后需要在babel.config.js中进行如下配置

plugins: [
    [
      "import",
      {libraryName: "ant-design-vue",libraryDirectory: "es",style: true}
    ]
  ]

之后的话,我们就不能全局引入组件了,而是引入我们项目中所用到的一些组件,可以将这些引入的组件单独放入一个js文件中,这样方便以后添加组件

//index.js
import Vue from 'vue';
import {
    Button,
    Row,
    Col,
    Layout,
    Menu,
    Icon,
    Form,
    Tag,
    Input
} from 'ant-design-vue';

Vue.use(Button)
Vue.use(Row)
Vue.use(Col)
Vue.use(Layout)
Vue.use(Menu)
Vue.use(Icon)
Vue.use(Form)
Vue.use(Tag)
Vue.use(Input)
//也可以这样写,但是这样写比较麻烦
// Vue.component(Button.name,Button)
// Vue.component(Row.name,Row)
// Vue.component(Col.name,Col)
// Vue.component(Layout.name,Layout)
// Vue.component(Layout.Header.name,Layout.Header)
// Vue.component(Layout.Sider.name,Layout.Sider)
// Vue.component(Layout.Footer.name,Layout.Footer)
// Vue.component(Layout.Content.name,Layout.Content)
// Vue.component(Menu.name,Menu)
// Vue.component(Icon.name,Icon)
// Vue.component(Form.name,Form)
// Vue.component(Tag.name,Tag)
// Vue.component(Form.Item.name,Form.Item)
// Vue.component(Input.TextArea.name,Input.TextArea)

然后我们再来打包看看此时的文件大小

一下子少了近500kb,是不是好了很多呢,当然如果包体积还是比较大,这个时候我们可以考虑将一些依赖排除在打包当中,使用external的配置,这里就不多说了,有兴趣的同学可以自己试试。

当然我们用的其他ui组件也可以采用按需加载的方法。比喻elemen-ui  的按需加载:具体的这里不做详细说明,请参考我的另一篇文章:iview ui 和elment ui 的按需引用,减小项目体积_IT博客技术分享-CSDN博客

十五、图片资源懒加载


对于图片过多的页面,为了加速页面加载速度,所以很多时候我们需要将页面内未出现在可视区域内的图片先不做加载, 等到滚动到可视区域后再去加载。这样对于页面加载性能上会有很大的提升,也提高了用户体验。我们在项目中使用 Vue 的 vue-lazyload 插件:

(1)安装插件
 

npm install vue-lazyload --save-dev

(2)在入口文件 man.js 中引入并使用
 

import VueLazyload from 'vue-lazyload'

然后再 vue 中直接使用

Vue.use(VueLazyload)

或者添加自定义选项
 

Vue.use(VueLazyload, {
preLoad: 1.3,
error: 'dist/error.png',
loading: 'dist/loading.gif',
attempt: 1
})

(3)在 vue 文件中将 img 标签的 src 属性直接改为 v-lazy ,从而将图片显示方式更改为懒加载显示:

<img v-lazy="/static/img/1.png">

以上为 vue-lazyload 插件的简单使用,如果要看插件的更多参数选项,可以查看 vue-lazyload 的 github 地址。

十六、.vue-cli4配置webpack-bundle-analyzer插件

安装

npm install webpack-bundle-analyzer --save-dev

vue.config.js配置

module.exports = {
    chainWebpack: config => {
        config
            .plugin('webpack-bundle-analyzer')
            .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
    }

}

十七、.手机号中间四位加星号

var tel = "13800001234";
 
var reg = /^(\d{3})\d{4}(\d{4})$/;
 
tel = tel.replace(reg, "$1****$2");
console.log(tel); //138****1234

十八、elment ui  时间组件   el-date-picker   需要默认的时间为今天的 00:00:00  至今天的 23:59:59 

          <el-date-picker
            v-model="firstTime"
            value-format="yyyy-MM-dd HH:mm:ss"
            @change="onChangeFirstTime"
            clearable
            style="width:98%"
            type="datetimerange"
            range-separator="至"
            start-placeholder="选择拆链开始时间"
            end-placeholder="选择拆链结束时间" :default-time="['00:00:00', '23:59:59']">
          </el-date-picker>



    onChangeFirstTime(first){
      console.log("first:", first);
      if (first){
        this.firstTime = first;
        this.searchs.startDiscTime = first[0];
        this.searchs.endDiscTime = first[1]
      }
    },




//在created()里面赋值默认值

  created(){
    var start = new Date(new Date(new Date().toLocaleDateString()).getTime());
    var end = new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1);
    // console.log(FromTimes(start), FromTimes(end))
    this.firstTime[0] = FromTimes(start);
    this.firstTime[1] = FromTimes(end);
}

效果如下:

 打印结果:

十九、elment-ui 上传文件后不显示删除按钮,只能查看不能删除

1,看文档(upload上传)

2,代码:

  <a-descriptions-item label="文件" :span="3">
              <a-upload
                action="http://xxxxx/File"//上传文件接口
                :multiple="true"
                :showUploadList="{showRemoveIcon:false}" //不显示删除按钮
                :default-file-list="record.file"
              >
            
              </a-upload>
            </a-descriptions-item>

 3.效果图:

二十、element-ui  设置全局 Loding

 应用场景

场景:前端在发送Ajax请求,请求后台数据时,不允许用户点击当前页面的其他按钮。
 

在全局封装请求的js里面:

1. 先引入: 

import { Loading } from 'element-ui'

2. 定义全局loading

// newLoading 框设置局部刷新,且所有请求完成后关闭 newLoading 框
let newLoading
function startLoading() {
    newLoading = Loading.service({
    lock: true,
    text: 'Loading',
    spinner: 'el-icon-loading',
    background: 'rgba(0, 0, 0, 0.7)'
  })
}
function endLoading() {
    setTimeout(() => {
        newLoading.close()
    }, 1000)
}
// 声明一个对象用于存储请求个数
let needLoadingRequestCount = 0
function showFullScreenLoading() {
  if (needLoadingRequestCount === 0) {
    startLoading()
  }
  needLoadingRequestCount++
}
function tryHideFullScreenLoading() {
  if (needLoadingRequestCount <= 0) return
  needLoadingRequestCount--
  if (needLoadingRequestCount === 0) {
    endLoading()
  }
}

3. 调用:

service.interceptors.request.use(
    (config) => {
        showFullScreenLoading() //加载 Loading
        // 判断是否存在token,如果存在的话,则每个http header都加上token
        if (store.state.user.token) { 
            // console.log("headers++", store.state.user.token)
            // config.headers.Authorization = `token ${store.state.user.token}`
            config.headers.Authorization = `${store.state.user.token}`
        }
        // console.log(config)
        // removePending(config); //在一个ajax发送前执行一下取消操作
        config.cancelToken = new cancelToken((c) => {
            // 这里的ajax标识我是用请求地址&请求方式拼接的字符串,当然你可以选择其他的一些方式
            pending.push({
                u: config.url + '&' + config.method,
                f: c
            });
        });
        tryHideFullScreenLoading() //关闭 Loading
        return config
    },
    (error) => {
        tryHideFullScreenLoading() //关闭 Loading
        return Promise.error(error)
    }
)

二十一、Vue elment-ui  刷新当前路由方法 

vue通过js执行完方法后有时需要刷新当前路由,常见的this.reload(),  window.reload()之类,但这类刷新会刷新整个页面,出现白屏,体验不好,所以在网上又找了一种中转的方法.

this.$router.replace({ 
   path: '/refresh'
})

首先新建一个新的路由:refresh.vue

<!-- 空页面,负责中转到目标页面 -->
<template>
  <div></div>
</template>
 
<script>
export default {
  name: 'refresh',
  data () {
    return {
    }
  },
  beforeRouteEnter (to, from, next) {
    next(vm => {
      vm.$router.replace(from.path)
    })
  }
}
</script>

然后在你需要刷新当前路由的方法里面加上这个:

this.$router.replace({ 
   path: '/refresh'
})

注:from.path为需要刷新页面的地址。
为什么要用replace而不用push呢,因为push假如刷新成功后点返回会回到refresh页面,replace可以避免这个问题

二十二、 element-ui el-table多选置灰

<el-table-column
    type="selection"
    :selectable="checkSelectable"
    width="55">
  </el-table-column>

 method中方法:

checkSelectable (row) {
  let mark = 0
  this.checkedInitQuestions.forEach((item) => {
    if (item.id === row.id) {
      mark = mark + 1
      return false
    }
  })
  return mark <= 0
}

checkedInitQuestions 为需要置灰的数据列表

二十三、elment-ui  编辑修改的时候, this.historyData  = row ;  时候直接这样赋值,会联动双向数据绑定,输入框内容改变,表格内容也跟着改变。

处理办法:  this.historyData  = JSON.parse(JSON.stringify(row));

 二十四、 element-ui 表单 form 回车 enter 触发查询,怎么禁止调

方法一: 全局屏蔽

@keyup.enter.native="onQuery"
<el-form  @submit.native.prevent></el-form>

在 el-form 上添加

方法二:自己写个全局的方法:

在 el-form 上添加   @keyup.enter.native="onQuery"

二十五、ElementUI Table组件树表结构默认展开一级目录

 

 处理方法:

if (this.tableData[0].children) {
                // 默认展开根节点
                this.$nextTick(() => {
                  document.getElementsByClassName('el-table__expand-icon')[0].click();
                });
              }

二十六、ElementUI el-table单击行row-click与个别列的按钮操作冲突

row-click和cell-click都一样。
如果是原生标签,就直接给click事件加.stop 
如果是el标签,需要加.native.stop 
下面是我的demo,可以参考下↓
        <el-table
          title="双击查看详情"
          @sort-change="handleSortChange"
          ref="singleTable"
          :data="tableData"
          style="cursor: pointer;font-size: 12px;"
          @row-click="handleRowChange"
          :row-class-name="tableRowClassName">
           <el-table-column
            <template slot-scope="scope">
              <img
                  @click.stop="mark(scope.row)"
                  v-if="scope.row.is_mark == '0'"
                  width="16"
                  alt=""
                  src="../../assets/image/machineAnalysis/unmark.png"
                  style="cursor: pointer;"/>
            </template>
          </el-table-column>
          <el-table-column
            label="操作"
            :show-overflow-tooltip="true"
            align="center"
            width="210"
            >
            <!-- eslint-disable-next-line -->
            <template slot-scope="scope">
              <el-button
                size="mini"
                @click.native.stop="handleEdit(scope.row.task_id)">编辑数据</el-button>
            </template>
          </el-table-column>
        </el-table>

二十七、element UI中table组件实现单选操作 的radio的显示 bug

先复现bug截图:

现在不像要这个id显示出来

<el-radio
            :label="scope.$index"
            v-model="currentRow"
            @change.native="getCurrentRow(scope.row)">{
   
   {""}}</el-radio>

全部代码:

<template>
  <div class="page">
    <el-table
      :data="tableData"
      ref="singleTable"
      highlight-current-row
      border
      style="width: 100%">
      <el-table-column label="选择" width="70" header-align="center" align="center">
        <template scope="scope">
          <el-radio
            :label="scope.$index"
            v-model="currentRow"
            @change.native="getCurrentRow(scope.row)">{
   
   {""}}</el-radio>
        </template>
      </el-table-column>
      <el-table-column prop="date" label="日期"> </el-table-column>
      <el-table-column prop="name" label="姓名"> </el-table-column>
      <el-table-column prop="address" label="地址"> </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      currentRow: 0,
      tableData: [
        {
          date: "2016-05-02",
          name: "王小虎",
          index: "1",
          address: "上海市普陀区金沙江路 1518 弄",
        },
        {
          date: "2016-05-04",
          name: "王小虎",
          index: "2",
          address: "上海市普陀区金沙江路 1517 弄",
        },
        {
          date: "2016-05-01",
          name: "王小虎",
          index: "3",
          address: "上海市普陀区金沙江路 1519 弄",
        },
        {
          date: "2016-05-03",
          name: "王小虎",
          index: "3",
          address: "上海市普陀区金沙江路 1516 弄",
        }
      ]
    }
  },
  methods: {
    getCurrentRow(row) {
      console.log(row);
    }
  }
}
</script>

效果图:

二十八、element Upload 上传文件只能上传一次 ,再次点击上传无反应的问题的坑

解决办法:

在 上传成功之后掉这个方法:
this.$refs.upload.clearFiles(); //上传成功之后清除历史记录

element Upload 上传文件只能上传一次 ,再次点击上传无反应的问题的坑

今天在开发的时候,文件上传都没有问题,但是修改文件数据后,再次上传图片就无反应了,导致整个问题的原因是因为你没有清除当前 fileList,导致它一直保存这你第一次上传文件的信息,只要你把他一刀切掉就好了!

那么问题来了,应该怎么清除呢!所以要想继续上传文件,就需要在on-success钩子函数中通过ef 拿到它的document元素进行清除已经上传的文件 看下面的代码:
 

 <el-upload
   class="upload-demo"
   ref='upload'
   action="https://jsonplaceholder.typicode.com/posts/"
  :on-preview="handlePreview"
  :on-remove="handleRemove"
  :before-remove="beforeRemove"
  :on-success="handleSuccess"
   multiple
  :limit="3"
  :on-exceed="handleExceed"
  :file-list="fileList">
   <el-button size="small" type="primary">点击上传</el-button>
   <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
 </el-upload>

解决方法:

 handleSuccess(res, file) {
       this.$refs.upload.clearFiles(); //上传成功之后清除历史记录
}

二十九、vue 关闭弹框重新打开时elementui验证规则还在的处理方式

 以下代码在哪里关闭弹框就写在哪里 :

//清除所有校验
this.$refs.formData.clearValidate();

最后为了方便大家的沟通与交流请加QQ群: 625787746

请进QQ群交流:【IT博客技术分享群①】:正在跳转

猜你喜欢

转载自blog.csdn.net/qq_41646249/article/details/115428261