Vue实战中遇到的常见的问题总结(三)---关于Element UI

737 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情。 接下来想总结关于项目开发过程中,使用到element-ui的一些总结。

Element UI 表格点击某一行完成选中事件或取消选中事件

需求:点击表格的某一行,即可触发选中该行。
如同element table中组件提供了单选的支持,只需要配置highlight-current-row属性即可实现单选。如下图。但element仅提供了单选,那多选的情况如何实现呢?

image.png 多选点击效果如下:选中某一行后,相当于对应的checkbox被选中

image.png 实现如下:
界面:在表格上添加以下三个参数:row-click,row-style和row-class-name,具体用法可参考elementUI文档。

image.png

<el-table 
   border
   ref="serveTable"
   :data="tableData"
   @selection-change="handleSelectionChange"
   @row-click="rowClick"  
   :row-style="rowStyle" 
   :row-class-name="rowClassName"
>
<el-table-column type="selection" width="60" align="center"></el-table-column>
<el-table-column type="index" width="50" label="序号" align="center"></el-table-column>
<el-table-column prop="name" label="设备名" show-overflow-tooltip align="center"></el-table-column>
<el-table-column prop="ip" label="终端IP" show-overflow-tooltip align="center"></el-table-column>
<el-table-column prop="status" label="状态" show-overflow-tooltip :formatter="formatter_status" align="center"></el-table-column>
<el-table-column prop="model" label="设备型号" show-overflow-tooltip align="center"></el-table-column>
<el-table-column label="操作" align="center" width="150">
  <template slot-scope="scope">
    <el-button
      size="mini"
      icon="el-icon-delete"
      type="danger" plain
      @click.native.stop="handleDelete(scope.$index, scope.row)"
     >删除</el-button>
   </template>
 </el-table-column>
</el-table>

事件触发:大概实现过程如下:监听row-click事件,找到选中的行,实现选中行的选中事件,并使用rowClassName方法实现高亮。同时也要注意对重复选中进行处理。

//表格选中事件
handleSelectionChange(val) {
   this.multipleSelection = val;
},
rowStyle({row,rowIndex}) {
   Object.defineProperty(row, 'rowIndex', { //给每一行添加不可枚举属性rowIndex来标识当前行
   value: rowIndex, 
   writable: true,
   enumerable: false
  })
},
//监听row-click事件,实现选中
rowClick(row, column, event) {
   let refsElTable = this.$refs.serveTable; // 获取表格对象
   let findRow = this.multipleSelection.find(c => c.rowIndex == row.rowIndex);       //找到选中的行
   if (findRow ) {
      refsElTable.toggleRowSelection(row, false);  //如过重复选中,则取消选中
      return;
   }
   refsElTable.toggleRowSelection(row,true); // 实现选中行中选中事件
 },
//实现选中高亮
  rowClassName({ row,  rowIndex }) {
    let rowName = "",
    findRow = this.multipleSelection.find(c => c.rowIndex === row.rowIndex);
    if (findRow) {
      rowName = "current-row "; 
    }
   return rowName; //也可以再加上其他类名 如果有需求的话
  },
}

最后,发现如果点击按钮,也会触发选中事件,此时可以使用按钮的冒泡事件。如下:

image.png

element框架中,可输入下拉框(el-select和el-autocomplete对比)

需求:需要一个即可选择也可输入的输入框,且需要自定义模板(输入视频源url时,其名称也需展示)。 考虑到element有两种组件可实现,那么就来对比一下这两种 实现: el-select的实现比较简单,参考element的官网:element.eleme.io/#/zh-CN/com…

只需加filterable allow-create即可完成此需求,且有clearable属性,可清除。同时,也可通过以下方式自定义模板。 但是,展示效果并不让人满意。即需要选中下拉框的新增项。

 <el-select v-model="url" filterable allow-create default-first-option clearable placeholder="请选择或输入视频源地址" style="width:780px"> 
    <el-option v-for="item in videoTableData"  :key="item.url"  :label="item.filename"  :value="item.url" >
        <span style="float: left">{{ item.name }}</span>
        <span style="margin-left:15px;color: #8492a6; font-size: 13px">({{ item.url }})</span>
    </el-option>
 </el-select>

于是,我选用了el-autocomplete,参考element的官网:element.eleme.io/#/zh-CN/com… 展示效果良好。
以上就是关于el-select和el-autocomplete对比总结。但有一个小小的扩展:
el-autocomplete该组件无清空按钮,于是我通过以下方式给该组件增加上了清空按钮。清空按钮大概实现逻辑为:利用mouseenter和mouseleave监听鼠标移入移出触发hove事件,通过设置isHover这个标志位,从而实现判断是否展示X的icon图标。接下来按照正常业务逻辑对点击icon图标后的事件进行编写即可。demo如下:

<el-autocomplete
    class="inline-input"
    ref="input"
    v-model="url"
    :fetch-suggestions="querySearch" 
    placeholder="请选择或输入视频源地址" 
    style="width:780px"
    @mouseenter.native="isHover = true"
    @mouseleave.native="isHover = false">
    <i v-if="showsClear" class="el-icon-circle-close el-input__icon" slot="suffix" @click="handleIconClick"></i>
    <i v-else class="el-icon-arrow-down el-input__icon" slot="suffix" @click="handleIconClick"></i>
    <template slot-scope="{ item }">
        <div @click="choose(item)">
            <span style="float: left">{{ item.name }}</span>
            <span style="margin-left:15px;color: #8492a6; font-size: 13px">({{ item.value }})</span>
        </div>
    </template>
</el-autocomplete>
<script>
export default {
    props:{
        clearable: {
            type: Boolean,
            default: true,
        }
    },
    data() {
         return {
             isHover: false,
             url:'',
             videoTableData :[]
         }
    },
     mounted(){
            this.getvideoTableData ();   
      },
    computed: {
         showsClear () {
             return this.clearable && this.url && this.isHover
         },
     },
    methods:{
         handleIconClick () {
         if (this.showsClear) {
             this.url = '';
         } else {
             this.$refs.input.focus();
         }
     },    
     querySearch(queryString, cb) {
         var videoTableData = this.videoTableData;
         var results = queryString ? videoTableData.filter(this.createStateFilter(queryString)) : videoTableData;
         cb(results);
      },
     createStateFilter(queryString) {
       return (state) => {
          return (state.value.toLowerCase().indexOf(queryString.toLowerCase()) >=0);
        };
     },
     //获取列表数据
     getvideoTableData (){
       this.videoTableData = [{
       name:'文件分享.mp4',
       value:'dshgfdshfjdshghfhsd……'  
       },
       ……
       ]
     }
     
     …………       
}
</script>

最终,利用el-autocomplete组件实现的效果如下:

image.png

image.png