关于element-ui:elementui中使用form验证功能后如果有不符合的字段则定位到指定字段

1:场景形容:如果表单过长,且谬误字段和保留按钮没有在同一可视范畴内,用户不能及时通晓哪里出了问题,导致始终点击提交有效 2:阐明:表单验证谬误字段会带一个is-error的类,通过该类进行定位 3:外围源码: /*** 对表单ref=edititemform进行相干规定验证* 如果验证不通过,仅需获取指定验证表单内的谬误字段:this.$refs.edititemform.$el* 如果你的页面上进存在一个form表单,能够间接通过document.getElementsByClassName来获取谬误字段* 滚动定位到第一个报错的字段即可**/this.$refs.edititemform.validate((valid) => { if (valid){ console.log("验证通过,做你后续操作") }else{ this.$nextTick(() => { let err = this.$refs.edititemform.$el.getElementsByClassName('is-error') if (err.length) { err[0].scrollIntoView({ block: 'center', behavior: 'smooth', }) } }) } });

July 4, 2023 · 1 min · jiezi

关于element-ui:element-table上下滚动时表格错行

应用 elementui 的 <el-table> 时 当应用了fixed后 表格高低滚动时会有错行的体现应用了官网的doLayout() 也不好用 .el-table__fixed-body-wrapper .el-table__body { padding-bottom: 20px;}加上这行代码刷新

May 9, 2023 · 1 min · jiezi

关于element-ui:eltree-递归显示机构城市等信息

构造最简略的el-tree应用, 常常用来显示机构,菜单,省市县等信息 <el-tree ref="tree" :data="treedata" :props="defaultProps2"></el-tree>list: function(){ u.axios.get("http://localhost:6088/treeList").then(function(res){ console.log(res.data); //为什么用push quan.treedata.push(res.data); }); }后端, 应用正向递归查问 package com.bw.controller;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import com.bw.entity.City;import com.bw.entity.CityExample;import com.bw.entity.CityExample.Criteria;import com.bw.mapper.CityMapper;@RestControllerpublic class CityTreeController { @Autowired CityMapper cityMapper; /** * * 难度系数在 **** * redisTemplate *** * @param city * @return */ public City recur(City city){//city-->父节点 CityExample cityExample=new CityExample(); Criteria criteria = cityExample.createCriteria(); criteria.andPidEqualTo(city.getCityid());//pid= List<City> children = cityMapper.selectByExample(cityExample);//select * from city for (City child : children) { this.recur(child); } city.setChild(children); return city; } @RequestMapping("treeList") public City treeList(){ City city = cityMapper.selectByPrimaryKey(1);//1-->中国的节点 city=this.recur(city); return city; }}数据库构造 ...

March 21, 2023 · 1 min · jiezi

关于element-ui:修复element-ui级联懒加载问题二次封装成elcascaderplus

el-cascader-plus常常碰到懒加载不回显的问题,应用起来很不不便,于是花了些工夫二次开发了这个组件,下次遇到同样问题就能间接解决,在此开源进去,心愿对遇到雷同问题的人有帮忙。开源互助使程序的世界更美妙! el-cascader-plus基于 element-ui 级联二次封装,补救了原 element-ui 级联组件懒加载常常无奈回显的有余,用法与原级联组件统一。 应用前请确保装置了 vue 和 element ui (或者已独自按需引入 element ui 的级联 Cascader) 版本举荐 "vue": "^2.6.11","element-ui": "^2.15.13", 配置参数同 ElementUI 的 Cascader 级联选择器,可参考其文档ElementUI 官网文档 新增的属性 参数阐明类型可选值默认值maxLevel懒加载最大层级,最小值0Number整数1000git仓库https://github.com/fatelyh/el... 优化点:   1、修复原组件懒加载单选数据加载提早的状况下不响应数据变动、不触发回显的问题  2、修复原组件懒加载多选不响应数据变动、不触发回显的问题 3、单选懒加载做了回显速度优化,比原组件单选懒加载回显速度会快一些 4、新增一个prop属性:maxLevel,可限度懒加载最大层级,整数,最小值0,默认值1000  5、props中的lazyLoad在原根底上对resolve做了一点小批改。      props{        lazy:true,        lazyLoad:this.getNode      }      getNode(node, resolve) { //依据node获取子集操作 resolve(params) // 其中params可为一般数据和promise(要有resolve值) }成果预览 install 装置npm i el-cascader-plus --save应用在 main.js 中写入上面的代码就能够全局应用 import elCascaderPlus from "el-cascader-plus";Vue.use(elCascaderPlus);在组件中独自应用 ...

February 22, 2023 · 9 min · jiezi

关于element-ui:elselect-filterable为true情况下大数据量卡顿问题处理

7千条数据,搜寻卡顿 <el-select v-model="query.enterpriseId" filterable :filter-method="enterpriseSearchF" placeholder="请抉择企业名称" clearable> <el-option v-for="item in conInputShowList" :key="item.id" :label="item.companyName" :value="item.id" :disabled="item.disabled"> </el-option></el-select>data() { return { conInputShowList: [], // 显示的数据 conInputList: [], // 原始接口数据 }},// 自定义搜寻条件enterpriseSearchF(val) { const moreVal = '输出更具体的条件查问更多数据'; const maxNum = 100; // 超出量,超出只显示此量的数据。 const key = 'companyName'; // 数据key,须要搜寻的字段 if (val) { //val存在 this.conInputShowList = this.conInputList.filter((item) => { if (item[key].indexOf(val) > -1) { return true } }) if (this.conInputShowList.length > maxNum) { this.conInputShowList = this.conInputShowList.slice(0, maxNum); const temp = { disabled: true } temp[key] = moreVal; this.conInputShowList.push(temp); } } else { this.conInputShowList = this.conInputList.slice(0, maxNum); const temp = { disabled: true } temp[key] = moreVal; this.conInputShowList.push(temp); } const allTemp = { id: null } allTemp[key] = '全副'; this.conInputShowList.unshift(allTemp);},

January 16, 2023 · 1 min · jiezi

关于element-ui:eltable多列同时排序且样式保留多用于后台排序

场景:上图中能够看到多个箭头都是选中成果 形容:element-ui的el-table仅才反对单列(一个字段)进行排序,想要反对多列排序,首先要定义一个数组,用于寄存所有排序的字段及其程序,设置列sortable=“custom”,联合sort-change事件,在点击排序箭头时进行排序操作 实现:话不多说间接上代码,大家本人能够批改成合乎本人的业务: <template> <el-table :data="tableData" style="width: 100%" :default-sort = "{prop: 'date', order: 'descending'}" @sort-change="handleSortChange" :header-cell-class-name="handleHeaderCellClass" > <el-table-column prop="date" label="日期" sortable="custom" width="180"> </el-table-column> <el-table-column prop="name" label="姓名" sortable="custom" width="180"> </el-table-column> </el-table></template><script> export default { data() { return { tableData: [{ date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }], orderArray: [] } }, methods: { //增加排序办法(可把多个字段独特退出排序) handleHeaderCellClass({ row, column, rowIndex, columnIndex }) { this.orderArray.forEach((element) => { if (column.property === element.prop) { column.order = element.order; } }); }, // 点击排序箭头 handleSortChange({ column, prop, order }) { if (order) { //参加排序 let flagIsHave = false; this.orderArray.forEach((element) => { if (element.prop === prop) { element.order = order; flagIsHave = true; } }); if (!flagIsHave) { this.orderArray.push({ prop: prop, order: order, }); } } else { //不参加排序 this.orderArray = this.orderArray.filter((element) => { return element.prop !== prop }); } //调后端接口进行排序操作, this.orderArray就是最终排序后的汇合 console.log(this.orderArray ); }, } }</script>

January 11, 2023 · 1 min · jiezi

关于element-ui:基于elementui的表格分页组件

CustomTableCustomTable是基于elementui将表格与分页封装一体的组件,反对失常应用elemenui表格中的属性与办法。 1.应用例子 <CustomTable ref="customTable" :api="'/api/crmemotion/customer-v2/customer-list.do'" :simpleMode="false" :ordered="true" :requestMethod="'post'" @dataUpdates="dataUpdates" > <el-table-column prop="memberId" label="相亲ID" :min-width="TABLELINEWIDTH.ICONID" sortable > <template slot-scope="scope"> <a class="za-tx" href="javascript:void(0)" @click=" common.openPage.customPage( '跟进客户', 'followUpCustomer', scope.row.emotionId, { memberId: scope.row.emotionId, trueMemberId: scope.row.memberId, } ) " > {{ scope.row.memberId !== -1 ? scope.row.memberId : '' }} </a> </template> </el-table-column></CustomTable>2.属性2.1.应用elementui table属性基于elementui的customtable能够间接失常elementui对应的属性、事件、插槽个性等,无再次学习的老本。 2.2.申请接口api和requestMethod、requestConfig属性发送申请。listName为接口返回列表名,默认为list 目前requestMethod申请形式只反对get、post申请,同时当申请形式为post时组件外部会将申请格局通过qs.stringify()格式化,以反对情感crm的post申请参数格局。requestConfig用于设置axios申请头配置,传入格局例如: <CustomTable :requestConfig="{ 'Content-Type': 'multipart/form-data' }" />表格外部配有loading属性。胜利申请后组件通过dataUpdates事件将返回数据data传给父组件2.3.分页simpleMode、countOption、pageCount设置分页组件属性。 simpleMode代表分页是否为简略模式,默认值为否。countOption为页数展现数抉择,仅在一般模式下失效。2.4.表格配置ordered设置表格是否有序号

December 27, 2022 · 1 min · jiezi

关于element-ui:封装-基于elementui的表格分页组件

CustomTableCustomTable是基于elementui将表格与分页封装一体的组件,反对失常应用elemenui表格中的属性与办法。 1.应用例子 <CustomTable ref="customTable" :api="'/api/crmemotion/customer-v2/customer-list.do'" :simpleMode="false" :ordered="true" :requestMethod="'post'" @dataUpdates="dataUpdates" > <el-table-column prop="memberId" label="相亲ID" :min-width="TABLELINEWIDTH.ICONID" sortable > <template slot-scope="scope"> <a class="za-tx" href="javascript:void(0)" @click=" common.openPage.customPage( '跟进客户', 'followUpCustomer', scope.row.emotionId, { memberId: scope.row.emotionId, trueMemberId: scope.row.memberId, } ) " > {{ scope.row.memberId !== -1 ? scope.row.memberId : '' }} </a> </template> </el-table-column></CustomTable>2.属性2.1.应用elementui table属性基于elementui的customtable能够间接失常elementui对应的属性、事件、插槽个性等,无再次学习的老本。 2.2.申请接口通过api和requestMethod、requestConfig属性发送申请。listName为接口返回列表名,默认为list 目前requestMethod申请形式只反对get、post申请,同时当申请形式为post时组件外部会将申请格局通过qs.stringify()格式化,以反对情感crm的post申请参数格局。requestConfig用于设置axios申请头配置,传入格局例如: <CustomTable :requestConfig="{ 'Content-Type': 'multipart/form-data' }" />表格外部配有loading属性。胜利申请后组件通过dataUpdates事件将返回数据data传给父组件2.3.分页通过simpleMode、countOption、pageCount设置分页组件属性。 simpleMode代表分页是否为简略模式,默认值为否。 简略模式 一般模式countOption为页数展现数抉择,仅在一般模式下失效。

December 27, 2022 · 1 min · jiezi

关于element-ui:elementui-使用技巧

el-table 动静高度&固定表头<el-table :data="tableData" height="calc(100vh - 180px )" style="width: 100%"></el-table>

November 26, 2022 · 1 min · jiezi

关于element-ui:透明背景eltable的滚动条及fixed列样式问题

需要el-table 通明背景 固定列 滚动条的解决 头疼~ 根底node:14.17.3@vue/cli 5.0.1vue:2.6.12element-ui:2.15.61.设置表格通明背景后,革除表格下边框线.el-table th.el-table__cell,.el-table tr,.el-table,.el-table__expanded-cell { background-color: transparent;}.el-table::before { width: 0;}2.列表呈现纵向滚动条后,暗藏最右侧的空白列.el-table th.gutter { display: none; width: 0;}.el-table colgroup col[name='gutter'] { display: none; width: 0;}3.增加固定列后,调整固定列的款式.el-table .el-table__fixed-right { height: auto !important; bottom: 5px !important; right: 4px !important; background-color: rgb(1, 10, 23); border-left: 1px solid rgba($color: #fff, $alpha: 1);}// 固定表格内的table-body.el-table__fixed-right .el-table__fixed-body-wrapper { height: auto !important; bottom: 5px !important;}// 暗藏固定列表头右侧多出单元格.el-table .el-table__fixed-right-patch { display: none;}// 革除固定列右侧边框线.el-table--border .el-table__cell:last-child { border-right: none !important;}// 重置固定列单元格背景色.el-table__fixed-right td.el-table__cell { background-color: rgb(1, 10, 23);}4.table组件二次封装 ...

November 7, 2022 · 2 min · jiezi

关于element-ui:使用element给表头单元格添加斜线分割线

先看下效果图,表头第一个单元格应用斜线宰割。 html代码: <el-table-column label="时段" align="right" width="150"> <el-table-column prop="month" label="月度" width="120" align="center" header-align="left" > </el-table-column></el-table-column>留神:在el-table-column上增加了align和header-align两个属性,header-align是表头的对齐形式,而align是表格内容的对齐形式,所以能够依据不同的原型图进行相干设置。 css: ::v-deep .el-table thead.is-group th { background: none;}::v-deep .el-table thead.is-group tr:first-of-type th:first-of-type { border-bottom: none;}::v-deep .el-table thead.is-group tr:first-of-type th:first-of-type:before { content: ""; position: absolute; width: 1px; height: 82px; /*这里须要本人调整,依据td的宽度和高度*/ top: 0; left: 0; background-color: #bbb; opacity: 0.3; display: block; transform: rotate(-58deg); /*这里须要本人调整,依据线的地位*/ transform-origin: top;}::v-deep .el-table thead.is-group tr:last-of-type th:first-of-type:before { content: ""; position: absolute; width: 1px; height: 82px; /*这里须要本人调整,依据td的宽度和高度*/ bottom: 0; right: 0; background-color: #bbb; opacity: 0.3; display: block; transform: rotate(-59.9deg); /*这里须要本人调整,依据线的地位*/ transform-origin: bottom;}留神:代码中有正文的中央是须要本人手动去微调的,其实就是将时段和月度分成两个元素,而后应用rotate调整角度,使两条线齐全重合。 ...

October 13, 2022 · 1 min · jiezi

关于element-ui:关于elementui表头吸附的问题

废话不多说,间接上思路通过sticky实现element-ui表头吸顶,具体步骤如下 新建一个sticky容器将element-ui的表头挪动至这个容器中解决左侧固定列贴代码<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title></head><style> .first-title { height: 300px; background: #f00; }</style><body> <div class="first-title"> this is title </div> <div id="app"> <el-table v-table-sticky="{ top: '0px', zIndex: 101}" :data="tableData" style="width: 100%"> <el-table-column prop="date" label="日期" width="180"> </el-table-column> <el-table-column prop="name" label="姓名" width="180"> </el-table-column> <el-table-column prop="address" label="地址"> </el-table-column> </el-table> </div></body><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.slim.min.js"></script><script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- 引入款式 --><link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"><!-- 引入组件库 --><script src="https://unpkg.com/element-ui/lib/index.js"></script><script>Vue.directive('table-sticky', { // 当被绑定的元素插入到 DOM 中时…… inserted (el, binding, vnode) { // 获取以后vueComponent的ID。作为寄存各种监听事件的key const uid = binding.value.uid let panel = document.createElement("div"); panel.className = 'el-table el-table--fit el-table--enable-row-transition el-table--small'; panel.style=`position: sticky;top: ${binding.value.top}; z-index: ${binding.value.zIndex};`; console.log('uid_is',[el,uid]) $(panel).insertBefore(el) let func = function () { let elFixed = $(el).children('.el-table__fixed'); if ($(el).children('.el-table__header-wrapper')[0] !== undefined) { panel.append($(el).children('.el-table__header-wrapper')[0]) } elFixed.children('.el-table__fixed-header-wrapper').width(elFixed.width()).css('overflow', 'hidden') elFixed.children('.el-table__fixed-body-wrapper').css('top',0) if (elFixed.children('.el-table__fixed-header-wrapper')[0] !== undefined) { panel.append(elFixed.children('.el-table__fixed-header-wrapper')[0]) } if (binding.value.isFooter === true) { if ($(el).children('.el-table__footer-wrapper')[0] !== undefined) { panel.append($(el).children('.el-table__footer-wrapper')[0]) } if (elFixed.children('.el-table__fixed-footer-wrapper')[0] !== undefined) { panel.append(elFixed.children('.el-table__fixed-footer-wrapper')[0]) } } } for (let i = 100; i <= 1500; i=i+100) { setTimeout(function() { func() },i); } // 获取以后滚动的容器是什么。如果是document滚动。则可默认不传入parent参数 }, // component 更新后。从新计算表头宽度 componentUpdated (el, binding, vnode) { let elFixed = $(el).children('.el-table__fixed'); elFixed.children('.el-table__fixed-body-wrapper').css('top',0) }, // 节点勾销绑定时 移除各项监听事件。 unbind (el, binding, vnode) { }}) var app= new Vue({ el:"#app", //绑定的元素 data:{ tableData: [] }, created() { for (let i = 0; i < 1000; i++) { this.tableData.push({ date: '2016-05-03', name: '王小虎', address: '上海市普陀区金沙江路 1516 弄' }) } } });</script></html>

September 27, 2022 · 2 min · jiezi

关于element-ui:elementui源码学习之仿写一个eltooltip

本篇文章记录仿写一个el-tooltip组件细节,从而有助于大家更好了解饿了么ui对应组件具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续闲暇了会不断更新并仿写其余组件。源码在github上,大家能够拉下来,npm start运行跑起来,联合正文有助于更好的了解。github仓库地址如下:https://github.com/shuirongsh...前言什么是编程对于什么是编程这个问题,确实有很多答案。在很久以前,在笔者刚入行的时候,被告知了这样一句话: 编程就是:规定的学习,规定的应用,规定的了解、规定的自定义 有肯定的情理... 背景介绍咱们在做组件的封装时,经常会遇到一些“弹框组件”,以饿了么UI为例,比方:el-tooltip组件、el-popover组件、el-popconfirm组件、el-dropdown组件等,这类组件在操作的时候,经常会有一个弹框呈现,对于这些弹框的触发条件(或悬浮、或点击)以及地位的管制(上方、下方、左侧、右侧)等,vue团队专门封装了一个vue-popper组件,通过props传参以及一些事件办法的形式,去管制以达到咱们想要的成果 那么,vue-popper组件是如何实现的呢?底层原理是啥?是把popper.js这个很优良的库做了一层封装 那么,popper.js是如何实现的呢?底层原理是啥?是通过js管制弹出框dom的地位 因为popper.js国内材料不多,所以大家能够间接应用vue-popper组件组件去做一些操作即可,毕竟其底层原理,也是prpper.js el-tooltip组件是应用了vue-popper组件的规定vue-popper组件是应用了popper.js库的规定popper.js库是应用了js和dom的规定有限规定套娃...附上传送门prpper.js 官网:https://popper.js.org/、中文... 感兴趣的道友,能够闲暇工夫钻研钻研(像elementUI和iview和Bootstrap和Material UI等都用到了proper.js)也是做的二次封装 另:prpper.js团队专门给react写了一套React Popper,vue临时没有,所以咱们就学习vue-popper呗 本篇文章着眼于,中层底层原理vue-popper组件,让咱们开始学习吧 tooltip组件思考什么是tooltip组件tooltip组件是用来做简略的文字附带阐明(提醒)的气泡框组件个别交互是鼠标移入显示,鼠标移出隐没tooltip组件个别不会做简单的交互操作,以及承载过多的文本内容能够了解为是dom元素title属性性能的具体补充tooltip组件需要暗黑模式tooltip,黑底白字高亮模式tooltip,白底黑字tooltip组件的地位,在指向援用reference元素的那个方向,个别是上下左右,拓展共有12个方向tooltip的小三角形(个别是显示的)可管制敞开开启,即符合条件hover展现,反之hover敞开个别状况下tooltip都是单行内容,若内容过多,反对文字换行乃至自定义tooltip一些款式(反对插槽)至于其余的需要如:tooltip显示开展的过渡动画、小箭头是否能够暗藏、以及偏移量offset、提早呈现隐没等,个别状况下不会怎么更改,所以本文着眼于重点常见需要,来进行阐明在应用库或者一些根底组件之前,咱们先尝试一下,手写一下 一个简略的tooltip的demo次要是应用属性选择器去管制,四个方向的tooltip和三角形小箭头。 标签的whichPlacement属性值为"top"时,就让其在上方,为left时,就让其在左侧,其余方位同理 demo效果图 demo代码复制粘贴即可应用 <!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> body { box-sizing: border-box; padding: 60px 240px; } /* 设置根本款式 */ .item { width: fit-content; box-sizing: border-box; padding: 12px; border: 2px solid #aaa; /* 搭配伪元素,用绝对定位 */ position: relative; } /* 应用伪元素创立tooltip */ .item::after { /* 内容为 应用 tooltipContent的属性值 */ content: attr(tooltipContent); position: absolute; background-color: #000; width: fit-content; height: auto; padding: 6px 12px; color: #fff; border-radius: 12px; /* 文字不换行 */ word-break: keep-all; display: none; } /* 应用伪元素创立小三角形 */ .item::before { content: ""; position: absolute; border-width: 6px 6px 0 6px; border-style: solid; border-color: transparent; border-top-color: black; display: none; } /* 上下左右四个方位,应用css的属性选择器管制tooltip和小三角形 */ /* 当whichPlacement的属性值为top时,做...款式 */ /* 上方 */ [whichPlacement='top']::after { left: 50%; transform: translateX(-50%); top: -100%; } [whichPlacement='top']::before { top: -26%; left: 50%; transform: translateX(-50%); } /* 下方 */ /* 当whichPlacement的属性值为bottom时,做...款式 */ /* 对于四个方向的小三角形,能够应用旋转更改即可 */ [whichPlacement='bottom']::after { left: 50%; transform: translateX(-50%); bottom: -100%; } [whichPlacement='bottom']::before { bottom: -28%; left: 50%; transform: rotate(180deg); } /* 左侧 */ /* 当whichPlacement的属性值为left时,做...款式 */ [whichPlacement='left']::after { top: 50%; transform: translateY(-50%); right: 108%; } [whichPlacement='left']::before { top: 50%; transform: translateY(-50%) rotate(270deg); left: -10.5px; } /* 右侧 */ /* 当whichPlacement的属性值为right时,做...款式 */ [whichPlacement='right']::after { top: 50%; transform: translateY(-50%); left: 108%; } [whichPlacement='right']::before { top: 50%; transform: translateY(-50%) rotate(90deg); right: -10px; } .item:hover::after { display: block; } .item:hover::before { display: block; } </style></head><body> <div class="item" whichPlacement="top" tooltipContent="上方呈现tooltip内容">悬浮上方</div> <br> <div class="item" whichPlacement="bottom" tooltipContent="tooltip内容在下方呈现">悬浮下方</div> <br> <br> <br> <div class="item" whichPlacement="left" tooltipContent="左侧呈现tooltip内容">悬浮左侧</div> <br> <div class="item" whichPlacement="right" tooltipContent="tooltip内容呈现在右侧">悬浮右侧</div></body></html>对于css属性选择器和attr()函数上述代码中用到了属性选择器和attr()函数,这里简略的提一下 ...

September 13, 2022 · 5 min · jiezi

关于element-ui:elementui源码学习之仿写一个elswitch

本篇文章记录仿写一个el-switch组件细节,从而有助于大家更好了解饿了么ui对应组件具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续闲暇了会不断更新并仿写其余组件。源码在github上,大家能够拉下来,npm start运行跑起来,联合正文有助于更好的了解。github仓库地址如下:https://github.com/shuirongsh...switch组件思考组件性能作用switch组件个别是示意开关状态或者两种状态之间的切换,如点击开启网站的夜间模式,或敞开夜间模式。如下图vue官网首页就有这样的操作性能: vue官网链接地址:https://cn.vuejs.org/组件的构造switch组件的构造还是比较简单的,次要分为两局部: switch组件切换小圆点按钮switch组件切换容器 组件的实现思路根本的switch切换布局构造 在实现switch组件的时候,switch组件切换容器 能够间接画一个div去示意,那么 switch组件切换小圆点按钮 咱们也须要画一个div吗?其实不必的。 咱们能够应用伪元素先画出一个切换小圆点按钮(联合定位)而后须要定义一个标识布尔值,用于更改切换组件开启敞开状态当状态变动的时候,去更改切换小圆点按钮在左侧或在右侧的地位(通过class),即实现了切换性能再加上过渡成果,这样的话,switch组件的切换(开启敞开)就会很丝滑了开启敞开switch组件的阐明文字性能注意事项 如下图: 对于开启时候文字在左侧,敞开时候文字在右侧,也开始能够通过弹性盒款式管制 justifyContent:flex-start / flex-end;,当然动静padding也要加上,详情见代码若将文字退出切换框外部,那么就须要让切换框背景容器dom的宽度自适应,即依据内容文字的多少来管制,所以要提到width: fit-content;属性(应用fit-content属性,让宽度随着内容文字多少自适应)对于 fit-content 详情见官网文档:https://developer.mozilla.org...给伪元素加上hover成果的写法 给伪元素加悬浮成果是先hover再::after(不要搞反了) 正确写法:.target:hover::after { background-color: red; } 谬误写法!!!:.target::after:hover { background-color: red; } 这里举一个例子代码效果图,复制粘贴即可应用,如下: <!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> body { padding: 120px; } .target { display: inline-block; width: 60px; height: 18px; background-color: #c4c4c4; border-radius: 10px; cursor: pointer; transition: all 0.3s; position: relative; } /* 应用伪元素画一个小圆点 */ .target::after { content: ""; position: absolute; top: -4px; left: -2px; border-radius: 50%; width: 24px; height: 24px; border: 1px solid #e9e9e9; box-shadow: 0 1px 10px 0 rgba(0, 0, 0, 0.3); background-color: #fff; transition: all 0.3s; } /* 给本人加悬浮成果间接写即可 */ .target:hover { background-color: green; } /* 给伪元素加悬浮成果是先hover再::after(不要搞反了) */ .target:hover::after { background-color: red; } </style></head><body> <div class="target"></div></body></html>对于封装的mySwitch组件的其余的货色,联合笔者的正文,就能够清晰的了解了。这个组件次要还是款式的动态控制。 ...

September 3, 2022 · 3 min · jiezi

关于element-ui:elementui源码学习之仿写一个elcollapse

本篇文章记录仿写一个el-collapse组件细节,从而有助于大家更好了解饿了么ui对应组件具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续闲暇了会不断更新并仿写其余组件。源码在github上,大家能够拉下来,npm start运行跑起来,联合正文有助于更好的了解。github仓库地址如下:https://github.com/shuirongsh...组件思考el-collapse即为折叠面板的意思,个别次要是用于:对简单区域进行分组和暗藏,放弃页面的整洁,有分类整理的意思。 collapse有折叠的意思,不过fold也有折叠的意思。所以笔者这里封装的组件就改名字了,不叫my-collapse,叫做my-fold组件的需要咱们先看一下下图折叠组件的结构图 联合上图曾经工作教训,大抵剖析组件的需要有以下: 点击折叠头部区域开展或敞开折叠内容体区域开展或折叠的时候,加上过渡成果头部区域的内容文字参数定义是否暗藏折叠的小箭头手风琴模式的折叠面板(默认是都能够开展折叠的)组件实现之父组件对立更改所有子组件状态个别状况下父组件更改子组件数据状态有以下形式: 父组件传递数据,子组件props接管。更改父组件数据,子组件也就主动更改更新了应用this.$refs.child.xxx = yyy,给子组件打一个ref,间接更改对应值即可应用this.$children能够拜访所有的子组件实例对象。所以,也能够间接更改,如下:父组件代码 // html<template> <div> <h2>下方为三个子组件</h2> <child1 /> <child2 /> <child3 /> <button @click="changeChildData">点击按钮更改所有子组件数据</button> </div></template>// jschangeChildData() { // this.$children拿到所有子组件实例对象的数组,遍历拜访到数据,更改之 this.$children.forEach((child) => { child.flag = !child.flag; });},其中一个子组件代码,另外两个也一样 // html<template> <div>child1中的flag--> {{ flag }}</div></template>// js<script>export default { data() { return { flag: false } },};</script>效果图 为什么要提到这个呢?因为手风琴模式下的折叠面板会用到这个形式去更改别的面板,使别的面板敞开 组件实现之高度过渡成果组件的封装高度的过渡,次要是从0到某个高度,以及从某个高度到0的变动,须要搭配transition以及overflow属性去管制。咱们先看一下简略的写法和效果图,再看一下封装的组件的代码 1.简略写法 伸手党福利,复制粘贴即可应用 <!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> .target { width: 120px; height: 120px; line-height: 120px; text-align: center; background-color: #baf; /* 以下两个是必要的款式管制属性 */ transition: height 0.2s linear; overflow: hidden; } </style></head><body> <button>点击高度变动</button> <br> <br> <div class="target">过渡的dom</div> <script> let isOpen = true // 初始状况下,标识状态为关上状态 let btn = document.querySelector('button') let targetDom = document.querySelector('.target') btn.onclick = () => { // 若为开展状态,就将其高度置为0,因为css有过渡代码,所以高度过渡成果就进去了 if (isOpen) { targetDom.style.height = 0 + 'px' isOpen = false } // 若为敞开状态,就将其高度置为原来,因为css有过渡代码,所以高度过渡成果就进去了 else { targetDom.style.height = 120 + 'px' isOpen = true } } </script></body></html>2.简略写法效果图 ...

August 29, 2022 · 4 min · jiezi

关于element-ui:elementui源码学习之仿写一个ellink

本篇文章记录仿写一个el-link组件细节,从而有助于大家更好了解饿了么ui对应组件具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续闲暇了会不断更新并仿写其余组件。源码在github上,大家能够拉下来,npm start运行跑起来,联合正文有助于更好的了解。github仓库地址如下:https://github.com/shuirongsh...组件思考简而言之,el-link组件就是给a标签包了一层,加上一些款式。故link组件除了领有a标签的性能,还须要有一些可能应用的款式成果。所以,咱们仿写这个组件标签的时候次要是温习一下传参的变量和款式的搭配,从而实现咱们须要的成果 组件的需要给link组件加上不同类型的链接款式,比方一般款式、胜利款式、正告款式、危险款式的链接款式给link组件加上鼠标悬浮时下划线。封装组件中应用的是伪元素搭配border-bottom实现的通过传参去管制link组件什么时候有下划线,什么时候没有下划线另外,也须要思考组件会被禁用,禁用时,不能点击,不能跳转,且更换一下款式成果同时,link组件跳转链接时的一些操作也要是思考到link组件须要搭配小图标去应用(本例中以饿了么icon为例)组件的效果图 组件实现剖析给link组件加上链接款式这里应用动静class的数组用法去管制,如下简略例子: // html<a :class="[ 'myLink', type]">// jsprops:{ type: String, // 标签色彩的类型}// css.primary { color: #2d8cf0; }.success { color: #19be6b; }.warning { color: #f90; }.danger { color: #ed4014; }由上,比方传递的type参数值为success,那么a标签就会加上一个success的类名,这样的话,就会找到对应css中的类名,从而出现相应的色彩成果(当然type的值在底下css中要有对应的) 给link组件加上鼠标悬浮时下划线其实相似这种,悬浮下划线,悬浮上划线,悬浮非凡背景管制。大抵能够演绎为在次要dom旁边加上一个小东西,都能够思考应用伪元素 对于啥是伪元素,这里不赘述咱们看下方的鼠标悬浮上划线和下划线的效果图,这个效果图就是应用伪元素搭配定位以及border去实现的 代码: // cssspan { font-size: 24px; position: relative;}span:hover::before { content: ""; position: absolute; left: 0; right: 0; height: 0; /* 定位管制 */ top: 2px; border-top: 1px solid red;}span:hover::after { content: ""; position: absolute; left: 0; right: 0; height: 0; /* 定位管制 */ bottom: -2px; border-bottom: 1px solid red;}// html<span>早上好,程序猿兽们</span>通过传参管制是否加上下划线(即:是否加上这个下划线类名)这里仍然是应用动静class的数组用法,在数组中书写四元表达式,简洁代码如下: ...

August 25, 2022 · 3 min · jiezi

关于element-ui:elementui源码学习之仿写一个eltimeline

本篇文章记录仿写一个el-timeline组件细节,从而有助于大家更好了解饿了么ui对应组件具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续闲暇了会不断更新并仿写其余组件。源码在github上,大家能够拉下来,npm start运行跑起来,联合正文有助于更好的了解。github仓库地址如下:github.com/shuirongshu…组件剖析组件形成局部工夫线组件形成局部可分为四局部: 工夫线小圆点工夫线竖线条工夫戳具体内容详情如下图: 所以针对工夫线组件的需要,次要是从这四个角度去管制。个别工夫线组件需要如下: 组件需要剖析对于分割线的组件,个别应用的场景需要有: 比方依照工夫线正序或顺叙的展现(如:日志记录)比方默认的工夫线小圆点的款式色彩,以及能够自定义色彩(这里默认蓝色圆环)比方也能够应用小图标代替工夫线小圆点(例,应用饿了么图标)应用了饿了么小图标,有时候还须要给图标上色比方管制工夫戳和具体内容详情的地位(这里默认工夫戳在上方,有时候工夫戳可能在下方)有的时候,可能不须要展现工夫戳,只须要展现内容,所以要再加一个是否暗藏工夫戳的变量对于官网组件的集体认识:1.官网组件的provide和inject能够拿掉,如下图: 2.官网组件管制工夫戳地位用了两份dom,能够更改为一份dom搭配弹性盒方向管制 3.参考各方对仿写封装组件做一个简洁的解决 大家能够看一下antd和iview的工夫线组件,参数确实是比饿了么的工夫线组件少一些。 antd:https://ant.design/components... iview:https://www.iviewui.com/view-... 个人观点不肯定对,仅供参考组件中回顾知识点温故而知新 this.$slots.default.reverse()默认插槽数组this.$slots.default,也是数组,所以也是能够应用数组的办法的。 这里管制工夫线的正序顺叙就是应用了,这个办法 :style中写四元表达式冒号style其实也是能够写三元、或者四元或者更多元的,蕴含变量的表达式,如下: <div class="dots" :style="{ border: elementIcon ? 'none' : borderColor ? `2px solid ${borderColor}` : '2px solid #1890ff', }" ></div>粗心:通过:style给class为dots的dom元素设置border边框款式,具体边框的值取决于elementIcon和borderColor这两个变量的值。 代码演示的话,间接复制粘贴即可应用。当然残缺的代码在github上哦^_^ 咱们先看一下效果图,再看一下代码 效果图 应用组件代码<template> <div> <!-- 一般应用工夫正序排列 --> <button @click="reverse = !reverse">点击更改工夫线排序</button> <my-timeline style="margin-top: 6px" :reverse="reverse"> <my-timeline-item timestamp="2018-01-01" >2018年好像还在昨天一样</my-timeline-item > <my-timeline-item timestamp="2020-01-01" >2020就像刚刚过来一样</my-timeline-item > <my-timeline-item timestamp="2022-01-01" >2022年也曾经走完一半了</my-timeline-item > </my-timeline> <br /> <!-- 自定义工夫线圆点色彩或应用饿了么小图标 --> <my-timeline> <my-timeline-item v-for="(item, index) in timeArr" :key="index" :timestamp="item.timestamp" :borderColor="item.borderColor" :elementIcon="item.elementIcon" :iconColor="item.iconColor" >{{ item.content }}</my-timeline-item > </my-timeline> <br /> <!-- 管制工夫戳地位与是否暗藏工夫戳 --> <my-timeline> <my-timeline-item timestamp="2222-02-02" >默认工夫戳在文字上方</my-timeline-item > <my-timeline-item timestamp="3333-03-03" timeLocation="down" >通过timeLocation属性将工夫戳放在文字下方</my-timeline-item > <my-timeline-item timestamp="4444-04-04" hideTimestamp >若不想要工夫戳可应用hideTimestamp属性将其暗藏</my-timeline-item > </my-timeline> </div></template><script>export default { data() { return { reverse: false, timeArr: [ { timestamp: "2022-04-01", content: "默认工夫线小圆点款式", }, { timestamp: "2022-05-01", content: "更改工夫线小圆点色彩", borderColor: "red", }, { timestamp: "2022-04-01", content: "应用饿了么的小图标做为工夫线小圆点", elementIcon: "el-icon-view", }, { timestamp: "2022-07-01", content: "给饿了么的icon上色", elementIcon: "el-icon-location", iconColor: "green", }, ], }; },};</script>myTimeline代码<script>export default { name: "myTimeline", // 外层组件只承受一个参数即是否反转,内层组件的参数多一些 props: { reverse: { // 是否反转,即管制工夫排序形式 type: Boolean, default: false, // 默认从上往下 }, }, // 应用render函数渲染数据 render() { const reverse = this.reverse; const classes = { "my-timeline": true, "is-reverse": reverse, }; let slots = this.$slots.default || []; // 获取默认插槽数组 if (reverse) { slots = slots.reverse(); // 默认插槽数组,也是数组,所以也是能够应用reverse办法做反转的 } // 加上动静class 并传递默认插槽 return <ul class={classes}>{slots}</ul>; // 整体工夫线构造就是ul搭配li,一个li代表一项工夫线 },};</script><style lang="less">.my-timeline,.my-timeline .timeLineItem { list-style: none;}// 把最初一条竖向工夫线暗藏.my-timeline .timeLineItem:last-child .verticalLine { display: none;}</style>myTimelineItem代码<template> <li class="timeLineItem"> <!-- 垂直方向的线条 --> <div class="verticalLine"></div> <!-- 垂直方向的小圆点 --> <div class="dots" :style="{ border: elementIcon ? 'none' : borderColor ? `2px solid ${borderColor}` : '2px solid #1890ff', }" > <!-- 上述三元表达式意思: 当传了elementIcon时,阐明要应用饿了么UI的图标,即不应用border了,故为none; 当未传elementIcon时,再看是否传了borderColor了,若传了,就应用传递的borderColor作为 border-color的值,否则就应用默认的#1890ff为边框色 --> <i v-if="elementIcon" :style="{ color: iconColor }" :class="elementIcon" ></i> </div> <!-- 内容区,通过flex-direction管制工夫和细节的高低地位 --> <div class="content" :class="{ isSetTimeDown: timeLocation == 'down' }"> <!-- 内容区的工夫 --> <div class="contentTime" v-if="!hideTimestamp">{{ timestamp }}</div> <!-- 内容区的具体细节 --> <div class="contentDetail"> <slot></slot> </div> </div> </li></template><script>export default { name: "myTimelineItem", props: { // 工夫戳具体值 timestamp: String, // 是否暗藏工夫戳,只展现文字内容 hideTimestamp: { type: Boolean, default: false, // 默认显示工夫戳 }, // 工夫戳的地位,默认工夫戳地位在上方 timeLocation: String, // 指定工夫线条连贯的小圆点的边框色 borderColor: String, // 应用饿了么UI的图标替换节点小圆点,如 el-icon-more elementIcon: String, // 设置饿了么UI图标的色彩 iconColor: String, },};</script><style scoped lang="less">.timeLineItem { position: relative; // 定位管制工夫线和小圆点的地位细节 padding-bottom: 12px; .verticalLine { width: 2px; height: 100%; background-color: #e9e9e9; // 定位管制 position: absolute; top: 4px; } .dots { width: 12px; height: 12px; background-color: #fff; border-radius: 50%; // 通过定位将小圆点挪动到左侧工夫线上方 position: absolute; left: -5px; top: 4px; i { position: absolute; left: -2px; top: -2px; } } .content { padding-left: 24px; display: flex; // 通过弹性盒方向管制contentTime和contentDetail的高低地位(默认工夫在上方) flex-direction: column; .contentTime { margin-bottom: 6px; font-size: 13px; color: #666; } .contentDetail { margin-bottom: 6px; font-size: 14px; color: #333; } } // 是否让工夫在下方,取决于是否timeLocation的值是否为down .isSetTimeDown { flex-direction: column-reverse; }}</style>如果对您有一点点帮忙的话,欢送github不吝star哦^O^

August 22, 2022 · 2 min · jiezi

关于element-ui:elementui源码学习之仿写一个elbread

本篇文章记录仿写一个el-bread组件细节,从而有助于大家更好了解饿了么ui对应组件具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续闲暇了会不断更新并仿写其余组件。源码在github上,大家能够拉下来,npm start运行跑起来,联合正文有助于更好的了解。github仓库地址如下:https://github.com/shuirongsh...什么是面包屑直观来说,面包屑其实就相当于一个导航跳转的快捷操作形式。那么为什么这么叫呢?源自格林童话: 面包屑导航(BreadcrumbNavigation)这个概念来自童话故事“汉赛尔和格莱特”,当汉赛尔和格莱特穿过森林时,不小心迷路了,然而他们发现沿途走过的中央都撒下了面包屑,让这些面包屑来帮忙他们找到回家的路。所以,面包屑导航的作用是通知访问者他们在网站中的地位以及如何返回。 源自百度百科:https://baike.baidu.com/item/... 组件需要剖析对于bread面包屑组件,次要是用于展现以后页面所在的层级地位,告知用户在哪里,且可能点击面包屑做路由跳转(返回),咱们剖析一下面包屑组件的需要,大抵有以下: 面包屑分隔内容需要 默认分隔内容,比方饿了么UI的面包屑导航默认就是以 斜杠 / 分隔的如果咱们感觉默认分隔斜杠 / 不难看,也可本人传递分隔内容,比方以 >> 分隔跳转性能需要 比方push跳转,即:this.$route.push(...)或者replace跳转,即:this.$route.replace(...)整顿来说,这两个需要都是挺简略的,不过咱们再看下方封装的代码之前须要温习一下组件中用到的常识:provide和inject provide、inject的知识点温习一言以蔽之:先人组件provide提供数据,后辈组件(蕴含子组件)inject接收数据 对于provide和inject咱们能够这样的类比了解: 父传子,是父组件应用冒号:绑定传递,子组件应用props接收数据而先人传后辈,先人应用provide绑定传递(提供),后辈应用inject接收数据(注入)只说文字,有点不太直观,所以咱们看一下上面这个案例就了解了 小案例此案例是分为三个组件,别离是one组件、two组件、three组价,one组件是two组件的父组件、two组件是three组件的父组件。即关系为:one、two、three三个组件形成了爷、父、子这样关系的先人组件和后辈组件 one组件中有name和age两个字段的数据,须要提供到two组件和three组件中应用 案例代码图示剖析 案例效果图 了解了这个小案例,再看下方的代码会更好清晰思路 为甚要提到provide和inject呢?因为在封装面包屑组件的时候,官网是分为两个组件,el-breadcrumb和el-breadcrumb-item;在el-breadcrumb组件中应用到了provide提供默认分隔内容斜杠/和分隔内容的图标class类名给后辈组件el-breadcrumb-item应用。 接下来咱们看一下仿写封装的组件代码封装代码封装的效果图 应用组件的代码相似官网的面包屑组件代码,这里咱们也用两个面包屑组件代码,为:my-bread组件和my-bread-item组件(先人后辈关系) <template> <div> <my-divider content-position="left">默认颜文字分隔</my-divider> <my-bread> <my-bread-item>外层</my-bread-item> <my-bread-item>中层</my-bread-item> <my-bread-item>内层</my-bread-item> </my-bread> <my-divider content-position="left">自定义分隔内容</my-divider> <my-bread customDivide=">"> <my-bread-item>外层</my-bread-item> <my-bread-item>中层</my-bread-item> <my-bread-item>内层</my-bread-item> </my-bread> <my-divider content-position="left">应用饿了么UI的图标做分隔</my-divider> <my-bread elementIconClassDivide="el-icon-wind-power"> <my-bread-item>外层</my-bread-item> <my-bread-item>中层</my-bread-item> <my-bread-item>内层</my-bread-item> </my-bread> <my-divider content-position="left">可跳转</my-divider> <my-bread elementIconClassDivide="el-icon-location-outline"> <my-bread-item :to="{ path: '/myTag' }">myTag跳转</my-bread-item> <my-bread-item replace :to="{ path: '/myBadge' }">myBadge跳转(replace)</my-bread-item> <my-bread-item>当下</my-bread-item> </my-bread> </div></template>my-bread组件代码<template> <div class="breadWrap"> <slot></slot> </div></template><script>export default { name: "myBread", props: { // 应用饿了么UI的图标icon类名进行分隔 elementIconClassDivide: { type: String, default: "", }, // 自定义分隔内容,用户填写什么,就以什么为分隔 customDivide: { type: String, default: "→_→", // 如这里,默认以颜文字为默认分隔。饿了么是斜杠默认分隔/ }, }, /** * 父组件provide注入一个本身实例this给到子组件myBreadItem,不便子组件拜访 * 父组件的分隔内容变量defaultDivide或customDivide或elementIconClassDivide * 因为子组件须要去渲染出对应的分隔内容是啥 * * 其实这里不应用provide注入的形式也是能够的。子组件myBreadItem拜访父组件myBread * 也能够应用this.$parent.defaultDivide这样的模式去拜访父组件的数据内容。不过 * 这里只是做一个分隔内容的展现,不牵涉到响应式数据处理,所以应用provide更优雅 * */ provide() { return { fatherInstance: this, // 提供本身实例,不便子组件应用,子组件需inject申明注入接管应用 }; },};</script><style lang="less" scoped>.breadWrap { font-size: 14px; // 第一个面包屑的文字加粗 /deep/ .breadItem:first-child .breadItemWords { font-weight: 700; } // 最初一个面包屑的小图标暗藏 /deep/ .breadItem:last-child .breadItemDivide { display: none; }}</style>my-bread-item组件代码<template> <div class="breadItem"> <!-- 面包屑文字局部(点击文字跳转) --> <span ref="link" :class="['breadItemWords', to ? 'isLink' : '']"> <slot></slot> </span> <!-- 面包屑图标局部 --> <!-- 应用饿了么UI的图标做分隔 --> <i v-if="elementIconClassDivide" class="breadItemDivide" :class="elementIconClassDivide" ></i> <!-- 自定义分隔 二者只留一个即可 --> <span v-else class="breadItemDivide">{{ customDivide }}</span> </div></template><script>export default { name: "myBreadItem", inject: ["fatherInstance"], // 要申明承受当前能力应用,留神名字要和父组件provide的保持一致 props: { // 跳转的path to: {}, // 默认不做replace跳转 replace: { type: Boolean, default: false, }, }, data() { return { elementIconClassDivide: "", // 应用饿了么图标做分隔的类名 customDivide: "", // 自定义分隔内容 }; }, mounted() { /** * 先祖组件provide提供数据,后辈组件inject注入承受数据(能够inject多个实例,故为数组) * 这里是以父子组件为例,子组件拜访父组件的值(也可思考应用this.$parent.xxx形式) * * 渲染分隔符 * */ // console.log( // "父组件提供数据,子组件注入本身当前便可拜访", // this.fatherInstance // ); // 拜访并再存一份去应用,从而渲染分隔内容 this.elementIconClassDivide = this.fatherInstance.elementIconClassDivide; this.customDivide = this.fatherInstance.customDivide; /** * 跳转性能 * */ // 获取组件实例 const link = this.$refs.link; // 绑定监听点击,点击跳转 link.addEventListener("click", (_) => { // 没有传递to就不做跳转 if (!this.to) return; // 当replace为true的时候,才做replace跳转(默认还是push跳转) this.replace ? this.$router.replace(this.to) : this.$router.push(this.to); }); },};</script><style lang="less" scoped>.breadItem { display: inline-block; .breadItemWords { font-weight: 400; } .isLink { font-weight: 700; } .isLink:hover { color: #409eff; cursor: pointer; } .breadItemDivide { margin: 0 8px; color: #999; }}</style>总结集体愚见provide和inject次要应用的场景还是组件封装这一块,貌似在业务代码中应用的少 ...

August 17, 2022 · 2 min · jiezi

关于element-ui:动态选择表头的隐藏和显示elementui的table表格

起因:因为elementui的表格没有做动静渲染表头的操作,本人封装了一个步骤一:建设vue组件<template> <div class="operate-btn"> <el-button class="o-ml-12" icon="el-icon-s-operation" v-preventReClick type="success" size="mini" @click="headFilterShow" >显示项调整</el-button > <!-- 筛选穿梭框 --> <el-dialog :close-on-click-modal="false" v-dialogDrag :visible.sync="headFilter.visible" title="显示项调整" width="536px"> <el-form label-position="right" label-width="100px" :model="coefficientAdjustShowForm"> <el-form-item label="测试字段:"> <el-checkbox :indeterminate="coefficientAdjustShowForm.options1IsInde" v-model="coefficientAdjustShowForm.option1CheckAll" @change="option1CheckAllChg" >全选</el-checkbox > <el-checkbox-group @change="options1CheckChg" v-model="coefficientAdjustShowForm.options1"> <el-checkbox v-for="item in headerShowList.option1" :label="item" :key="item">{{ item }}</el-checkbox> </el-checkbox-group> </el-form-item> <el-form-item label="试验字段:"> <el-checkbox :indeterminate="coefficientAdjustShowForm.options2IsInde" v-model="coefficientAdjustShowForm.option2CheckAll" @change="option2CheckAllChg" >全选</el-checkbox > <el-checkbox-group @change="options2CheckChg" v-model="coefficientAdjustShowForm.options2"> <el-checkbox v-for="item in headerShowList.option2" :label="item" :key="item">{{ item }}</el-checkbox> </el-checkbox-group> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button v-preventReClick @click="headFilter.visible = false">取 消</el-button> <el-button v-preventReClick type="primary" @click="handleClickUpdateThead">确 定</el-button> </div> </el-dialog> </div></template><script>export default { name: 'tableHeadAdjust', props: ['tableData', 'headerShowList', 'headFilter', 'curThis'], data() { return { coefficientAdjustShowForm: { options1: [], options2: [], option1CheckAll: false, option2CheckAll: false, options1IsInde: true, options2IsInde: true } }; }, methods: { // 单选 options1CheckChg(value) { let checkedCount = value.length; this.coefficientAdjustShowForm.option1CheckAll = checkedCount === this.headerShowList.option1.length; this.coefficientAdjustShowForm.options1IsInde = checkedCount > 0 && checkedCount < this.headerShowList.option1.length; }, options2CheckChg(value) { let checkedCount = value.length; this.coefficientAdjustShowForm.option2CheckAll = checkedCount === this.headerShowList.option2.length; this.coefficientAdjustShowForm.options2IsInde = checkedCount > 0 && checkedCount < this.headerShowList.option2.length; }, // 全选 option1CheckAllChg(val) { this.coefficientAdjustShowForm.options1 = val ? this.headerShowList.option1 : []; this.coefficientAdjustShowForm.options1IsInde = false; }, option2CheckAllChg(val) { this.coefficientAdjustShowForm.options2 = val ? this.headerShowList.option2 : []; this.coefficientAdjustShowForm.options2IsInde = false; }, headFilterShow() { this.curThis.headFilter.visible = true; // 解决点击CheckBox时候,动静扭转了表头的数值 this.$nextTick(() => { this.coefficientAdjustShowForm.options1 = this.curThis.headFilter.value.option1; this.coefficientAdjustShowForm.options2 = this.curThis.headFilter.value.option2; this.options1CheckChg(this.coefficientAdjustShowForm.options1); this.options2CheckChg(this.coefficientAdjustShowForm.options2); }); }, handleClickUpdateThead() { // 当表头数据特地多的时候清空table数据,解决卡顿问题 // this.curThis.tableData = []; // 排序 let list1 = []; let option1 = this.curThis.headerShowList.option1; if (option1.length > 0) { option1.forEach((item) => { if (this.coefficientAdjustShowForm.options1.length > 0) { this.coefficientAdjustShowForm.options1.forEach((item1) => { if (item == item1) { list1.push(item); } }); } }); } let list2 = []; let option2 = this.curThis.headerShowList.option2; if (option2.length > 0) { option2.forEach((item) => { if (this.coefficientAdjustShowForm.options2.length > 0) { this.coefficientAdjustShowForm.options2.forEach((item1) => { if (item == item1) { list2.push(item); } }); } }); } this.curThis.headFilter.value.option1 = list1; this.curThis.headFilter.value.option2 = list2; // 贮存到storage外面 this.curThis.king_setConceal(this.curThis.$route.path, this.curThis.headFilter.value); this.headFilter.visible = false; // // 触发扭转 // this.$emit('headFilterShowChg'); } }};</script><style></style>步骤二:建设vue单页面<template> <div> <tableHeadAdjust :tableData="tableData" :headerShowList="headerShowList" :headFilter="headFilter" :curThis="this"></tableHeadAdjust> <el-table :data="tableData" style="width: 100%"> <el-table-column prop="date" label="日期" width="180"> </el-table-column> <el-table-column prop="name" label="姓名" width="180"> </el-table-column> <!-- 形式一:同一级表头 --> <!-- <el-table-column v-for="(item, index) in headFilter.value.option1" :key="index + 'option1'" :label="item" :prop="tableHeadeTryList[item]"> </el-table-column> <el-table-column v-for="(item, index) in headFilter.value.option2" :key="index + 'option2'" :label="item" :prop="tableHeadTestList[item]"> </el-table-column> --> <!-- 形式二:父子表头 --> <el-table-column v-for="(item, index) in headFilter.value.option1" :key="index + 'option1'" :label="item"> <el-table-column v-for="(item, index) in headFilter.value.option2" :key="index + 'option2'" :label="item" :prop="tableHeadTestList[item]" > </el-table-column> </el-table-column> </el-table> </div></template><script>import tableHeadAdjust from '@/components/tableHeadAdjust.vue';export default { name: 'sysIndex', components: { tableHeadAdjust }, data() { return { tableData: [], headFilter: { visible: false, value: { option1: [], option2: [] } }, headerShowList: { option1: ['测试1', '测试2', '测试3', '测试4', '测试5', '测试6', '测试7'], option2: ['试验1', '试验2', '试验3', '试验4', '试验5', '试验6', '试验7'] } }; }, computed: { tableHeadeTryList() { return { 测试1: 'try1', 测试2: 'try2', 测试3: 'try3', 测试4: 'try4', 测试5: 'try5', 测试6: 'try6', 测试7: 'try7' }; }, tableHeadTestList() { return { 试验1: 'test1', 试验2: 'test2', 试验3: 'test3', 试验4: 'test4', 试验5: 'test5', 试验6: 'test6', 试验7: 'test7' }; } }, mounted() { // userMark为了辨别是哪个用户的表头,您能够依据手机号或者id用户的惟一标识来做 localStorage.setItem('userMark', 'userMark1'); // 初始化表格表头 this.king_tableConceal(this); this.tableData = [ { date: '2016-05-02', name: '王小虎', try1: '好的1', try2: '好的2', try3: '好的3', try4: '好的4', try5: '好的5', try6: '好的6', try7: '好的7', test1: '没方法1', test2: '没方法2', test3: '没方法3', test4: '没方法4', test5: '没方法5', test6: '没方法6', test7: '没方法7' }, { date: '2016-05-04', name: '王小虎', try1: '好的1', try2: '好的2', try3: '好的3', try4: '好的4', try5: '好的5', try6: '好的6', try7: '好的7', test1: '没方法1', test2: '没方法2', test3: '没方法3', test4: '没方法4', test5: '没方法5', test6: '没方法6', test7: '没方法7' } ]; }, methods: { /* reson:上面这些办法能够放到全局办法外面方便使用 author:king之浪迹天涯 */ /* * 初始化表格显示暗藏项 */ king_tableConceal(curThis) { let headerShowList = curThis.king_getConceal(curThis.$route.path); curThis.headFilter.value = headerShowList ? headerShowList : { option1: curThis.headerShowList.option1, option2: curThis.headerShowList.option2 }; }, /** * 获取用户表格显示暗藏项 * @param path */ king_getConceal(path) { let USER_ID = localStorage.getItem('userMark'); let USER_TABLEHEADADUST = localStorage.getItem('USER_TABLEHEADADUST'); USER_TABLEHEADADUST = USER_TABLEHEADADUST ? JSON.parse(USER_TABLEHEADADUST) : {}; if (USER_TABLEHEADADUST.hasOwnProperty(USER_ID) && USER_TABLEHEADADUST[USER_ID].hasOwnProperty(path)) return USER_TABLEHEADADUST[USER_ID][path]; return ''; }, /** * 存储用户表格显示暗藏项 * @param path、theader */ king_setConceal(path, conceal) { // userMark为了辨别是哪个用户的表头,您能够依据手机号或者id用户的惟一标识来做 let USER_ID = localStorage.getItem('userMark'); let USER_TABLEHEADADUST = localStorage.getItem('USER_TABLEHEADADUST'); USER_TABLEHEADADUST = USER_TABLEHEADADUST ? JSON.parse(USER_TABLEHEADADUST) : {}; if (!USER_TABLEHEADADUST.hasOwnProperty(USER_ID)) { USER_TABLEHEADADUST[USER_ID] = { [path]: conceal }; } else { USER_TABLEHEADADUST[USER_ID][path] = conceal; } localStorage.setItem('USER_TABLEHEADADUST', JSON.stringify(USER_TABLEHEADADUST)); } }};</script><style></style>

August 17, 2022 · 4 min · jiezi

关于element-ui:Elementvuecli4配置elementui按需引入

参考地址:《Vue-cli4 配置 element-ui 按需引入》 装置完element-ui后,如果残缺引入,不按需加载其组件,打出的包会很大,这很影响性能。 上面,依照官网的教程,咱们来操作一下,如何配置element-ui按需加载组件。 首先要增加babel-plugin-component依赖,代码如下: npm install babel-plugin-component -D上面就该写plugins配置项了,这就是重点了,依照官网的教程,肯定会失败,因为官网是依照vue-cli@3写的,在vue-cli@4环境下,咱们须要批改babel.config.js文件,代码如下: module.exports = { presets: [ '@vue/cli-plugin-babel/preset' ], plugins: [[ 'component', { libraryName: 'element-ui', styleLibraryName: 'theme-chalk' } ]]}之后就是在main.js中按需引入组件了,示例代码如下: import Vue from 'vue'import App from './App.vue'import router from './router'import store from './store'import { Dialog, Table, TableColumn, Tag, Container, Header, Main, Row, Col} from 'element-ui'Vue.use(Dialog)Vue.use(Table)Vue.use(TableColumn)Vue.use(Tag)Vue.use(Container)Vue.use(Header)Vue.use(Main)Vue.use(Row)Vue.use(Col)Vue.config.productionTip = falsenew Vue({ router, store, render: h => h(App)}).$mount('#app')—完—

August 10, 2022 · 1 min · jiezi

关于element-ui:elementui源码学习之仿写一个eltag

本篇文章记录仿写一个el-divider组件细节,从而有助于大家更好了解饿了么ui对应组件具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续闲暇了会不断更新并仿写其余组件。源码在github上,大家能够拉下来,npm start运行跑起来,联合正文有助于更好的了解。github仓库地址如下:https://github.com/shuirongsh...组件需要剖析对于tag组件,次要是用于展现一些标签信息,个别的需要有如下: tag标签文字色彩自定义tag标签背景色自定义tag标签边框色彩自定义管制是否展现敞开tag标签小叉号图标自定义tag标签的文字色彩、背景色、边框色彩标签的大小类型(大型、中型、小型标签)饿了么官网应用的是render函数编写的el-tag,所以这里咱们也应用render函数去写。整体来说,这个组件还是比较简单的。留神一下jsx的语法即可。 组件效果图 看成果的话,间接复制粘贴运行跑起来,联合正文更有助于了解。最残缺的代码在github上哦 应用之代码<template> <div> <my-divider lineType="dotted" content-position="left" >默认标签款式</my-divider > <my-tag>默认标签</my-tag> <my-tag closable>默认标签可敞开</my-tag> <my-divider lineType="dotted" content-position="left" >类型标签款式</my-divider > <my-tag type="primary">类型标签primary</my-tag> <my-tag type="primary" closable>类型标签primary可敞开</my-tag> <my-tag type="success">类型标签success</my-tag> <my-tag type="success" closable>类型标签success可敞开</my-tag> <my-tag type="info">类型标签info</my-tag> <my-tag type="info" closable>类型标签info可敞开</my-tag> <my-tag type="warning">类型标签warning</my-tag> <my-tag type="warning" closable>类型标签warning可敞开</my-tag> <my-tag type="danger">类型标签danger</my-tag> <my-tag type="danger" closable>类型标签danger可敞开</my-tag> <my-divider lineType="dotted" content-position="left" >自定义标签款式</my-divider > <my-tag color="blue">标签文字色彩自定义</my-tag> <my-tag bgColor="pink">标签背景色彩自定义</my-tag> <my-tag borderColor="red">标签边框色彩自定义</my-tag> <my-divider lineType="dotted" content-position="left" >中等标签及大型标签</my-divider > <my-tag type="primary" sizeType="big" closable>大型标签</my-tag> <my-tag type="success" sizeType="medium" closable>中型标签</my-tag> <my-tag style="cursor: pointer" type="info" sizeType="small" >默认(小型)标签,sizeType="small"写不写都行的</my-tag > <my-divider lineType="dotted" content-position="left" >动静编辑标签</my-divider > <my-tag v-for="(item, index) in arr" closable @close="handleClose(item)" @click="handleClick(item)" type="success" :key="item" >{{ item }}</my-tag > <el-input v-model.trim="val" @blur="blurFn" size="mini" style="width: 120px" ></el-input> </div></template><script>export default { data() { return { arr: ["标签一", "标签二", "标签三"], val: "", }; }, methods: { blurFn() { if (this.val === "") return; this.arr.push(this.val); this.val = ""; }, handleClose(tag) { // 找到点击的是哪个 let i = this.arr.findIndex((item) => { return tag === item; }); // 删除之 this.arr.splice(i, 1); }, handleClick(tag) { console.log("点击标签啦", tag); }, },};</script>封装组件的代码<script>const typeArr = ["primary", "success", "info", "warning", "danger"]; // 标签类型数组const sizeType = ["big", "medium", "small"]; // 标签大小数组export default { name: "myTag", props: { closable: Boolean, // 是否展现可敞开的小叉号图标 color: String, // 标签文字的色彩 bgColor: String, // 标签背景色 borderColor: String, // 标签边框色彩 // 五种标签类型 type: { type: String, validator(val) { return typeArr.includes(val); // 校验类型 }, }, // 三种标签大小 sizeType: { type: String, validator(val) { return sizeType.includes(val); // 校验大小 }, }, }, methods: { handleClose(event) { /* 阻止冒泡避免与下方的handleClick办法抵触,要不然点击close敞开小图标,也会 触发下方click事件的执行。即:内层事件阻止冒泡与外层事件隔离开来 */ event.stopPropagation(); this.$emit("close", event); }, handleClick(event) { this.$emit("click", event); }, }, // render函数jsx语法更加灵便 render(h) { // 1. 筹备款式类 class绑定classArr数组罕用款式,style绑定props变量自定义款式 const classArr = ["my-tag", this.type, this.sizeType]; // 2. 筹备一个dom,并绑定相干class、style、event const tagEl = ( <span class={classArr} style={{ backgroundColor: this.bgColor, color: this.color, borderColor: this.borderColor, }} on-click={this.handleClick} > {/* 默认插槽渲染内容即my-tag标签中的文字 */} {this.$slots.default} {/* 三元表达式条件管制是否渲染敞开小图标 */} {this.closable ? ( <span class="close-tag" on-click={this.handleClose}> x </span> ) : null} </span> ); // 3. 返回render渲染之 return <transition name="el-fade-in">{tagEl}</transition>; // 应用饿了么UI自带的突变过渡动画 },};</script><style scoped>/* 默认标签款式 */.my-tag { display: inline-block; box-sizing: border-box; padding: 0 8px; color: #252525; background-color: #fafafa; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 12px; white-space: nowrap; height: auto; line-height: 20px; margin: 0 8px 8px 0;}/* 标签敞开小叉号款式 */.close-tag { position: relative; margin-left: 5px; cursor: pointer; display: inline-block; transform: translateY(-6%);}/* 5种类型标签款式 */.primary { color: #409eff; border: 1px solid #d9ecff; background-color: #ecf5ff;}.success { background-color: #f0f9eb; border-color: #e1f3d8; color: #67c23a;}.info { background-color: #f4f4f5; border-color: #e9e9eb; color: #909399;}.warning { background-color: #fdf6ec; border-color: #faecd8; color: #e6a23c;}.danger { background-color: #fef0f0; border-color: #fde2e2; color: #f56c6c;}/* 默认小型标签款式,可选值为中等标签、大型标签。当然这里没有small,因为small就是默认的 */.big { padding: 4px 10px;}.medium { padding: 2px 10px;}</style>总结大家封装本人的组件的时候,最好借鉴其余UI组件库,比方这里仿写el-tag也是参照了antD的设计形式。再一个就是仿写组件,不是把官网的组件全副照搬过去,而是适当取舍,保留比拟罕用的组件性能,临时摒弃冷门组件性能,并退出本人公司罕用的性能,以及本人的了解如果有遇到冷门的组件性能,能够思考再独自封装一个组件去解决组件须要集成一些性能,然而不能集成十分多的性能,高内聚自己程度无限,说的不肯定对,仅供各位道友参考 ^_^

August 8, 2022 · 2 min · jiezi

关于element-ui:elementui源码学习之仿写一个eldivider

本篇文章记录仿写一个el-divider组件细节,从而有助于大家更好了解饿了么ui对应组件具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续闲暇了会不断更新并仿写其余组件。源码在github上,大家能够拉下来,npm start运行跑起来,联合正文有助于更好的了解。github仓库地址如下:https://github.com/shuirongsh...组件需要剖析对于分割线的组件,个别应用的场景有: 分割线之程度宰割(如:段落与段落之间分隔)程度分割线加上文字描述(文字描述地位个别是位于分割线的左侧、居中、右侧)宰割类型之垂直宰割(横向的行内文字与文字之间的宰割)分割线款式类型(solid分割线或dashed分割线或dotted分割线) 因为垂直宰割间隔不够,所以垂直宰割没有文字描述组件中用到的知识点函数式组件咱们晓得,一个函数,其实就是一个加工流水线,咱们入参,通过函数的加工当前,失去return加工后的后果。 对于组件而言,其实也能够当做一个函数(函数式组件),咱们传递参数,组件props接管,而后组件再依据传参的不同,渲染出对应的款式成果。 这种形式和原来的咱们应用组件的形式其实差不多,只不过更加精简,毕竟只思考接管参数,没有生命周期、this实例之类的。所以函数式组件的渲染效率会比一般组件高。 所以有些状况下,应用函数式组件效率会更高 函数式组件的两种定义形式比方,通过传参形式去渲染文字,能够有以下两种形式 形式一:render函数定义 <script>export default { functional: true, // 肯定要指明是函数式组件 props: { bookName: { type: String, default: "斗破天穹", }, }, // context上下文,有点像this的意思。但不一样 render: function (createElement, context) { // 创立一个h3标签,标签内容是上下文对象中的props中的bookName字段 return createElement("h3", {}, context.props.bookName); },};</script>形式二:template定义 <!-- 模板标签上加上functional关键字表明是函数式组件 --><template functional> <div> <h3>{{ props.bookName }}</h3> </div></template><script> export default { props: { bookName: { type: String, default: "斗破天穹", }, }, }</script>对于函数式组件的具体细节,详情见官网文档:https://cn.vuejs.org/v2/guide...这里为什么要提到函数式组件呢?因为el-divider组件就是应用函数式组件进行封装的(因为组件只是做宰割线条的展现,所以不须要有this实例,生命周期之类的) 故:为了晋升渲染效率,这里应用函数式组件 应用函数式组件的状况大抵有以下: 只做展现的组件,毕竟没啥逻辑操作相干高阶组件的操作循环中也能够思考应用整体来说,函数式组件还是比拟灵便的解决一像素太粗的问题先看一下问题图 只须要给对应dom元素略微缩放一下即可: transform: scaleY(0.95); 或 transform: scaleX(0.95); ...

August 2, 2022 · 2 min · jiezi

关于element-ui:vue-element-表格内的复制粘贴功能

https://blog.csdn.net/weixin_...

July 25, 2022 · 1 min · jiezi

关于element-ui:踩坑ElementUi中form组件的一些坑注意事项or巧妙用法

前言做我的项目用ElementUI组件的时候,因为有些业务需要,官网不可能有咱们我的项目中业务所有的例子阐明,所以在这里纪录了一下平时在写我的项目的时候遇到的一些问题。 一、form组件的 model 的数据类型必须是 Object问题背景有个这样的需要:做一个循环表单,表单的双向绑定的值应该就是一个数组,表单属性 :model 的值就须要写成 :model="类.数组" ,如果间接把数组赋给它,写成这样 :model="数组" 就会报错,如下图所示 正确示例//数据formData: { id: 1, name: '湖南师范大学', gradeList: [ { id: 1, name: '一年级', classList: [ { id: 1, name: '01班' }, { id: 2, name: '02班级' } ] } ] }<!-- form表单中model的值 formData 必须为 Object 类型 --> <el-form :model="formData" ref="ruleForm" label-width="100px" class="demo-ruleForm"> <template v-for="(grade, index) in formData.gradeList"> <el-form-item label="班级名字" :prop="'gradeList.' + index + '.name'" :rules="{required: true, message: '请输出年级',trigger: 'blur'}"> <el-input v-model="grade.name"></el-input> </el-form-item> </template> </el-form>二、循环表单中的表单验证问题有时候有这样的需要:一个学校相干信息的输出表单外面嵌套着各个年级信息的表单(单层循环表单),一个年级外面又有多个班级信息的表单(多层嵌套表单),这个时候对外面的各个输入框做表单验证,该怎么做呢?把prop属性外面的匹配写对就能够了,大抵是上面这个写法://数据formData: { id: 1, name: '湖南师范大学', gradeList: [ { id: 1, name: '一年级', classList: [ { id: 1, name: '01班' }, { id: 2, name: '02班级' } ] } ] }1、单层循环表单 <!-- prop是这样写 :prop="'gradeList.' + index + '.name'" --> <el-form :model="formData" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"> <template v-for="(grade, index) in formData.gradeList"> <el-form-item label="年级名字" :prop="'gradeList.' + index + '.name'" :rules="{required: true, message: '请输出年级',trigger: 'blur'}"> <el-input v-model="grade.name"></el-input> </el-form-item> </template> </el-form>2、双层循环表单 <!-- 第二层的 :prop 是这样写 :prop="'gradeList.' + index + '.name'" --> <el-form :model="formData" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"> <template v-for="(grade, index) in formData.gradeList"> <el-form-item label="年级名字" :prop="'gradeList.' + index + '.name'" :rules="{required: true, message: '请输出年级',trigger: 'blur'}"> <el-input v-model="grade.name"></el-input> </el-form-item> <template v-for="(class, classIndex) in grade.classList"> <el-form-item label="班级名字" :prop="'gradeList.' + index + '.classList.' + classIndex + '.name'" :rules="{required: true, message: '请输出班级',trigger: 'blur'}"> <el-input v-model="class.name"></el-input> </el-form-item> </template> </template> </el-form>依此类推,多层循环表单也能够依照双层循环表单中 prop 属性的格局来写。 ...

July 20, 2022 · 1 min · jiezi

关于element-ui:elementui源码学习之仿写一个elcard

本篇文章记录一下,仿写一个el-card组件,有助于大家更好了解,饿了么ui的轮子具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续闲暇了会不断更新并仿写其余组件。源码在github上,大家能够拉下来,npm start运行跑起来,联合正文有助于更好的了解。github仓库地址如下:https://github.com/shuirongsh...集体愚见对于卡片card组件,个别在应用中,次要还是card的交互成果,比方暗影成果。饿了么官网提供的card组件除了通过传参管制暗影呈现的机会,额定还提供了一个卡片头部插槽。好是好,不过个别用不到,因为卡片内容基本上都是本人写的,如果还应用头部插槽,可能须要多一些/deep/ 去管制款式,倒不如本人改写封装一个 自己看了饿了么el-card组件当前,也封装了一个my-card组件,没有退出原有的头部插槽#header,不过多加了一些交互成果,整体有以下成果: 暗影呈现的机会(原有性能) 鼠标悬浮呈现总是呈现不呈现鼠标悬浮卡片稍微上移鼠标悬浮卡片放大一些鼠标悬浮卡片反转(即多了一个slot="back"的插槽用于传递反面的内容)以及管制侧面、反面的款式变量cardStyle和backCardStyle咱们先看一下效果图 效果图 大家有什么好的录制gif软件能够分享我一下哦。我的这个软件录制进去的gif成果不太好。 组件中所用到的低频知识点perspective属性:示意咱们看到的与z=0立体的间隔,能够做三维地位变换透视成果 官网:https://developer.mozilla.org... backface-visibility:hidden属性:指定当元素反面朝向观察者时藏起来 官网:https://developer.mozilla.org... 实现思路就是将两个要展现的div利用定位重叠在一起,其中一个首先围绕Y轴旋转肯定角度,而后搭配backface-visibility:hidden先藏起啦。鼠标悬浮的时候,整个旋转,就呈现不可见到可见的一个成果啦,翻转动画就有喽this.$slots属性:寄存插槽的对象,能够存命名插槽、或者default一般插槽。 比方外界传递<div slot="back">反面的内容</div> 那么console.log("this.$slots", this.$slots); 就能够看到是否传递进来插槽了。本例中可用于判断是否开启翻转卡片模式,而后通过:class的数组用法来动静增加类名,即可实现上述效果图 大家打印一下就明确,这个很简略。 应用组件的代码<template> <div class="box"> <my-card class="cardClass" shadow="hover">悬浮出暗影</my-card> <my-card class="cardClass" shadow="always">始终出暗影</my-card> <my-card class="cardClass" shadow="none">没有暗影</my-card> <my-card class="cardClass" shadow="hover" isHoverUp>悬浮出暗影上移</my-card> <my-card class="cardClass" shadow="always" isHoverUp>始终出暗影上移</my-card> <my-card class="cardClass" shadow="none" isHoverUp>没有暗影上移</my-card> <my-card class="cardClass" shadow="hover" zoomCard>悬浮出暗影放大</my-card> <my-card class="cardClass" shadow="always" zoomCard>始终出暗影放大</my-card> <my-card class="cardClass" shadow="none" zoomCard>没有暗影放大</my-card> <my-card class="cardClass" :cardStyle="{ padding: 0 }" shadow="hover" >应用cardStyle去管制款式,比方这里革除内边距</my-card > <my-card class="cardClass cardClass2" :cardStyle="{ background: 'pink' }" :backCardStyle="{ background: '#baf' }" >悬浮卡片翻转(侧面) <!-- 当有命名插槽back的时候,主动开启翻转模式 --> <div slot="back">反面的内容</div> </my-card> </div></template><style lang='less' scoped>.box { display: flex; flex-wrap: wrap; box-sizing: border-box; padding: 24px; .cardClass { width: 240px; margin-right: 24px; margin-bottom: 24px; } .cardClass2 { height: 180px; }}</style>封装的组件代码<template> <div :class="[ 'card-box', this.$slots.back ? 'card-reverse' : '', zoomCard ? 'card-box-zoom' : '', ]" > <div class="card-content"> <!-- 当有back命名插槽时,加上frontReverse类名并移除front-side类名,才有反转成果 --> <div :style="cardStyle" :class="[ this.$slots.back ? 'frontReverse' : 'front-side', shadow, isHoverUp ? 'isHoverUp' : '', ]" > <!-- 失常状况下一般插槽显示内容即可 --> <slot></slot> </div> <div :style="backCardStyle" class="backReverse" v-if="this.$slots.back"> <!-- 有命名插槽就显示命名插槽内容,并做类名移除和新增,开启翻转成果 --> <slot name="back" /> </div> </div> </div></template><script>const shadowArr = ["hover", "always", "none"]; // shadow="none"不传递也行的export default { name: "myCard", props: { cardStyle: {}, // 管制卡片(侧面的款式) backCardStyle: {}, // 管制反面卡片的款式 shadow: { // 暗影呈现机会:鼠标悬浮呈现、始终呈现、或不呈现 type: String, validator(val) { // 校验 if (shadowArr.includes(val)) return true; return false; }, }, isHoverUp: Boolean, // 是否悬浮往上平移一点 zoomCard: Boolean, // 是否放大卡片(hover时) }, mounted() { console.log("this.$slots", this.$slots); },};</script><style lang="less" scoped>.card-box { // background-color: #fff; /* 留神卡片盒子不能加背景色,会挡住旋转款式成果 */ color: #333; perspective: 1000; transform-style: preserve-3d; transition: all 0.4s;}// 加card-box-zoom类名,就整体放大1.08倍.card-box-zoom:hover { transform: scale(1.08);}// 直达的用于定位的容器盒子.card-content { position: relative; width: 100%; height: 100%; transition: 0.75s; transform-style: preserve-3d;}/* 应用front-side类名管制一般状态时的款式 */.front-side { box-sizing: border-box; padding: 18px; border-radius: 4px; border: 1px solid #e9e9e9; transition: 0.3s;}// 有hover类名时,在hover时,就加暗影.hover:hover { box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);}// 有isHoverUp类名时,就在hover时往上挪动一点.isHoverUp:hover { transform: translateY(-3px);}// 有always类名时,就加暗影.always { box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);}/* 应用frontReverse和backReverse类名专门管制卡片反转状态时的款式 */.frontReverse, // 利用定位使前前面重叠.backReverse { position: absolute; top: 0; left: 0; right: 0; bottom: 0; backface-visibility: hidden; transform-style: preserve-3d; box-sizing: border-box; padding: 18px; border-radius: 4px; border: 1px solid #e9e9e9; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);}.frontReverse { z-index: 2; // 后面层级贬低}.backReverse { transform: rotateY(-180deg); // 前面旋转不可见}.card-reverse:hover .card-content { // hover时候,旋转容器,就会呈现,不可见到可见的过程了,翻转动画就有了 transform: rotateY(180deg);}</style>至于css兼容性的话,大家能够本人加上浏览器厂商的后缀呗总结复制粘贴,即可呈现成果。如果对您有一点点帮忙,欢送github给个star哦因为是系列文章,您的激励是咱创作的能源^_^

July 20, 2022 · 2 min · jiezi

关于element-ui:elementui源码学习之仿写一个eltabs

本篇文章记录一下,仿写一个el-tabs组件,有助于大家更好了解,饿了么ui的轮子具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续闲暇了会不断更新并仿写其余组件。源码在github上,大家能够拉下来,npm start运行跑起来,联合正文有助于更好的了解。github仓库地址如下:https://github.com/shuirongsh...知识点温习为了更好的浏览后续代码,咱们须要再来温习一下常识 vue中的render函数书写jsx语法vue中咱们写组件页面,经常是构造、逻辑、款式拆散,如: <template> <!-- 这里写构造 --></template><script> // 这里写逻辑</script><style> // 这里写款式</style>如果大家相熟react语法,就会发现,react中是把构造和逻辑书写在一块的(jsx)语法,其实vue中也是能够应用jsx语法的,不过要在render函数中去写。比方咱们要应用render函数写一个红色字体的H3标签、背景色黄绿色。代码能够如下书写: <script>export default { data() { return { name: "孙悟空" }; }, render(h) { /** * 第一步,筹备一个dom,dom中应用单大括号作为占位符,单大括号中能够应用变量 * vue中个别是双大括号中应用变量,区别不大。再一个就是中间应用小括号 * 包裹(不便换行书写) * */ let dom = ( <div class="box"> <h3 class="h3Class">{this.name}</h3> </div> ); // 第二步,返回。如此render函数就会主动翻译渲染之 return dom; },};</script><style>.box { background: yellowgreen; }.h3Class { color: red; }</style>效果图: 上述代码咱们只须要记住,jsx语法中应用单大括号去示意变量应用。 再一个就是render函数中,如何给子组件传参数呢?也是应用单大括号搭配点点点...,因为单大括号才示意变量。如下代码: render(h) { const sendParamsData = { // 筹备参数 props: { name: this.name, age: this.age, home: this.home, }, }; return ( <div class="kkk"> {/* 传递参数 */} <child {...sendParamsData}></child> </div> ); },饿了么官网el-tabs组件就是应用了jsx语法进行编写的(因为jsx语法更加灵便),故:一般业务需要template够用了。灵便简单需要,思考应用jsx ...

July 17, 2022 · 4 min · jiezi

关于element-ui:element-backtop组件

当鼠标在container容器中滚动高度 间隔container顶部 超过400px时,回到顶部按钮会展现,点击按钮会回到container顶部父组件: <template> <div class="container"> <back-top target=".container" :visibility-height="400"> </back-top> <div class="content"></div> </div></template><script>import BackTop from "@/components/BackTop";export default { components: { "back-top": BackTop, }, data() { return {}; },};</script><style scoped>.container { height: 300px; background-color: aqua;}.content { height: 1000px;}</style>子组件: <template> <div v-if="visible" class="el-backtop" @click.stop="handleClick()" :style="{ bottom: styleBottom, right: styleRight }" > <slot><i class="el-icon-arrow-up"></i></slot> </div></template><script>import throttle from "throttle-debounce/throttle";const cubic = (value) => Math.pow(value, 3);const easeInOutCubic = (value) => value < 0.5 ? cubic(value * 2) / 2 : 1 - cubic((1 - value) * 2) / 2;export default { name: "BackTop", props: { target: String, visibilityHeight: { type: Number, default: 200, }, bottom: { type: Number, default: 40, }, right: { type: Number, default: 40, }, }, data() { return { el: null, container: null, visible: false, }; }, computed: { styleBottom() { return `${this.bottom}px`; }, styleRight() { return `${this.right}px`; }, }, created() {}, mounted() { this.init(); this.throttledScrollHandler = throttle(300, this.onScroll); this.container.addEventListener("scroll", this.throttledScrollHandler); }, methods: { init() { if (this.target) { this.el = document.querySelector(this.target); if (!this.el) { throw new Error(`target is not existed: ${this.target}`); } this.container = this.el; } }, onScroll() { this.visible = this.el.scrollTop >= this.visibilityHeight; }, handleClick() { const el = this.el; const beginTime = Date.now(); const beginValue = el.scrollTop; const rAF = window.requestAnimationFrame || ((func) => setTimeout(func, 16)); const frameFunc = () => { const progress = (Date.now() - beginTime) / 500; if (progress < 1) { el.scrollTop = beginValue * (1 - easeInOutCubic(progress)); rAF(frameFunc); } else { el.scrollTop = 0; } }; rAF(frameFunc); }, },};</script><style>.x-backtop { position: fixed;}</style>

July 14, 2022 · 2 min · jiezi

关于element-ui:elementui源码学习之仿写一个elbadge标记

本篇文章记录一下,仿写一个el-badge标记提醒,有助于大家更好了解,饿了么ui的轮子具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续闲暇了会不断更新并仿写其余组件。源码在github上,大家能够拉下来,npm start运行跑起来,有助于更好的了解。github仓库地址如下:https://github.com/shuirongsh...知识点温习还是像平常一样,为了便于更好的了解代码,咱们先温习一下,el-badge组件中应用的一些曝光度不是十分高的知识点api sup和sub标签sup标签可定义文本上标内容(如平方、立方、未读音讯等...)sub标签可定义文本下标内容(个别是迷信公式多一些)代码举例: <h5>未读音讯<sup style="color:red">99+</sup></h5><h5>水是生命之源,化学分子式为:H<sub style="color:brown">2</sub>O</h5>效果图: 由此咱们能够明了,sup标签内写的文字,会主动放在右上方,也能够失常设置款式,所以应用sup标签用来做el-badge标记组件,确实是比拟适合的。 不过因为须要应用插槽传入定义内容,所以饿了么UI中应用sup标签不像上述嵌套的,相当于并排的,如:<h5>未读音讯</h5><sup style="color:red">99+</sup> 所以饿了么又通过款式定位批改其地位,使其在右上角了 props中的validator校验函数假如需要:父组件传递给子组件的age属性字段的值须要为数字类型的 咱们个别都会这样写: props: { age: Number,},或者这样写(额定指定一个默认值): props: { age: { type: Number, default: 100, }},这样写个别也就够用了,不过如果要精细化校验,就须要应用props校验某个属性字段自带的validator函数了。 比方新需要:父传子的age属性字段需为数字类型、且不能超过180 于是乎,咱们应用validator函数能够这样写: props: { age: { type: Number, default: 100, validator(val) { // validator函数接管的参数是父传子此字段的值 if (val <= 180) { return true; // 返回true代表校验通过,不报[Vue warn]正告 } else { return false; // 返回false代表校验不通过,报[Vue warn]正告,告知用户传值不对 } }, },}这样的话,确实是更不便精细化管制父传子参数了。官网阐明:https://cn.vuejs.org/v2/guide... 仿写效果图 应用代码<template> <div class="wrap"> <my-badge :value="11" type="primary"> <h5>primary类型</h5> </my-badge> <br /> <br /> <my-badge :value="22" type="success"> <h5>success类型</h5> </my-badge> <br /> <br /> <my-badge value="0" type="warning"> <h5>warning类型</h5> </my-badge> <br /> <br /> <my-badge :value="44" type="info"> <h5>info类型</h5> </my-badge> <br /> <br /> <my-badge :value="55" type="danger"> <h5>danger类型</h5> </my-badge> <br /> <br /> <my-badge :value="188" :max="99"> <h5>指定max最大值99</h5> </my-badge> <br /> <br /> <my-badge is-dot> <h5>小圆点</h5> </my-badge> <br /> <br /> <my-badge value="热点追踪"> <h5>《震惊!一程序猿青天白日居然...网友必看!》</h5> </my-badge> <br /> <br /> <my-badge :isShow="isShow" value="^@^"> <h5>暗藏</h5> </my-badge> <br /><button @click="isShow = !isShow">暗藏显示切换</button> </div></template><script>export default { data() { return { isShow: true } },};</script><style lang="less" scoped> .wrap { width: 100%; height: 100%; padding: 24px;} </style>仿写封装代码<template> <div class="my-badge"> <slot></slot> <!-- 应用sup上标,让sup标签内的文字内容渲染在的右上角(须要嵌套),然而 这里的写法不会让sup标签的文字间接渲染到右上角,还需定位挪动管制一下款式 --> <transition name="el-zoom-in-center"> <!-- el-zoom-in-center过渡动画是自带的哦,咱们间接加上就能用啦 --> <sup v-show="showSup" :class="[ 'fixedRightTop', typeArr.includes(type) ? type : '', /** 类型数组是否蕴含传进来的类型,蕴含就利用此类型款式,不蕴含就不利用类型款式 */ isDot ? 'isDotClass' : '', /** isDot为true就加上小圆点款式类型 */ ]" v-text="showValue" ></sup> </transition> </div></template><script>// 定义这五种类型const typeArr = ["primary", "success", "warning", "info", "danger"];export default { name: "myBadge", props: { value: [String, Number], type: { type: String, validator(val) { // console.log("校验参数", val); // props也能够退出类型校验函数,vue自带的哦,不合乎就抛出正告 if (typeArr.includes(val)) { return true; } else { return false; } }, }, max: { type: Number, validator(val) { // 校验最大值要是数字 if (val) { if (typeof val === "number") { return true; } else { return false; } } else { return true; } }, }, isDot: Boolean, isShow: { // 默认展现 type: Boolean, default: true, }, }, data() { return { typeArr } }, computed: { showValue() { // 如果是小圆点,就不必返回值 if (this.isDot) { return; } // 如果告知最大值,就做一个判断 if (this.max) { return this.value > this.max ? `${this.max}+` : this.value; } // 其余的状况,无论是数字或者自定义文字,就失常显示即可 else { return this.value; } }, showSup() { // isShow为false就暗藏喽 if (!this.isShow) { return false; } // 内容为空,也暗藏咯 if (this.value === "") { return false; } // 其余失常显示 return true; }, },};</script><style lang="less" scoped>.my-badge { position: relative; vertical-align: middle; display: inline-block; // 把块元素转换成行内块元素,如此,宽度便由内容撑开了 // 通过定位,把上标定位到右上角的哦 .fixedRightTop { position: absolute; // 因为上方display: inline-block;了 top: 0; // 所以定位才正好在插槽内容的右上方了,否则块元素默认宽度100%,那定位就在最右侧了 right: 3px; // 然而还须要transform平移一下 } sup { color: #fff; background-color: #f56c6c; // 默认淡红色 border-radius: 10px; // 加个圆角难看些 padding: 1px 4px; font-size: 12px; // 上标字体要设置最小 transform: translate(100%, -50%); // 要挪动一下才行 white-space: nowrap; // 自定义文字内容会换行,通过css管制,使之不换行 } // 五种类型配色,这里间接抄官网的 .primary { background-color: #409eff; } .success { background-color: #67c23a; } .warning { background-color: #e6a23c; } .info { background-color: #909399; } .danger { background-color: #f56c6c; } // 小圆点加款式 .isDotClass { height: 8px; width: 8px; right: 1px; border-radius: 50%; }}</style>总结好了,一篇water文章写完啦(手动捂脸哭),不过愚认为一直学习、一直输入、大抵便是不断进步吧 ...

July 11, 2022 · 3 min · jiezi

关于element-ui:elementui源码学习之仿写一个elmessage

问题形容工作中尽管应用工具库很高兴很高效,但咱们还是要抽空看看工具库的源码,因为源码中会用到一些不常常应用的api办法,记住这些api办法,可晋升本人的编程能力,有助于当前封装本人的工具库,从而更好的实现一些需要。 需要剖析组件封装之前,咱们要想一下要封装的这个组件的利用场景和应用需要有哪些,以此为突破口,便于更好的实现代码逻辑 利用场景和需要:音讯提醒愚认为,message次要是信息提醒,利用场景在于用户执行了一些操作,是否胜利或失败之类的交互反馈。所以,咱们能够定义这个要封装的组件有以下需要: 须要能够输出信息文字 message参数须要message信息的类型反馈(胜利反馈、正告反馈、谬误反馈、一般信息反馈)type参数须要提醒完当前,能够设定默认隐没工夫 duration参数当鼠标悬浮的时候保留这个音讯提醒,不让其隐没 定时器timer参数其余诸如 提醒小图标的类型和文字是否居中 之类的如果咱们看饿了么UI官网的组件,咱们会发现官网思考的还是非常具体的,给到了很多配置项Options参数,不过在咱们本人理论封装组件中,不须要像官网那样,做很多的配置项,只须要实现罕用的配置项即可,保留最实用的性能即可。 饿了么UI官网el-message组件:https://element.eleme.cn/#/zh...效果图 了解形式对于这个性能成果,集体倡议能够如下了解 先温习一下平时用的不多的api再把代码clone下来,跑起来(文末附上github代码仓库地址)联合正文,既可疾速了解了知识点温习之:class的数组用法和:style用法// html<div :class="[ 'messageBox', /* .messageBox这个类名确定要加到div这个标签上 */ center ? 'horizontal' : '', /* 是否给div标签加上.horizontal这个类名取决于center这个变量的值是否为true */ typeArr.includes(type) ? type : '', /* 是否给div这个标签加上type变量值的类名,取决于typeArr变量数组是否蕴含type的值 */ ]" :style="controlTop" /* 等价于:style={top: `12px`} 等价于 style="top: 12px" 即间隔顶部top值为12像素 */></div>// jsdata() { return { center: false, // 是否让程度文字居中,默认false type: "info", // 默认info类型 typeArr: ["info", "success", "warning", "error"], // 总共4种类型 };},computed: { controlTop() { return { top: `12px` }; }, },为什么要提到:class的数组用法以及:style的用法呢? ...

July 10, 2022 · 3 min · jiezi

关于element-ui:elementui的使用八

咱们的电商后盾管理系统最初还有商品治理、订单治理、数据统计三个模块没有实现,然而前面的内容和后面的基本相同,包含:显示数据、增加数据、编辑信息以及删除等操作 1.商品治理商品治理菜单中次要是用来显示商品数据并且蕴含一些基本操作:减少商品、编辑信息、删除等,以及商品参数和分类的治理 商品治理菜单中蕴含三个子菜单项:商品列表、分类参数、商品分类。 1.1 商品列表商品列表次要由Breadcrum面包屑、Card面板、Table表格、Button按钮组成 这部分和用户治理局部很相似,次要是前端向服务器发送数据申请,服务器收到申请,响应数据,返回给前端,前端把响应的数据存储在定义好的数组中,而后在Table表格中交给数据源model,而后每一个Table-item承受数组中的对应的字段信息。这样商品数据就展现进去了。 至于增加商品、编辑商品以及删除商品局部,和之前的都相似,次要是申请接口的变动,思路是统一的,不再赘述 1.2 分类参数分类参数中次要是对商品各个分类中的参数进行具体操作。 比拟重要的是级联选择器以及扩大按钮(expand) 咱们通过级联选择器抉择出指定的商品,而后就能够在下方的Table表格中批改它的参数。 Cascader级联选择器是咱们我的项目中常常应用的局部,个人感觉和Tree树形控件思维上很类似。 上面介绍一下Cascader的几个重要属性 value:选中项绑定值options:可选项数据源,也就是咱们级联选择器中显示数据的局部props:配置选项,也就是级联的选择器中的制订options数数据源中的数据,那个字段是显示数据,那个字段是children子选项等expand-trigger :次级菜单的开展形式,默认是click,我这里设置的hover还有一个重要的事件 change:当绑定值变动时触发事件,也就是咱们抉择好具体的三级目录时,会立即触发此事件,申请该分类的具体参数 整体思路是这样的: 首先咱们在页面创立结束时,前端向服务器发送数据申请,咱们把返回的数据存储在提前定义的数组中,而后把数组传给Cascader级联选择器的options属性(留神须要v-bind动静绑定),而后须要设置setpros,把它传给props,也就是配置选项,这样咱们的级联选择器的根本架构实现。而后须要增加change事件,当咱们抉择好三级分类后,change事件会默认存储咱们选择项中的绑定值,也就是id,咱们在申请数据时,须要携带该id.这样就大略实现了级联选择器。 setPorps:{ value:'id', label:'name', children:'children'}其余的增加参数和编辑参数,不再赘述 1.3 商品分类次要就是展现商品的各级分类以及增加分类操作,比拟重要的是Table表格中的树形构造,这个须要用到插件,个人感觉用到的中央不多,就没有记录了! 2.订单治理订单治理中只有一个子选项:订单列表 只须要申请订单列表数据后,展现在Table表格中即可。其余的不再赘述 3.数据统计数据统计中只有一个子选项:数据报表 这里用到了echarts图表,这部分还是比拟重要的,我这里具体介绍一些,vue我的项目中如何应用echarts 首先须要在vue我的项目中装置并引入echarts装置echarts很简略,只须要执行以下命令: npm install echarts --save引入的形式由两种:全局引入或者部分引入 全局引入的话,须要在main.js文件中 import echarts from 'echarts'Vue.prototype.$echarts=echarts部分引入的话,就只须要在对应的.vue文件中引入即可 定义一个固定宽高的容器来存储图表<div id="main" style="width: 600px;height:400px;"></div>在script标签内绘制咱们的图表(初始化实例、编辑配置项、执行配置项) <script type="text/javascript"> // 基于筹备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('main')); // 指定图表的配置项和数据 var option = { title: { text: 'ECharts 入门示例' }, tooltip: {}, legend: { data: ['销量'] }, xAxis: { data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] }, yAxis: {}, series: [ { name: '销量', type: 'bar', data: [5, 20, 36, 10, 10, 20] } ] }; // 应用刚指定的配置项和数据显示图表。 myChart.setOption(option); </script>这样咱们的图表就实现了。 ...

May 29, 2022 · 1 min · jiezi

关于element-ui:elementui的使用一

一、装置与引入element-ui的官网文档:https://element.eleme.cn/#/zh...首先,咱们在终端中输出npm i element-ui -S,就能够把element-ui下载下来,之后,须要在main.js我的项目入口文件中引入element-ui,留神,这里有两种抉择: 第一就是全盘引入import Element-UI from 'element-ui'第二种就是按需引入,比如说你须要用到Button,那么你就import {Button} from 'element-ui'留神咱们之前引入的只是element-ui的组件,然而具体的款式还没有引入,因而须要加上import 'element-ui/lib/theme-chalk/index.css',这个是容易被疏忽的中央,须要强调。之后还须要申明一下Vue.use(Element-UI),这样咱们才能够在vue的其余组件中应用集体还是比拟举荐按需引入,毕竟咱们的我的项目中不会把element-ui的全副组件都会用到,只可能最多十几种,所以为了整个我的项目,还是按需引入的好一些 二、配合Vue制作登录界面1.引入el-form表单el-form有很多种,然而我的需要是用户登录,那么只须要两个input文本框就好。我间接援用的是官网组件中Form表单的“自定义校验规定”,这个用着不便些。 大抵代码如下,简略的账户和明码验证: <template><div class="home"> <el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm" > <el-form-item label="账号" prop="username"> <el-input type="text" v-model="ruleForm.username" autocomplete="off" ></el-input> </el-form-item> <el-form-item label="明码" prop="Pass"> <el-input type="password" v-model="ruleForm.Pass" autocomplete="off" ></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm('ruleForm')" >提交</el-button > <el-button @click="resetForm('ruleForm')">重置</el-button> </el-form-item> </el-form></div></template><script>export default { data() { var validateUser = (rule, value, callback) => { if (value === "") { callback(new Error("请输出账号")); } else { callback(); } }; var validatePass = (rule, value, callback) => { if (value === "") { callback(new Error("请输出明码")); } else { callback(); } }; return { ruleForm: { username: "", Pass: "", }, rules: { username: [{ validator: validateUser, trigger: "blur" }], Pass: [{ validator: validatePass, trigger: "blur" }], }, }; }, methods: { submitForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { alert("submit!"); } else { console.log("error submit!!"); return false; } }); }, resetForm(formName) { this.$refs[formName].resetFields(); }, },};</script><!-- Add "scoped" attribute to limit CSS to this component only --><style scoped>.el-input>>> .el-input__inner{ width: 10%;}</style>这外面有几个问题须要提前说一下:首先最重要就是咱们在援用elment-ui的组件时,应用款式都是默认的,咱们能够批改,然而不能够间接在element-ui的默认款式文件index.css中批改,而是利用到了深度选择器进行款式重写,向下看... ...

May 16, 2022 · 3 min · jiezi

关于element-ui:elementUI-Descriptions-描述列表的换行问题

elementUI Descriptions 形容列表问题形容:如果内容过长,标签会被压缩,内容如果是中文能够主动换行,然而数字不会换行解决形式:所以须要加上款式 对于标签:labelStyle="white-space:nowrap;" 对于内容:contentStyle="word-break:break-all;"

May 16, 2022 · 1 min · jiezi

关于element-ui:elementUI上传文件

在应用elementUI进行文件提交的时候,有时候须要提交一些别的参数,这时候须要接管到上传的文件之后,将文件转为formData表单数据(具体看后端)再进行提交。首先咱们须要再模板中先配置下 el-upload,将 auto-upload 设置为 false 禁止主动提交,相干的属性能够查看elementUI文档: <el-upload name="file" ref="upload" :show-file-list="false" :action="baseUrl + '/pc/fee/bill/take-excel'" :before-upload="beforeUpload" :on-change="addFile" :file-list="fileList" :auto-upload="false"> <el-button type="primary" size="small">抉择文件</el-button></el-upload>而后就是在用户将文件抉择好上传的时候,咱们须要转成 FormData 的格局能够先应用 let formdata = new FormData() 创立进去,而后通过提供的 formdata.append('name', value) 办法向formdata外面增加键值对。须要留神的是,这个时候如果想要查看是否增加胜利千万不要用 console.log() 间接打印的形式,这样你会发现输入的是空的,正确的形式是通过给定的 get/getAll keys等形式获取到数据: console.log(formdata) //会输入一个空的 FormDataconsole.log(formdata.get('name')) //会输入对应的value这样就能输入你的 formdata 数据啦。筹备工作实现之后,和后端小伙伴沟通下,咱们来配置下申请的接口: billChargePostApiQuery(url,data){ return request({ url: url, headers: { "Content-Type": "multipart/form-data" //留神格局 }, method: 'post', data, baseURL: process.env.NODE_ENV === 'production' ? '正式' : '测试' }) },而后将接口所须要的一些参数也加进 formdata 中: let data ={ schoolId: this.$store.state.user.school_id, schoolName: this.$store.state.user.school_name, classificationId: this.form.order_sort, classificationName: sort_name, type: this.checkList.join(','), feeType: this.form.month? '2': '1', schoolYear: schoolYearGet, semester: this.form.semester, payMonth: this.form.month, createUserId: this.$store.state.user.userinfo.memberId, createUserName: this.$store.state.user.userinfo.name}//应要求转为 json 字符串增加进去this.fileData.append("takeExcelQuery", JSON.stringify(data))this.$API.billChargePostApi('pc/fee/bill/take-excel',this.fileData).then(res => { console.log('提交胜利',res);}).catch(err => { console.log('提交失败', err);})剩下的就是后端小伙伴的工作啦。欢送斧正! ...

May 11, 2022 · 1 min · jiezi

关于element-ui:后端一次性返回所有的数据让前端截取展示做分页

问题形容有这样一个业务场景:对于某个表格展现数据而言,这个表格的数据在30~60条之间,不会超过某个数量不会太多。后端说:我一次性返回给你所有的数据,因为产品说必须要做分页,你就本人做分页吧,也不必传我分页参数了。行吧?前端:行,那我拿到所有的数据,依据分页参数,本人做一个截取展现呗 效果图效果图就是失常的分页成果 代码附上演示的话,间接复制粘贴即可。正文中简述了,代码思路 <template> <div class="box"> <el-table height="240" :data="showTableData" border style="width: 100%"> <el-table-column prop="name" label="姓名" width="180"></el-table-column> <el-table-column prop="age" label="年龄" width="180"></el-table-column> <el-table-column prop="home" label="他乡"></el-table-column> </el-table> <el-pagination layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pageIndex" :page-size="pageSize" :page-sizes="[2, 4, 6, 10]" :total="total" > </el-pagination> </div></template><script>export default { data() { return { pageIndex: 1, // 第几页 pageSize: 4, // 每页几条数据 total: 0, // 总条目数 allTableData: [], // 所有的数据 showTableData: [], // 以后展现的数据 }; }, mounted() { setTimeout(() => { // 1. 模仿发申请获取所有的数据 let apiAllTableData = [ { name: "孙悟空", age: 500, home: "花果山水帘洞", }, { name: "猪八戒", age: 88, home: "高老庄", }, { name: "沙和尚", age: 1000, home: "通天河", }, { name: "唐僧", age: 9999, home: "东土大唐", }, { name: "白龙马", age: 12, home: "东海", }, { name: "观音菩萨", age: 18, home: "南海", }, { name: "玉皇大帝", age: 123456789, home: "凌霄宝殿", }, { name: "如来佛祖", age: 9999999.999, home: "迦毗罗卫国", }, ]; // 2. 存一份所有的数据 this.allTableData = apiAllTableData; // 3. 获取总条目数 this.total = this.allTableData.length; // 4. 依据以后是第几页、每页展现几条,去截取须要展现的数据 this.getShowTableData(); }, 1000); }, methods: { getShowTableData() { // 5. 获取截取开始索引 let begin = (this.pageIndex - 1) * this.pageSize; // 6. 获取截取完结索引 let end = this.pageIndex * this.pageSize; // 7. 通过索引去截取,从而展现 this.showTableData = this.allTableData.slice(begin, end); }, // 8. 页数扭转,从新截取 handleCurrentChange(val) { this.pageIndex = val; this.getShowTableData(); }, // 9. 条目数扭转,也从新截取 handleSizeChange(val) { this.pageIndex = 1; this.pageSize = val; this.getShowTableData(); }, },};</script>其实对于某些数据量比拟少的表格展现业务场景,齐全能够不分页,或者由前端做截取分页。

April 29, 2022 · 2 min · jiezi

关于element-ui:二次封装这几个-elementui-组件后让代码更加优雅了

element-ui 因其组件丰盛、可拓展性强、文档具体等长处成为 Vue 最火的第三方 UI 框架。element-ui 其自身就针对后盾零碎设计了很多实用的组件,基本上满足了平时的开发需要。既然如此,那么咱们为什么还要进行二次封装呢? 有以下两种场景 在日常的开发过程中,局部模块重复性比拟强,这个时候就会产生大量反复的代码。这些模块的款式基本上是比拟固定的,而且实现的性能也比拟相近。如果每个中央都复制一份类似的代码,既不恪守代码的简洁之道,也不利于前期的保护批改 此外,在一些业务背景下,产品可能会要求设计新的交互。这个时候也能够基于 element-ui 进行二次开发,将其封装成一个新的组件不便多个中央应用 因为在日常开发过程中,我的项目次要以 Vue2 为主,并且当初很多公司仍在应用着 Vue2。故本文次要探讨 Vue2 + element-ui 的我的项目能够怎么封装一些比拟通用化的组件 核心思想次要以父组件传递数据给子组件来实现一些性能,子组件定义固定的展现款式,将具体要实现的业务逻辑抛出来给父组件解决尽量放弃 element-ui 组件原有的办法(能够应用 v-bind="&dollar;attrs" 和 v-on="&dollar;listeners"),如果的确要做更改也尽量让类似的办法办法名不变组件InputNumberel-input-number 是一个很好用的组件,它只容许用户输出数字值。然而这个组件会有个默认值,给他赋予一个null 或""的时候会显示0 这对于有些业务来说并不是很敌对,例如增加页面和编辑页面 并且它这个组件的值是居中显示的,和一般的input 框居左显示不同,这就导致了款式不太对立 革新:让 InputNumber 能够居左显示且没有默认值,用法放弃和el-input-number组件类似 子组件 InputNumber.vue <template> <el-input-number id="InputNumber" style="width: 100%" v-model="insideValue" v-bind="$attrs" :controls="controls" v-on="$listeners" /></template><script>export default { // 让父组件 v-model 传参 model: { prop: 'numberValue', event: 'change', }, props: { numberValue: { type: [Number, String], default: undefined, }, // 默认不显示管制按钮,这个能够依据理论状况做调整 controls: { type: Boolean, default: false, }, }, data () { return { insideValue: undefined, }; }, watch: { numberValue (newVlalue) { // 若传入一个数字就显示。为空则不显示 if (typeof newVlalue === 'number') { this.insideValue = newVlalue; } else this.insideValue = undefined; }, },};</script><style lang="scss" scoped>#InputNumber { /deep/ .el-input__inner { text-align: left; }}</style>父组件 ...

April 25, 2022 · 5 min · jiezi

关于element-ui:Element-plus-图标使用

应用vue3引入Element plus,应用icon时发现没有失常渲染到页面上。到官网查看后发现,如果你想像用例一样间接应用,你须要全局注册组件,才可能间接在我的项目里应用。单个图标引入你能够在单个组件中像上面的形式引入: <template> <el-menu active-text-color="#ffd04b" background-color="#545c64" class="el-menu" default-active="2" text-color="#fff" @open="handleOpen" @close="handleClose" > <el-sub-menu index="1"> <template #title> <el-icon><location /></el-icon> <span>Navigator One</span> </template> </el-sub-menu> </el-menu></template><script>import { Location } from '@element-plus/icons-vue'export default { name: "SideMenu", components: { Location }}</script>全局注册为组件然而每次都这样做显然过于繁琐,咱们能够应用上面的形式把icon全局注册为组件: // main.jsimport { createApp } from 'vue'import ElementPlus from 'element-plus'import 'element-plus/dist/index.css'import * as ElIcons from '@element-plus/icons-vue'import App from './App.vue'const app = createApp(App)// 对立注册Icon图标for (const iconName in ElIcons) { app.component(iconName, ElIcons[iconName])}app.mount('#app')这样应用就不便多了。

April 23, 2022 · 1 min · jiezi

关于element-ui:解决element-ui的zindex问题

有趣味可关注公众号 毛毛虫的小小蜡笔,不定时更新前端等文章信息。 问题测试发现一个偶现的bug,第一次关上调度配置的页面,点击具体工夫是能抉择工夫的,但敞开后关上其余配置页面,再回来关上调度配置的页面,发现点击具体工夫没反馈。 如下截图所示: 剖析一开始认为是调度配置页面组件的状态问题。因为具体工夫是用了第三方组件,页面组件是通过v-show形式来显示暗藏的。所以再次关上后,可能没把状态解决好。 但验证的过程中,忽然想到一个问题:第三方组件应该不会有这么低级的bug,还是先看看它的工夫抉择div节点在不在。 后果,具体工夫尽管点击没反馈,但工夫抉择的div节点还是在的,只是页面上看不到而已! 原来是el-drawer的层级太高,把工夫抉择div节点笼罩了! 但为啥第一次关上调度配置页面就没问题,前面就被笼罩了呢? 原来是element ui的el-drawer,没关上一次,z-index都会+1。。。 第一次关上,如下截图所示: 第二次关上,如下截图所示: 第三次关上,如下截图所示: 解决目前解决形式就是加个important,笼罩element ui的z-index。 .mx-datepicker-popup { z-index: 2999 !important;}另外,el-dialog弹窗和其余浮窗貌似也有该问题。 疑难为啥element ui的z-index会自增呢? 看了下源码,没具体阐明什么起因。如下截图所示: 而后到github上看了下,发现一开始就这样设计的。如下截图所示: 最初有趣味可关注公众号 毛毛虫的小小蜡笔,不定时更新前端等文章信息。文章有疑难和问题,请留言。如果感觉文章还能够,请点赞或珍藏,谢谢。

April 13, 2022 · 1 min · jiezi

关于element-ui:解决element-ui的button没自动失焦的问题

问题在实例列表页面,点击详情按钮,在关上弹窗后,大拇指习惯性的点了下空格键,发现怎么又弹窗了? 尽管从界面看不错来,但从devTool的Elements中是能够看到,有两个dialog弹窗元素。 剖析因为这个页面不是我负责,一开始认为是在click的时候,加上stop等修饰符就能够。 原来是上面这样的: <el-button type="text" @click="showDetail(scope.row)">详情</el-button>但加了stop等修饰符,还是不行。看来事件并不是我想的那么简略。 因为用了element ui的button,所以想着看下文档,会不会有没留神到的阐明。一眼看完,没有特地的相干阐明。 而后回到页面持续测试,发现关上弹窗后,点击空格键,发现“详情”的字如同闪了一下。多测试几次,发现问题了。 原来关上弹窗后,button没有失焦,所以这时候点击空格键,就会再次触发button的click事件,从而再次关上弹窗。阐明一下,这里再次关上弹窗,是因为代码没判断是否已关上弹窗的逻辑。这个能够先疏忽。毕竟这里探讨的是失焦问题。 解决方案使元素失焦,个别是通过blur事件。 // 原来<el-button type="text" @click="showDetail(scope.row)">详情</el-button>showDetail(rowData) { this.openDialog(rowData)}// 革新后<el-button type="text" @click="showDetail(scope.row, $event)">详情</el-button>showDetail(rowData, event) { // 这里须要留神下,点击的target可能不是button,因为el-button最终生成的是button和span元素,所以须要判断下 if (event.target.nodeName === 'SPAN') { event.target.parentNode.blur() } else { event.target.blur() } this.openDialog(rowData)}下面的办法是能解决,但貌似有个问题:要每个中央都要加事件注入和失焦的判断逻辑。 那是否更好的解决?很显著,如果弹窗中有input等可输出的标签,是能够让input主动聚焦,从而使button失焦来解决问题。但如果弹窗中的内容只是展现的呢?比方弹窗中没有input等标签,都是div呢? 这就要用到tabindex属性了。tabindex=负值 (通常是tabindex=“-1”),示意以后元素是能够聚焦的,但不能通过键盘来导航拜访。所以在el-dialog中设置tabindex属性,以及mounted的时候,触发focus事件。 <el-dialog :visible="visible" :title="extend.title" width="880px" @close="close" ref="dialog" tabindex="-1">mounted() { this.$refs.dialog.$el.focus()}// mounted的时候间接执行focus,有时候会存在时间差问题。所以倡议通过setTimeout来设置mounted() { setTimeout(() => { this.$refs.dialog.$el.focus() }, 100)}可是,这跟计划1不是一样吗?也要写那么多代码。。。这个就要各位衡量取舍了。 最初公众号《毛毛虫的小小蜡笔》有疑难和问题,请留言。 如果感觉文章还能够,请点赞或珍藏,谢谢。

April 1, 2022 · 1 min · jiezi

关于element-ui:解决element-ui的table懒加载只执行一次的问题

问题有个需要是这样的:须要在table中退出开展行的性能。 看到element文档上可通过type="expand"实现,但例子只是form表单(“开展行”的例子)。前面看到有table的例子(“树形数据与懒加载”),可通过设置lazy属性和load函数来实现。 如下所示: 但整合到我的项目中,发现load只执行了一次。也就是第二次点击小箭头,是不会发申请的。这样就会有点问题,因为如果在别的页面更改了开展行的数据,那只能通过刷新页面来更新以后开展行的数据。 解决方案看了element的文档,没找到解决方案。前面联合expand-change事件,发现是能够解决的。 大略是load的时候,须要借助expand-change事件来再次触发load的执行。 代码如下所示:html: <el-table :data="dataList" v-loading="loading" class="table" row-key="prodInstId" lazy :load="load" :tree-props="{children:'children',hasChildren: 'hasChildren'}" @expand-change="handleExpandChange">JS: handleExpandChange(row, expanded) { if (expanded) { // 以后是开展状态 if (this.hasLoad) { // 已执行过load,则去掉执行过的标记 this.hasLoad = false } else { // 不然,则执行load。因为load只会执行一次,所以须要在expand事件触发再次执行 this.load(this.currentLoadTreeData, '', this.resolveObj) } }},async load(tree, treeNode, resolve) { // 标记以后已执行load this.hasLoad = true this.currentLoadTreeData = tree // 缓存以后的resolve this.resolveObj = resolve await this.getReadOnlyDetail(tree, resolve)},async getReadOnlyDetail(row, resolve) { const params = { prodInstId: row.prodInstId, isOnlyReadInst: true } const res = await http.detail(params) resolve([res.data]) return res}最初公众号《毛毛虫的小小蜡笔》有疑难和问题,请留言。 ...

March 31, 2022 · 1 min · jiezi

关于element-ui:elementui中eltable自定义表格暂无数据提示

依据我的项目须要,获取后端接口返回数据申请过程中,table提醒“数据加载中...”,申请胜利后,若无数据提醒“暂无数据”,有数据则展现数据。依据如上需要,须要自定义element-ui table表格暂无数据时的款式。1.只批改提醒文字间接在<el-table>中间接增加empty-text="数据加载中..."属性即可。2.批改提醒文字加图片如果须要更改文字并增加图片,则须要实用slot="empty"属性。 <template slot="empty"> <img src="写本人的地址" alt > <P> 写本人的提醒文字</p></template>

March 28, 2022 · 1 min · jiezi

关于element-ui:Element-Plus-源码分析构建与代码风格

我的项目概述官网:https://element-plus.org/GitHub 仓库:https://github.com/element-pl...包治理:pnpm workspace组件代码:TypeScript、Vue SFC(Vue 单文件组件)款式:Scss、CSS var单元测试:Jest、Vitest构建:Rollup、esbuild、TypeScript、Gulp代码格调:ESLint、Prettier本文章基于 Element Plus v2.1.4。如有谬误之处,欢送斧正。 构建Keywords: Vue SFC, Rollup, Bundleless, TypeScript, ESM, CommonJS/CJS, UMD这部分在一个独自的包 @element-plus/build,代码位于 /internal/build。 应用到的工具有:rollup、unbuild、esbuild、gulp、ts-morph、fast-glob 等。如需深度了解,倡议先自行理解这些包后浏览本章节。 目录构造源码internal/build├── build.config.ts # unbuild 配置文件├── dist # 构建产物├── gulpfile.ts # 构建脚本├── package.json├── src│ ├── build-info.ts # 构建信息│ ├── constants.ts # 一些常量│ ├── index.ts # 入口文件│ ├── plugins # 插件│ │ └── element-plus-alias.ts # 导入别名│ ├── tasks│ │ ├── full-bundle.ts # 构建残缺产物│ │ ├── helper.ts # 生成 WebStorm 提醒文件│ │ ├── index.ts│ │ ├── modules.ts # 构建 bundleless 产物│ │ └── types-definitions.ts # 生成 d.ts 文件│ ├── type-safe.json # 「类型平安」列表│ └── utils # 工具函数│ ├── gulp.ts│ ├── index.ts│ ├── log.ts│ ├── paths.ts│ ├── pkg.ts│ ├── process.ts│ └── rollup.ts├── tsconfig.json└── vue-jest-transformer.js构建产物在线预览 ...

March 20, 2022 · 3 min · jiezi

关于element-ui:eltable点击行内容实现单选和多选的选中状态

建一个文章,揭示本人来整顿。。敬请期待。。

March 16, 2022 · 1 min · jiezi

关于element-ui:记录elementUI中表格合并

有个需要是这样的,表格第一列须要合并行,后边的数据是通过接口获取,效果图如下: 首先,列中的工夫是前端生成的,尖峰、顶峰、低谷是每行数据都会有的,能够写死,具体代码如下: // 表格: <el-table :data="tableData" :span-method="arraySpanMethod" border size="mini" > <el-table-column label prop="company"> <template slot-scope="scope">{{ scope.row.company }}</template> </el-table-column> <el-table-column label="工夫" prop="symbolType" width="120px"> <template slot-scope="scope">{{ scope.row.symbolType }}</template> </el-table-column> <el-table-column v-for="(item, index) in timeData" :key="index" :prop="item.label" :label="item.time" > <template slot-scope="scope">{{ scope.row[item.label] }}</template> </el-table-column> </el-table>// data数据如下: data() { return { companyArr: [], companyPos: 0, typeArr: [], typePos: [], // 假数据,前期是通过接口获取 tableData: [ {company: "xxxx1",type:1,symbolType: "尖峰",m1: "1",m2:"1",m3: "",m4: "",m5:"",m6: "",m7:"",m8:"",m9:"","m10":"",m11:"",m12:""}, {company: "xxxx1",type:1,symbolType: "顶峰",m1: "",m2:"1",m3: "1",m4: "",m5:"",m6: "",m7:"",m8:"",m9:"","m10":"",m11:"",m12:""}, {company: "xxxx1",type:1,symbolType: "低谷",m1: "",m2:"",m3: "1",m4: "1",m5:"",m6: "",m7:"",m8:"",m9:"","m10":"",m11:"",m12:""}, {company: "xxxx2",type:2,symbolType: "尖峰",m1: "",m2:"2",m3: "2",m4: "",m5:"",m6: "",m7:"",m8:"",m9:"","m10":"",m11:"",m12:""}, {company: "xxxx2",type:2,symbolType: "顶峰",m1: "",m2:"",m3: "2",m4: "2",m5:"",m6: "",m7:"",m8:"",m9:"","m10":"",m11:"",m12:""}, {company: "xxxx2",type:2,symbolType: "低谷",m1: "",m2:"",m3: "",m4: "2",m5:"2",m6: "",m7:"",m8:"",m9:"","m10":"",m11:"",m12:""}, {company: "xxxx3",type:3,symbolType: "尖峰",m1: "",m2:"",m3: "3",m4: "3",m5:"",m6: "",m7:"",m8:"",m9:"","m10":"",m11:"",m12:""}, {company: "xxxx3",type:3,symbolType: "顶峰",m1: "",m2:"",m3: "",m4: "3",m5:"3",m6: "",m7:"",m8:"",m9:"","m10":"",m11:"",m12:""}, {company: "xxxx3",type:3,symbolType: "低谷",m1: "",m2:"",m3: "",m4: "",m5:"3",m6: "3",m7:"",m8:"",m9:"","m10":"",m11:"",m12:""}, ], }}// timeData: ...

March 12, 2022 · 2 min · jiezi

关于element-ui:记录使用elementUI设置主题遇到的坑

前段时间我的项目中要求设置主题切换,因为之前没接触过,所以跟着官网流程走,记录下开发过程中所遇到的坑。 我的项目设计有暗黑模式和清亮模式,接下来进入流程: 1、装置主题生成工具 npm i element-theme -g2、装置白垩主题 npm i element-theme-chalk -D3、初始化变量文件 et -i执行完以上命令后,会在根目录下会生成element-variables.scss文件,里边蕴含了elementui中组件所用到的所有变量,像字体大小,色彩,背景色彩等。 如果我的项目有本人的设计稿,并且对字体色彩、按钮色彩等有严格要求,能够在这个文件找到对应属性进行批改,批改实现之后执行et编译主题 et这时根目录下会生成theme文件夹,里边有fonts和一些css文件,这里的fonts文件会有用,其余css文件能够删除了。 接下来是重点,将element-variables.scss批改名称为element-variables-dark.scss,而后在执行第三步(初始化变量文件),这样根目录会从新生成一份element-varibles.scss文件,对里边的色彩、背景色彩更改保留,改名称为element-variables-light.scss,这里保留的是清亮模式的文件。 4、应用gulp-css-wrap神器 npm install gulpnpm install gulp-clean-cssnpm install gulp-css-wrap5、在根目录下创立gulpfile.js文件 截图中.custom-light选择器是定义了清亮模式下在body中增加的类属性,src/assets/theme/light 这块是寄存清亮模式的主题文件。文件夹中蕴含fonts和index.css,这里的fonts就是之前根目录theme下的fonts,是复制过去的,index.css文件则是真正的主题引入的文件。 最重要的一点,不论对暗黑模式还是清亮模式进行批改,首先批改根目录下两种模式对应的element-variables-light.scss文件,批改为element-variables.scss,零碎才会辨认进去,而后在执行et -i,批改完之后在执行et 编译主题。6、执行gulp输入 gulp css-wrap7、在main.js中引入 8、遇到的坑 因为装置gulp,gulp的版本和node不兼容,执行et -i 时报错:primordials is not defined; 解决方案: gulp3.x.x须要将node升高到11.x.x 要么升高node版本为12以下,要么降级gulp为4.x版本。 这个报错终于解决了,又呈现了其余报错,没有发现chalk,我本人独自装了下,还是报错,最初发现还是版本的问题。 node v10.16.0版本 如下装置: npm i element-theme -gnpm i element-theme-chalk -Dnode v12.13.0 版本 如下装置: npm i element-themex -gnpm i element-theme-chalk -D版本不同,引入的element主题不一样,高版本用的是element-themex,这个在官网上没有找到,心愿能够帮到大家,其余的就是应用主题了,很简略,写一个el-switch开关对主题进行设置,利用vuex进行全局保留就能够了。

March 12, 2022 · 1 min · jiezi

关于element-ui:需求复选框状态判断将000000转变成001011即选中由01

通过复选框是否选中的状态将字符串中的0转变成1。<el-table ref="itemref" :data="itemList" border highlight-current-row stripe @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55" /> <el-table-column type="index" label="序号" min-width="70"> <template slot-scope="scope"> {{ scope.$index + (formData.pageInfo.pageNumber - 1) * formData.pageInfo.pageSize + 1 }} </template> </el-table-column> <el-table-column prop="name" label="姓名" show-overflow-tooltip> </el-table-column></el-table>itemList : [] //将选中的选项暂存在该数组中itemNum: ['0', '0', '0', '0', '0', '0'],items: '', //最终失去的字符串,传递给后端itemList: [ { itemIndex: 0, name: "第一项" }, { itemIndex: 1, name: "第二项" }, { itemIndex: 2, name: "第三项" }, { itemIndex: 3, name: "第四项" }, { itemIndex: 4, name: "第五项" }, { itemIndex: 5, name: "第六项" }, ],handleSelectionChange(val) { this.itemList = val; //将选中的项放入到数组中 this.itemList.forEach(item => { this.itemNum[item.itemIndex] = 1 //定位将0赋值为1 this.items = this.itemNum.join('').toString() //将数组转换成字符串 });},// this.$refs.itemref.clearSelection(); //清空十四项多选状态 多用于弹窗敞开时

March 9, 2022 · 1 min · jiezi

关于element-ui:在table列表中通过按钮移除某条数据

需要:前提是table展现list数组的全副数据,要求移除操作后,在list数组中删除该条数据。 //移除办法deleteBatch(elecId) { console.log(this.valList, 'valList1'); //移除前数组 this.valList.forEach((value, index, array) => { if (value.elecId == elecId) { //判断条件 array.splice(index, 1) //删除符合条件的数据 } }) console.log(this.valList, 'valList2'); //移除后数组},

March 8, 2022 · 1 min · jiezi

关于element-ui:处理-elementUI-中table表格多选框判断是否禁用问题

在 el-table-column type 类型为 selection 组件中,增加 :selectable='办法名' <template> <el-table :data="tableData" v-loading="loading" max-height="570" stripe :header-cell-style="headerStyle" @selection-change="handleSelectionLeftChange"> <el-table-column type="selection" :selectable='selectEnable'> </el-table-column> </el-table></template>判断是否禁用办法函数 selectEnable(row, rowIndex) { if ('此处是判断条件') { return false //禁用 } else { return true// 不禁用 }}

March 8, 2022 · 1 min · jiezi

关于element-ui:vue使用element中Cascader-级联选择器回显

1.开发环境 vue2.电脑系统 windows10专业版3.在开发的过程中,咱们在应用element的Cascader 级联选择器会遇到回显的问题,上面我来分享一下解决办法。4.废话不多说,间接上代码: //vue代码<el-cascader class="ipt-cascader" v-model="AppListId" //要害代码 :options="dependentData.AppList" :props="{ value:'value',label:'label',children:'datas'}" @change="handleCascaderChange" clearable></el-cascader>// return代码AppListId:['',''],//在对应的办法中增加如下this.AppListId[0]=this.positionData.cdcAppId;//数组的第一个值是第一层数据的idthis.AppListId[1]=this.positionData.tabId + '';数组的第二个值是第二层的id4.成果如下: //留神:::这是默认显示的,不是点击之后显示的5.本期的分享到了这里就完结啦,心愿对你有所帮忙,让咱们一起致力走向巅峰。

February 23, 2022 · 1 min · jiezi

关于element-ui:配置化elform的二次封装之思路分析附上代码可直接使用

问题形容集体愚见编写代码其实就是: 学习规定(看官网文档)应用规定(在应用的过程中进一步了解官网文档)最终基于原有底层官网文档规定再自定义新规定(封装新的规定,便于复用)所以本文讲述一下基于原有的el-form的规定,进行二次封装自定义新的规定的思路,以及附上能间接用的代码。咱们先看一下效果图: 效果图 思路剖析最终成果是配置化“写代码”,就像echarts一样,写不同的配置,呈现不同的成果,天然是配置,所以就要提前思考好有哪些须要配置。当然也要思考数据的回显。 配置表单项类型(组件中要加上校验规定)配置表单项的名字配置表单项的字段配置表单项是否必填配置输入框的单位(如果有的话)配置placeholder的文本提醒配置下拉框选项数据数据(如果是固定的下拉框能够传过来)如果是枚举值类型的下拉框就须要发申请获取下拉框选项数组数据等...这里要多提一下表单项类型 配置表单项~输入框的类型首先咱们要分明form表单项的类型,这里为了便于了解,只举例三种大类型,当然大类型中也蕴含小类型,同时也要做校验。至于别的类型,大家了解了这几个类型当前,就能够本人写了。 输入框类型 文本输入框类型(校验得填写,不能为空)数字输入框类型(校验输出的数字类型,比方须要正整数、须要保留两位小数等)下拉框类型 固定选项的下拉框类型(这里间接写死,传过来即可,比方性别下拉框,只有男女两种类型选项)枚举多个选项的单选下拉框类型(须要提前发申请获取数据,或者visible-change事件发申请获取)枚举多个选项的单选多选下拉框类型(同上)工夫选择器范畴类型留神绑定的后果值是数组即可 最初不要忘了回显逻辑哦 el-form表头数据举例子组件表单数据依据依据父组件传递过去的formHeader动静渲染。即v-for中搭配v-if去出现,先简略看一下formHeader数据结构,具体在后边代码中都有的 // 表头数组数据 formHeader: [ { itemType: "text", // 输入框类型 labelName: "姓名", // 输入框名字 propName: "name", // 输入框字段名 isRequired: true, // 是否必填 placeholder: "请填写名字", // 输入框placeholder提醒语加上,可用于告知用户规定 }, { itemType: "number", labelName: "年龄", propName: "age", isRequired: true, unit: "year", // 数字类型的要有单位 placeholder: "请输出年龄(大于0的正整数)", }, { itemType: "selectOne", // 下拉框类型一,固定的选项能够写死在配置里,比方性别只有男女 labelName: "性别", propName: "gender", isRequired: true, placeholder: "请抉择性别", optionsArr: [ { label: "男", value: 1, }, { label: "女", value: 2, }, ], }, ],残缺代码倡议复制粘贴,运行跑起来,这样成果更加显著,更便于了解。毕竟:no words,show codes ...

February 3, 2022 · 7 min · jiezi

关于element-ui:eltable表格拖动列记住列宽度功能刷新页面还在

问题形容产品大佬说这个表格的列当初是能够拖动,然而拖动了当前,当用户刷新当前,拖动的列的宽度会回到默认的宽度了,所以,减少一个表格拖动列,刷新宽度还在性能。 思路刷新还在的性能必定是要存储一份数据,要么后端存数据库,要么前端存本地。本文说一下前端存本地的写法 效果图 拖动当前刷新还在哦打印拖动事件参数 本地存了一份 代码附上演示成果的话,间接复制粘贴运行即可 <template> <div class="twoWrap"> <el-table :data="tableBody" border style="width: 100%" :header-cell-style="{ height: '48px', background: '#FAFAFA', color: '#333333', fontWeight: 'bold', fontSize: '15px', }" @header-dragend="headerDragend" > <!-- 表头应用tableHeader数据 --> <el-table-column v-for="(item, index) in tableHeader" :key="index" :prop="item.propName" :label="item.labelName" :width="item.width" > </el-table-column> </el-table> </div></template><script>export default { data() { return { // 表头数据 tableHeader: [ { propName: "name", labelName: "姓名", width: "auto", }, { propName: "age", labelName: "年龄", // width: 180, width: "auto", }, { propName: "hobby", labelName: "喜好", // width: 180, width: "auto", }, { propName: "home", labelName: "他乡", // width: 180, width: "auto", }, ], // 表体数据 tableBody: [ { name: "孙悟空", age: 500, hobby: "吃桃子", home: "花果山", }, { name: "猪八戒", age: 88, hobby: "吃包子", home: "高老庄", }, { name: "沙和尚", age: 1000, hobby: "游泳", home: "通天河", }, ], }; }, created() { // 当页面刷新时,若本地存储中存的有表头数组信息,就用本地的。当然第一次本地是没有的 if (sessionStorage.getItem("tableHeader")) { this.tableHeader = JSON.parse(sessionStorage.getItem("tableHeader")); } }, methods: { // 表头拖动事件 headerDragend(newWidth, oldWidth, column, event) { // 饿了么UI中提供的有对应参数,次要用到的是newWidth和column.property console.log(newWidth, oldWidth, column, event); // 依据column中的信息就能够晓得用户拖动的是哪一列,从而将新的列宽度替换原来的列宽度 let newTableHeader = this.tableHeader.map((item, index) => { if (item.propName == column.property) { item.width = newWidth; } return item; }); // 最初存一份到本地,当刷新的时候,就用本地的这个记录了用户拖动宽度的表头数组数据 sessionStorage.setItem("tableHeader", JSON.stringify(newTableHeader)); }, },};</script>如果是后端存一份也是一个情理,只有在表格拖动事件的回调函数中把对应列的宽度更改即可,而后告知后端(比方通过接口)当然表头数据也要通过后端获取,就不是前端代码中写死的了好忘性不如烂笔头,记录一下把 ^_^ ...

January 9, 2022 · 1 min · jiezi

关于element-ui:eldatepicker日期框点击失效问题

elementUI DatePicker 组件抉择日期发现奇怪的bug:鼠标点击后没反馈,控制台不报错,上官网文档下来看也会呈现这bug。 解决办法是敞开掉浏览器的网页翻译就好,改成默认不翻译当前页:

January 9, 2022 · 1 min · jiezi

关于element-ui:Elementui时间选择器禁止选择当月之后的月份

html <el-date-picker v-model="fixValue" type="month" class="fl" value-format="yyyy-MM" clearable size="mini" placeholder="抉择日期" :picker-options="endDatePicker" > </el-date-picker>data数据定义 data(){ return{ endDatePicker: this.handelFixDate(), fixValue:null }},methods: handelFixDate() { console.log(this.fixValue, "132"); let self = this; return { disabledDate(time) { let t = new Date().getDate(); // 如果想蕴含本月本月 - 8.64e7 * t 就不须要了, // 如果想之前的不能抉择把 > 换成 < return time.getTime() > Date.now() - 8.64e7 * t; }, }; },————————————————版权申明:本文为CSDN博主「__不靠谱学生」的原创文章,遵循CC 4.0 BY-SA版权协定,转载请附上原文出处链接及本申明。原文链接:https://blog.csdn.net/weixin_...

December 31, 2021 · 1 min · jiezi

关于element-ui:elementui-渲染错误只显示变量

应用 element-ui 开发的后盾管理系统呈现以下画面: 如图所示,图中应该显示文字或组件的地位只显示了变量名称。 后续在控制台发现有以下正告: Cannot translate the value of keypath 'el.table.emptyText'. Use the value of keypath as default通过查证,是vue-i18n这个第三方库的报错,element 在配置时设置了 vue-i18n 选项,在 main.js 中批改以下代码即可解决问题: Vue.use(ElementUI, { size: 'small'- i18n: (key, value) => i18n.t(key, value)})如果我的项目中仍然须要应用 vue-i18n,则须要独自配置,这个库的 v5 和 v6 版本差异比拟大,需解决抵触后应用。

December 24, 2021 · 1 min · jiezi

关于element-ui:ElementUI-奇淫技巧第二弹提升开发效率延长摸鱼时间

主题款式批改已经为了批改组件格调,一个我的项目用了上百个款式穿透,起初才发现定制一个主题就够了! 第一步,在官网的主题页面,批改背景色、字体色彩及边框色彩 第二步,下载主题 第三步,用下载的css文件替换掉默认的css文件 成果如下: el-backtop 回到顶部组件有时候页面很长,咱们须要一个回到顶部的按钮,举荐大家应用 el-backtop,自带过渡成果。 代码如下:<template> <div class="container"> <div class="box">Scroll down to see the bottom-right button.</div> <el-backtop target=".container"> <i class="el-icon-caret-top"></i> </el-backtop> </div></template><style lang="scss" scoped>.container { height: 100vh; overflow-x: hidden; .box { padding: 20px; height: 1500px; }}</style>留神:须要将 body 的 margin 设置为 0,不然会呈现两个滚动条。 el-form-item label宽度自适应通常咱们是给 label 设置一个固定宽度,但这齐全限度了 UI 的施展,如何让 label 宽度自适应呢?答案是给控件设置一个固定宽度。 代码如下:<template> <el-form> <el-form-item label="老师"> <el-input v-model="form.teacher" style="width: 625px;"></el-input> </el-form-item> <el-form-item label="请抉择在线教学平台名称"> <el-select v-model="form.platform" style="width: 500px;"> <el-option label="平台一" value="1"></el-option> <el-option label="平台二" value="2"></el-option> </el-select> </el-form-item> </el-form></template><script>export default { data() { return { form: { teacher: '', platform: '' } } }}</script>el-form-item 循环校验有时候表单项是一个循环的列表,须要对每一项进行校验。 ...

December 21, 2021 · 3 min · jiezi

关于element-ui:eltable树表格报错-Error-in-render-Maximum-call-stack-size-exceeded

问题形容和后端联调树结构表格时,原本是好好的,起初忽然呈现:当点击表格中树结构开展的小箭头的时候,忽然呈现这样的报错: Error in render: "RangeError: Maximum call stack size exceeded" 报错截图如下: 报错截图 起因通过看看官网文档,得出起因如下: 应用树表格,须要指定row-key="id",即给每一行数据绑定一个惟一身份标识id,然而id不能反复。若子节点和父节点id一样,就会导致树的递归函数出错,就会导致渲染谬误,因为会始终递归,从而超过最大调用堆栈空间。所以肯定要id不同,惟一身份标识肯定要具备唯一性。 模仿代码<template> <div> <!-- row-key="id" 须要指定,不指定就不会呈现 右侧朝向小箭头 就没有懒加载的状况 tree-props配置树表格懒加载标识 load办法,用于点击小箭头加载数据 lazy开启懒加载当前,就能够把load来的数据追加到表格中去了 --> <el-table :data="tableData1" style="width: 100%" border row-key="id" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" :load="load" lazy > <el-table-column type="index" label="序号" width="50" fixed></el-table-column> <el-table-column prop="name" label="书名" width="180"> </el-table-column> <el-table-column prop="date" label="年代" width="180"> </el-table-column> <el-table-column prop="price" label="价格(元)" width="180"> </el-table-column> </el-table> </div></template><script>export default { data() { return { tableData1: [ { id: 1, name: "三国演义", date: "三国期间", price: "77", }, { id: 2, name: "西游记", date: "唐朝", price: "100", hasChildren: true, }, { id: 3, name: "水浒传", date: "宋朝", price: "108", }, ], }; }, methods: { load(tree, treeNode, resolve) { console.log("点击触发", tree, treeNode); let apiDataArr = [ { id: 2, // id不能反复,反复就报错 因为指定的row-key="id" 须要指定确保唯一性 name: "大闹天宫", // 这里让其和西游记那一行的id反复,便会呈现Error in render: "RangeError: Maximum call stack size exceeded" date: "神话时代", price: "666", }, { id: 5, name: "虚实美猴王", date: "神话时代", price: "2333", }, ]; // 模仿后端返回的数据 setTimeout(() => { resolve(apiDataArr); }, 1000); }, },};</script>演示的话,间接复制粘贴即可 ...

December 3, 2021 · 1 min · jiezi

关于element-ui:vue-组件递归调用

理论我的项目中,除了根本的树结构,有时还需扩大。如下图层级关系的递归调用,红框中的局部为齐全递归组件。 父级:template <div class="dept-tree-show"> <div class="teer-deep"> <div class="per-teer first-teer clearfix"> <template v-for="(item) in deptlist"> <div class="pt-item ft-item" :key="item.id" v-if="item.treeType==activedepttree.code" :class="{ 'disactive': teer2, 'active': (teer2&&teer2.code==item.code) }" @click.stop="openChildren(item)"> <div class="top-title">{{item.name.slice(0,2)}}</div> <div class="total-more" title="人员列表" @click.stop="showRelatedUsers(item)"> <i :class="item.userloading?'el-icon-loading':'fa fa-users'"></i> </div> <div class="total-title">{{item.name}}</div> <!-- <div class="total-code">{{item.code}}</div> --> <div class="total-children" @click.stop="openChildren(item)"> {{(item.children&&item.children.length)?item.children.length:0}} <i :class="(teer2&&teer2.code==item.code)?'el-icon-arrow-up':'el-icon-arrow-down'"></i> </div> </div> </template> </div> <secondtree v-if="teer2" :openitem="teer2" @closetopChildren="closetopChildren" @showRelatedUsers="showRelatedUsers"></secondtree> </div> </div>js: //....不残缺代码import secondtree from './dept/childrenteer.vue'//....不残缺代码components:{ secondtree }//....不残缺代码子级: <template><div class="wrap-wrap"> <div class="children-teer-wrap" @click.stop v-if="opendata"> <div class="breaker" :id="opendata.id"> <div class="line"> <div class="line-left"></div> <div class="line-right"></div> </div> <div class="baseinfo"> <div class="l-title">{{opendata.name}}</div> <div class="l-close" @click.stop="closeChildren(opendata)">收起</div> </div> </div> <div class="per-teer children-teer clearfix"> <template v-for="(item) in opendata.children"> <div class="pt-item ct-item " :key="item.id" @click.stop="openChildren(item)" :class="{ 'disactive': treedata, 'active': (treedata&&treedata.code==item.code) }"> <div class="top-title">{{item.name.slice(0,2)}}</div> <div class="total-title">{{item.name}}</div> <div class="total-more" title="人员列表" @click.stop="showRelatedUsers(item)"><i :class="item.userloading?'el-icon-loading':'fa fa-users'"></i></div> <!-- <div class="total-code">{{item.code}}</div> --> <div class="total-children" @click.stop="openChildren(item)"> {{(item.children&&item.children.length)?item.children.length:0}} <i :class="(treedata&&treedata.code==item.code)?'el-icon-arrow-up':'el-icon-arrow-down'"></i> </div> </div> </template> </div> </div> <childrentree v-if="treedata" :openitem="treedata" @unActiveParent="unActiveParent" @closeChildren="closeChildren" @showRelatedUsers="showRelatedUsers"></childrentree></div> </template><script>export default { name:"childrentree", props:{ openitem:{ type: Object, default: () => {}, } }, watch:{ openitem(val){ this.opendata=val; this.treedata="" } }, data(){ return{ opendata:this.openitem, treedata:"" } }, methods: { openChildren(data){ if(this.treedata && this.treedata.code && data&& data.code && this.treedata.code==data.code){ this.treedata=""; }else{ if(data&&data.children && data.children.length){ this.treedata=data; this.$nextTick(()=>{ document.getElementById(data.id).scrollIntoView({behavior: "smooth"}) }) // } } }, unActiveParent(){ this.treedata=""; }, closeChildren(data){ this.opendata=""; this.$emit('unActiveParent'); this.$emit('closetopChildren'); }, showRelatedUsers(data){ this.$emit("showRelatedUsers",data) } },}</script>一些重要的废话放到最初:1:子组件,即须要递归应用的组件,在js中是要申明name(name:"childrentree")。这样子组件在自身就能够间接应用自身。2:本例从第二层节点才开始应用递归,所以写发有冗余,可按需精简3:子组件的事件须要按需辨别是要发动仅紧挨着的下层事件(this.$emit('unActiveParent');)还是顶层事件(this.$emit('closetopChildren');)。能够通过承受的办法名进行辨别4:开展某一节点后,节点子集的顶部,即大括号顶部的话,能够应用:(依据具体场景自行判断是否须要应用$nextTick) ...

December 2, 2021 · 1 min · jiezi

关于element-ui:elementUI-eltree-懒加载时设定某个节点为末端isLeaf节点不展示小三角图标

不想看废话版:1:须要给树增加props,申明isLeaf无效(官网没有这个说法,我本人了解的意思)2:给末端节点的节点数据中设置isLeaf=true; (lll¬¬)|('口')━━∑( ̄□ ̄|||━━( ̄△ ̄;)(°ー°〃) 废话很多版:我的项目生产中,咱们常应用element-UI 的el-tree的懒加载事件即手动点击节点左侧的小三角开展图标后才去加载其子集数据然而有时咱们明确晓得某个节点不须要开展(比方我的我的项目中,岗位和人员在一棵树中混合展现的时候,我明确晓得作为人员节点,是不须要左侧的小三角图标的)这时候咱们在通过"学生"节点懒加载获取其下的子级(蕴含其余几个岗位和一个人员时,人员类型不须要再开展)咱们发现官网树有一个属性:isLeaf如同很简略的样子然而依照这个设置之后没有用啊!!!! 翻看github的issue issue:1252 惟一缺一个props 而后能够了!!! 就,,,正经人谁写props啊(;´`)ゞ

November 18, 2021 · 1 min · jiezi

关于element-ui:eltable表头文字换行的三种方式

问题形容表格中的表头个别都是不换行的,不过有时候在某些业务场景中,须要让表头的文字换行展现一下,咱们先看一下效果图 效果图 三种形式的代码看正文就行啦。 演示的话,间接复制粘贴运行就行啦 <template> <div class="vueWrap"> <el-table style="width: 900px" :data="tableBody" border :header-cell-style="{ background: '#FAFAFA', color: '#333333', fontWeight: 'bold', fontSize: '14px', }" > <el-table-column type="index" label="序号" width="58" align="center" ></el-table-column> <!-- 表头换行形式一,应用头部插槽形式,将表头文字拆分在两个div中,因为div盒子是块元素 所以两个div会换行,所以表头就换行了,此形式实用于固定数据的表头换行 --> <el-table-column prop="toolName" width="180" align="center"> <template slot="header"> <div>工具箱</div> <div>整机名称</div> </template> <template slot-scope="scope"> <span>{{ scope.row.toolName }}</span> </template> </el-table-column> <el-table-column label="供应商" prop="supplier" width="120" align="center"> </el-table-column> <!-- 表头换行形式二,较之于形式一,这种形式是/n换行符,加css的white-space空白款式管制--> <el-table-column :label="labelFn()" prop="supplierCountry" width="180" align="center" > </el-table-column> <!-- 表头换行形式三,动静形式 --> <el-table-column v-for="(item, index) in tableHeader" :key="index" :label="item.labelName" :prop="item.propName" width="180" align="center" :render-header="renderheader" ></el-table-column> </el-table> </div></template><script>export default { data() { return { // 动态数据表头就须要让后端返回来了,让其在须要换行的中央用逗号分隔开 tableHeader: [ { labelName: "型号001,价格(元)", propName: "typeOne", }, { labelName: "型号002,价格(元)", propName: "typeTwo", }, ], // 表体数据 tableBody: [ { id: "2021111101", toolName: "5G服务", supplier: "华为", supplierCountry: "中国", typeOne: "8888888", typeTwo: "9999999", }, { id: "2021111101", toolName: "6G-SERVER", supplier: "中华有为", supplierCountry: "CHINA", typeOne: "678678678", typeTwo: "789789789", }, ], }; }, methods: { labelFn() { // 在须要换行的中央退出换行符 \n ,在搭配最底下的white-space款式设置 return `供应商\n所属国家`; }, // 饿了么UI的表头函数渲染形式,这种形式和表头插槽形式有点相似 // 也是把表头的数据文字宰割成两块,而后将内容渲染到两个div中(div主动换行) renderheader(h, { column, $index }) { return h("div", {}, [ h("div", {}, column.label.split(",")[0]), h("div", {}, column.label.split(",")[1]), ]); }, },};</script><style lang="less" scoped>/deep/ .el-table th.el-table__cell > .cell { white-space: pre; // white-space: pre-wrap; // 也行。}</style>对于white-space不赘述,详情查问官网文档: https://developer.mozilla.org...总结三种形式各有特色,然而render-header会略为消耗一点点性能。 ...

November 11, 2021 · 1 min · jiezi

关于element-ui:eltable合并列代码步骤讲解

问题形容有时候,产品让咱们做的表格,会有合并列的性能,然而官网的demo略有不清晰,本文举个例子简述之。咱们先看下效果图: 假如产品的需要是这样的:设施类别那一列,同类的,做成分堆模式,也就是合并列模式 剖析剖析写在代码正文中外面哦 代码附上<template> <div class="vueWrap"> <el-table :span-method="objectSpanMethod" style="width: 800px" :data="tableBody" border :header-cell-style="{ background: '#FAFAFA', color: '#333333', fontWeight: 'bold', fontSize: '14px', }" > <el-table-column type="index" label="序号" width="58" align="center" ></el-table-column> <el-table-column prop="toolsKinds" label="设施类别" align="center" ></el-table-column> <el-table-column prop="toolsName" label="设施名称" align="center"></el-table-column> <el-table-column prop="price" label="价格(元)" align="center"></el-table-column> <el-table-column prop="remark" label="备注" align="center"></el-table-column> </el-table> </div></template><script>export default { data() { return { // 表体数据 tableBody: [ { toolsKinds: "螺丝刀", toolsName: "一号螺丝刀", price: 10, remark: "", }, { toolsKinds: "螺丝刀", toolsName: "二号螺丝刀", price: 20, remark: "", }, { toolsKinds: "螺丝刀", toolsName: "三号螺丝刀", price: 30, remark: "", }, { toolsKinds: "扳手", toolsName: "大号扳手", price: 88, remark: "", }, { toolsKinds: "扳手", toolsName: "中号扳手", price: 44, remark: "", }, { toolsKinds: "老虎钳子", toolsName: "火星专供老虎钳", price: 999, remark: "", }, { toolsKinds: "老虎钳子", toolsName: "土星专供老虎钳", price: 1001, remark: "", }, ], cellList: [], // 单元格数组 count: null, // 计数 }; }, mounted() { // 第1步,依据表体信息,计算合并单元格的信息 this.computeCell(this.tableBody); }, methods: { computeCell(tableBody) { // 循环遍历表体数据 for (let i = 0; i < tableBody.length; i++) { if (i == 0) { // 先设置第一项 this.cellList.push(1); // 初为1,若下一项和此项雷同,就往cellList数组中追加0 this.count = 0; // 初始计数为0 console.log("索引", 0, this.count); } else { // 判断以后项与上项的设施类别是否雷同,因为是合并这一列的单元格 if (tableBody[i].toolsKinds == tableBody[i - 1].toolsKinds) { // 如果相等 this.cellList[this.count] += 1; // 减少计数 this.cellList.push(0); // 相等就往cellList数组中追加0 console.log("索引", i, this.count); } else { this.cellList.push(1); // 不等就往cellList数组中追加1 this.count = i; // 将索引赋值为计数 console.log("索引", i, this.count); } } } }, // 第2步,将计算好的后果返回给el-table,这样的话表格就会依据这个后果做对应合并列渲染 objectSpanMethod({ row, column, rowIndex, columnIndex }) { // 给第二列做单元格合并。0是第一列,1是第二列。 if (columnIndex === 1) { console.log("单元格数组,若下一项为0,则代表合并上一项", this.cellList); const rowCell = this.cellList[rowIndex]; if (rowCell > 0) { const colCell = 1; console.log(`动静竖向合并单元格, 第${colCell}列,竖向合并${rowCell}个单元格 `); return { rowspan: rowCell, colspan: colCell, }; } else { // 革除原有的单元格,必须要加,否则就会呈现单元格会被横着挤到前面了!!! // 本例中数据是写死的不会呈现,数据若是动静后端获取的,就会呈现了!!! return { rowspan: 0, colspan: 0, }; } } }, },};</script>打印截图留神打印的后果 ...

November 8, 2021 · 2 min · jiezi

关于element-ui:elementui-table表头部使用checkbox状态不回显

header中即时不应用scope,也要把插槽加上(slot-scope="scope"),否则change之后无奈回显表头中checkbox的勾选状态!!!!! <el-table-column prop="ischecked" > <template slot="header" slot-scope="scope"> <el-checkbox v-model="istableallsearch" @change="tableAllchecked">{{istableallsearch}}</el-checkbox> </template> <template slot-scope="scope"> <el-checkbox :disabled="scope.row.disabled" v-model="scope.row.ischecked" @change="checkSingle"></el-checkbox> </template> </el-table-column>我找了一个小时BUG,真想反手给本人一巴掌/香甜

November 2, 2021 · 1 min · jiezi

关于element-ui:elementUI时间日期选择器更改小图标的位置和icon

问题形容产品经理说,想要把工夫日期选择器的的小图标放在右侧,并且不要小时钟的图标,换成日历的图标。于是乎先看一下官网文档有没有插槽,没有!好吧,那就间接操作DOM吧。 幸好产品不懂技术,要不然会说我间接操作DOM节约性能呢!其实操作这一点点DOM对浏览器性能的影响是能够疏忽的。再者,咱公司的服务器硬件也是杠杠的!思路就是先通过css将工夫日期选择器左侧的小闹钟暗藏起来,而后再插入一个小图标元素并调整地位到右侧即可。 咱们先看一下效果图: 效果图 代码如下<template> <div> <el-date-picker ref="datedate" v-model="value1" type="datetime" placeholder="抉择日期工夫" > </el-date-picker> </div></template><script>export default { name: "CodeVue", data() { return { value1: "", }; }, mounted() { /* 思路:通过document文档,选中日期工夫选择器元素,而后创立一个i标签, 并指定其类名为el-icon-date,并将其插入到日期工夫选择器元素中 而后通过款式的管制调整其到工夫选择器尾部的地位 */ let keyNode = document.querySelector(".el-date-editor"); let iNode = document.createElement("i"); iNode.setAttribute("class", "el-icon-date"); // el-icon-bottom keyNode.appendChild(iNode); iNode.style.position = "absolute"; iNode.style.top = "13px"; iNode.style.right = "32px"; },};</script><style lang="less" scoped>// 暗藏小时钟图标/deep/ .el-date-editor { position: relative; .el-input__prefix { display: none; }}</style>总结在有些状况下,还是须要咱们去间接操作dom的。在硬件疾速迭代的当初,操作一点点dom基本上问题不大,然而还是要留神去优化性能,尽量应用vue提供的规定去操作虚构dom,毕竟虚构dom的性能还是很好的。所以vue官网强调的是尽量不要间接操作dom,并没有说严禁操作dom,想想以前的jQuery,细品一下,好像明确了什么...

October 21, 2021 · 1 min · jiezi

关于element-ui:ElementUI-10个奇淫技巧你知道几个

el-scrollbar 滚动条看到这个组件是不是有点生疏,生疏就对了,因为它素来没有呈现在 element 官网上(预计是性能问题),但好货色怎么能藏着掖着,来上效果图。 是不是比原生的滚动条好看多了,应用办法也非常简单: <el-scrollbar> <div class="box"> <p v-for="item in 15" :key="item">欢送应用 el-scrollbar {{item}}</p> </div></el-scrollbar><style scoped>.el-scrollbar { border: 1px solid #ddd; height: 200px;}.el-scrollbar ::v-deep .el-scrollbar__wrap { overflow-y: scroll; overflow-x: hidden; }</style>只有 scrollbar 外部盒子的高度超过 scrollbar 的高度就会呈现滚动条,横向滚动条同理。 el-upload 模仿点击有时候咱们想用 el-upload 的上传性能,但又不想用 el-upload 的款式,如何实现呢?办法也很简略,暗藏 el-upload,而后再模仿点击就能够了。 <button @click="handleUpload">上传文件</button><el-upload v-show="false" class="upload-resource" multiple action="" :http-request="clickUploadFile" ref="upload" :on-success="uploadSuccess"> 上传本地文件</el-upload><script>export default { methods: { // 模仿点击 handleUpload() { document.querySelector(".upload-resource .el-upload").click() }, // 上传文件 async clickUploadFile(file) { const formData = new FormData() formData.append('file', file.file) const res = await api.post(`xxx`, formData) } // 上传胜利后,清空组件自带的文件列表 uploadSuccess() { this.$refs.upload.clearFiles() } }}</script>el-select 下拉框选项过长很多时候下拉框的内容是不可控的,如果下拉框选项内容过长,势必会导致页面十分不协调,解决办法就是,单行省略加文字提醒。 ...

October 18, 2021 · 2 min · jiezi

关于element-ui:elementUI组件工具中button的原生代码

实现的效果图 实现代码 <!-- * @Author: [you name] * @Date: 2021-10-13 14:27:18 * @LastEditors: [you name] * @LastEditTime: 2021-10-14 16:21:38 * @Description: --><!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> <script src="../js/vue.js"></script> <style> /* 个按钮设置款式 */ button{ width: 98px; height: 40px; margin-top: 30px; border-radius: 5px; border: 1px solid rgb(219, 214, 214); } </style></head><body> <div id="app"> <!-- 应用自定义组件 el-button--> <el-button type="default">默认按钮</el-button> <el-button type="success">胜利按钮</el-button> <el-button type="danger">危险按钮</el-button> <el-button type="info">信息按钮</el-button> <el-button type="warning">正告按钮</el-button> </div> <script> //全局注册组件 并创立一个component实例 Vue.component('el-button', { //父传子 利用props传值 // 父组件通过属性绑定的形式将参数传递给子组件,子组件通过props申明冀望从父组件那里获取的参数。 props: { type: { //类型为String type: String, //带有默认值 default: '默认内容' } }, data() { return { //设置可选款式 style: { default:{ backgroundColor:'white', color:'#333' }, success: { backgroundColor: '#67c23a', color: 'white' }, danger: { backgroundColor: '#f56c6c', color: 'white' }, info: { backgroundColor: '#909399', color: 'white' }, warning: { backgroundColor: '#e6a23c', color: 'white' }, } } }, //网页渲染 template: ` <div> <button :style='style[type]'><slot></slot></button> </div> `, }) let vm = new Vue({ el: '#app', data: {}, methods: {}, created() {}, }) </script></body></html>

October 14, 2021 · 1 min · jiezi

关于element-ui:elmenu导航菜单的二次封装递归组件实现动态多级菜单

问题形容在后盾治理我的项目中,牵涉到权限的货色少数是后端传递过去的数据,前端去展现(当然前端也会做一些管制)。就导航菜单而言,也不能写死了,须要在用户登录了当前,发申请获取用户的对应菜单数据,依据对应的数据去展现对应的菜单。本文记录一下应用组件递归的形式,封装一个动静的、多级的导航菜单,从而实现动态效果。 看这篇文章之前,能够看看我之前的《vue组件的递归自调用~代码思路剖析》文章,本篇文章是之前文章的延长。地址如下:https://segmentfault.com/a/11...效果图咱们先看一下效果图: 思路剖析首先,咱们要和后端沟通返回的数据格式,咱们晓得前端的el-menu菜单的外围数据属性有四个: 菜单的名字name点击菜单进行路由跳转的门路path菜单上小图标icon菜单是不是最内层的菜单,即children是否是空数组,当children为空的时候,就阐明到菜单最里层了。(最里层的菜单children为空数组的时候,点击的时候,做路由跳转)所以须要有name、path、icon、children属性,且得是一个树结构的格局,和左侧导航菜单保持一致。这里咱们模仿一下后端返回的代码后端返回的el-menu菜单数据menuArr: [ {// 留神!留神!有children的菜单项,path不会应用的,所以path为什么都无所谓;没children的,即children的length等于0的,才会应用path属性做路由跳转 name: "前端三大框架", path: "前端三大框架", icon: "el-icon-star-off", children: [ { name: "vue页面", path: "/vue", icon: "el-icon-star-off", children: [], }, { name: "react页面", path: "/react", icon: "el-icon-star-off", children: [], }, { name: "angular页面", path: "/angular", icon: "el-icon-star-off", children: [], }, ], }, { name: "后端两大框架", path: "后端两大框架", icon: "el-icon-star-off", children: [ { name: "Spring Boot页面", path: "/springBoot", icon: "el-icon-star-off", children: [], }, { name: "Spring页面", path: "Spring页面", icon: "el-icon-star-off", children: [ { name: "MySql页面", path: "/mysql", icon: "el-icon-star-off", children: [], }, { name: "Redis页面", path: "/redis", icon: "el-icon-star-off", children: [], }, ], }, { name: "Mybatis页面", path: "/mybatis", icon: "el-icon-star-off", children: [], }, ], }, ]咱们先看一下非动静多级菜单的写法,而后再看一下递归组件动静多级菜单的写法非动静多级菜单(写死了,不灵便,不倡议应用)<el-menu :default-active="activeIndex" class="elMenu" background-color="#333" text-color="#B0B0B2" active-text-color="#fff" :unique-opened="true" router ref="elMenu" @select="menuSelect"> <el-submenu index="非叶子节点也须要index属性"> <template slot="title"> <i class="el-icon-star-off"></i> <span>前端三大框架</span> </template> <!-- 这个是没子节点的 没有子内容,用el-menu-item构造 --> <el-menu-item index="/vue"> <i class="el-icon-star-off"></i> <span slot="title">vue页面</span> </el-menu-item> <el-menu-item index="/react"> <i class="el-icon-star-off"></i> <span slot="title">react页面</span> </el-menu-item> <el-menu-item index="/angular"> <i class="el-icon-pear"></i> <span slot="title">angular页面</span> </el-menu-item> </el-submenu> <el-submenu index="非叶子节点也须要index属性哦"> <template slot="title"> <i class="el-icon-star-off"></i> <span>后端两大框架</span> </template> <el-menu-item index="/springBoot"> <i class="el-icon-star-off"></i> <span slot="title">Spring Boot页面</span> </el-menu-item> <!-- 留神看这里有子节点的无子节点的html标签的区别 --> <!-- 这个是有子节点的 还有子内容,用el-submenu构造--> <el-submenu index="非叶子节点也须要index属性哈"> <template slot="title"> <i class="el-icon-star-off"></i> <span>Spring页面</span> </template> <el-menu-item index="/mysql"> <i class="el-icon-star-off"></i> <span slot="title">MySql页面</span> </el-menu-item> <el-menu-item index="/redis"> <i class="el-icon-star-off"></i> <span slot="title">Redis页面</span> </el-menu-item> </el-submenu> <!-- 这个是没子节点的 没有子内容,用el-menu-item构造 --> <el-menu-item index="/mybatis"> <i class="el-icon-star-off"></i> <span slot="title">Mybatis页面</span> </el-menu-item> </el-submenu></el-menu>发现法则通过上述代码,咱们发现,el-menu代码大抵分为两类,有子集和没有子集的 ...

October 11, 2021 · 2 min · jiezi

关于element-ui:elemenntUI-eldrawer组件中使用时间选择器自动弹出选择器下拉框的问题

问题:点击关上抽屉组件时,工夫选择器(或选择器类)下拉框会自动弹出,如图所示: 自己摸索了两个办法,先只上最简略暴力的方法!解决办法:1.在选择器上加上disabled属性。 <el-drawer size="25%" class="car-drawer" :wrapperClosable="false" :visible="drawerVisible" :destroy-on-close="true" :append-to-body="true" :with-header="false" @open="handleOpenDrawer" @close="handleCloseDrawer" > <el-date-picker style="margin-right: 10px;" size="small" class="control-date-picker2" v-model="time" clearable :disabled="drawerShow" :editable="false" type="datetimerange" range-separator="至" start-placeholder="开始日期" end-placeholder="完结日期" value-format="yyyy-MM-dd HH:mm:ss" :default-time="['00:00:00', '23:59:59']" ></el-date-picker></el-drawer>data() { return { drawerShow: true };},2.利用open事件解除禁用性能。 handleOpenDrawer() { this.$nextTick(() => { this.drawerShow = false; });}3.敞开时应用close事件再重置禁用状态。 handleCloseDrawer() { this.drawerShow = true;},

September 26, 2021 · 1 min · jiezi

关于element-ui:基于elementui的select和tree自写一个下拉选择树

下拉树理论开发中应用场景很多,然而组件并非肯定满足我的项目开发的需要,所以本人封装了一个。 阐明:该下拉树在一个table中一列展现片段代码不能失常运行,所以次要传播的是一种解决形式的思路,有问题请斧正。 template: <el-select v-model="scope.row.deptname" placeholder="请抉择" class="select-with-tree" filterable :filter-method="($event)=> filterdeptTree($event,scope.$index)"> <el-option :value="scope.row.deptname" class="swt-option"> <el-tree :ref="'deptselectree'+scope.$index" highlight-current @node-click="($event)=> changeChoosedDept($event,scope.row,scope.$index)" :indent="10" node-key="code" :expand-on-click-node="false" accordion :filter-node-method="filterdeptNode" :data="depttreelist"> <div class="role-dept-tree-node clearfix" slot-scope="{ data }"> <div class="tree-title-code" v-show="data.name">{{data.code}}</div> <div class="tree-title">{{data.name?data.name:data.code}}</div> </div> </el-tree> </el-option> </el-select>js: /** * select-tree搜寻联动 * filterTree为selectfilter,获取输出的内容触发filteNode * filterNode为treefilter * **/ filterdeptTree(val,index) { this.$nextTick(() => { if (this.$refs['deptselectree' + index] && this.$refs['deptselectree' + index][0]) { this.$refs['deptselectree' + index][0].filter(val) } }) }, filterdeptNode(value, data) { if (!value) return true; var dataarr = [] if (data.name) { dataarr.push(data.name) } if (data.code) { dataarr.push(data.code) } var datastring = JSON.stringify(dataarr) return datastring.indexOf(value) !== -1; },/** * 点击部门后即触发行对应的dept和deptname的变动 * 参数别离为:点击节点,行数据,行index * **/ changeChoosedDept(deptdata,data,index) { let that = this; this.$nextTick(() => { this.$set(data, 'dept', deptdata.code) this.$set(data, 'deptname', deptdata.name) }) },css因为相当于在select外面嵌了一个tree,所以在款式上须要本人复写原组件款式 ...

September 16, 2021 · 1 min · jiezi

关于element-ui:解决elementui分页时eltable选择框不显示问题

el-table分页时抉择框不显示问题,例如:第一页抉择了数据,点击分页到第二页,而后再返回第一页时,第一页抉择的数据失落了,想破了脑袋相处了上面的办法,求大神求教外围办法:// 表格单选事件 selectRole(selection, row) { // 因为翻页点选后selection会呈现为undefined的元素,须要进行是否存在判断 if (selection && selection.find(item => item && item.permissionId === row.permissionId)) { // 选中新增一行 this.addRows([row]); } else { // 勾销删除一行 this.removeRows([row]); } }, // 表格全选事件 selectRoleAll(selection) { // 如果有则是全选否则就是全勾销 if (selection.length > 0) { this.addRows(this.tableList); } else { this.removeRows(this.tableList); } }, // 增加选中行 addRows(rows) { for (const item of rows) { // 如果选中的数据中没有这条就增加进去 if (!this.selectedRow.find(i => i.id === item.id)) { this.selectedRow.push(item); } } }, // 勾销选中行 removeRows(rows) { if (this.selectedRow && this.selectedRow.length) { for (const item of rows) { this.selectedRow = this.selectedRow.filter(i => i.id !== item.id); } } }, // 前端实现分页 以及翻页记忆勾选 setPagination(no, size, data) { // this.tableList = data; this.toggleSelection(this.selectedRow); }, // 选中table已有数据 toggleSelection(rows) { if (rows && rows.length) { rows.forEach(row => { this.$nextTick(() => { const checked = this.tableList.find(tableRow => tableRow.id === row.id); this.$refs.roleData.toggleRowSelection(checked); }); }); } else { if (this.$refs.roleData !== undefined) { this.$refs.roleData.clearSelection(); } } },残缺代码:<template> <div> <div class=""> <el-table border highlight-current-row :height="500" resizable :data="tableList" ref="roleData" :row-style="selectedHighlight" @select="selectRole" @select-all="selectRoleAll" > <el-table-column type="selection" width="40"></el-table-column> <el-table-column label="序号" type="index" width="60"></el-table-column> <el-table-column v-for="(item, index) in tableLabelStaff" :key="index" :prop="item.prop" :width="item.width" :label="item.label" :show-overflow-tooltip="item.showOverTooltip" > <template slot-scope="scope"> <span>{{ scope.row[scope.column.property] }}</span> </template> </el-table-column> </el-table> </div> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="rolepageIndex" :page-sizes="[5, 10, 15, 20]" :page-size="rolepageSize" layout="total, sizes, prev, pager, next, jumper" :total="rolepageCount" ></el-pagination> </div></template><script>export default { data() { return { // 分页 rolepageIndex: 1, rolepageSize: 5, rolepageCount: 0, // 记忆分页的时table选中状态 tableList: [], // 记忆曾经选中的 selectedRow: [], // 表头的数据 tableLabelStaff: [ { label: '日期', width: '133', prop: 'date', showOverTooltip: true, sortable: false }, { label: '姓名', width: '90', prop: 'name', showOverTooltip: true, sortable: false }, { label: '地址', width: '90', prop: 'address', showOverTooltip: true, sortable: false } ] }; }, computed: { // 相当于后端接口返回的数据 tableData() { let list = []; for (let i = 0; i < 100; i++) { list[i] = {}; list[i]['date'] = '2016-05-02' + i; list[i]['name'] = '王小虎' + i; list[i]['address'] = `上海市普陀区金沙江路${i}号`; list[i]['id'] = i; } return list; } }, mounted() { // 获取第一页的接口 this.currentChangePage(this.tableData, this.rolepageIndex); this.roleData = this.tableData; this.rolepageCount = this.tableData.length; this.setPagination(this.rolepageIndex, this.rolepageSize, this.roleData); }, methods: { handleSizeChange: function(pageSize) { // 每页条数切换 this.rolepageSize = pageSize; this.handleCurrentChange(this.rolepageIndex); }, handleCurrentChange: function(currentPage) { //页码切换 this.rolepageIndex = currentPage; this.currentChangePage(this.tableData, currentPage); }, //分页办法(重点) currentChangePage(list, currentPage) { let from = (currentPage - 1) * this.rolepageSize; let to = currentPage * this.rolepageSize; this.tableList = []; for (; from < to; from++) { if (list[from]) { this.tableList.push(list[from]); } } this.setPagination(this.rolepageIndex, this.rolepageSize, this.roleData); }, // 表格单选事件 selectRole(selection, row) { // 因为翻页点选后selection会呈现为undefined的元素,须要进行是否存在判断 if (selection && selection.find(item => item && item.permissionId === row.permissionId)) { // 选中新增一行 this.addRows([row]); } else { // 勾销删除一行 this.removeRows([row]); } }, // 表格全选事件 selectRoleAll(selection) { // 如果有则是全选否则就是全勾销 if (selection.length > 0) { this.addRows(this.tableList); } else { this.removeRows(this.tableList); } }, // 增加选中行 addRows(rows) { for (const item of rows) { // 如果选中的数据中没有这条就增加进去 if (!this.selectedRow.find(i => i.id === item.id)) { this.selectedRow.push(item); } } }, // 勾销选中行 removeRows(rows) { if (this.selectedRow && this.selectedRow.length) { for (const item of rows) { this.selectedRow = this.selectedRow.filter(i => i.id !== item.id); } } }, // 前端实现分页 以及翻页记忆勾选 setPagination(no, size, data) { // this.tableList = data; this.toggleSelection(this.selectedRow); }, // 选中table已有数据 toggleSelection(rows) { if (rows && rows.length) { rows.forEach(row => { this.$nextTick(() => { const checked = this.tableList.find(tableRow => tableRow.id === row.id); this.$refs.roleData.toggleRowSelection(checked); }); }); } else { if (this.$refs.roleData !== undefined) { this.$refs.roleData.clearSelection(); } } }, }};</script><style lang="scss"></style>

August 21, 2021 · 3 min · jiezi

关于element-ui:解决elementui的DatePicker-日期选择器带快捷选项自定义12个月的方法

## 废话不多说,线上效果图 问题形容:网上找了很久,都找不到elementui的DatePicker 日期选择器能够自定义某年某月的快捷选项,elementui的官网例子都是依据以后月份来做的快捷选项1、自定义带快捷选项的12个月的办法 <template> <div class="kingPickerIndex" style="margin: 300px;"> <el-date-picker :default-value="kingDefaultValue" popper-class="kingChangePickPanelPaBo" ref="elPicker" value-format="yyyy-MM-dd" format="yyyy-MM-dd" v-model="date" align="right" type="dates" placeholder="抉择日期" :picker-options="pickerOptions" ></el-date-picker> </div></template><script>export default { name: 'kingPicker', data() { return { date: null, kingDefaultValue: '', pickerOptions: {} }; }, computed: { monthList() { let monthList = []; for (var i = 1; i < 13; i++) { monthList.push({ label: `${i}月`, value: i }); } return monthList; } }, mounted() { this.initpickerOptions(); }, methods: { // 初始化picker抉择参数 initpickerOptions() { let that = this; this.pickerOptions.shortcuts = []; // 给date选择器加上12个月的快捷方式 this.monthList.forEach((item, index) => { this.pickerOptions.shortcuts[index] = {}; this.pickerOptions.shortcuts[index]['text'] = item.label; this.pickerOptions.shortcuts[index]['onClick'] =(picker)=> { // 获取选择器中的年份, let curYear = that.$refs['elPicker'].picker.year; // 月份则是用户点击哪个月就是哪个月 let curMonth = item.value; // 获取用户抉择某年某月的第一天和最初一天 let assignMoFiAndAf = that.getAssignMoFiAndAf(curYear, curMonth); let curFirstDay = assignMoFiAndAf.kingFirstDay; let curLastDay = assignMoFiAndAf.kingLastDay; // 获取某年某月的所有日期 let curDays = that.getAllDate(curFirstDay, curLastDay); let newcurDays = []; // 设置picker的默认值,解决抉择完某月的快捷方式后,从新关上picker后的显示问题 that.kingDefaultValue = curDays[0]; // 设置赋值给picker的工夫值,只有这样能力设置胜利(还有其余方法,请大神指教) if (curDays.length > 0) { curDays.forEach(item => { newcurDays.push(new Date(new Date(item).setHours(0, 0, 0, 0))); }); } picker.$emit('pick', newcurDays); }; }); }, // 获取指定月份的第一天和最初一天 getAssignMoFiAndAf(y, m) { let firstDay = new Date(y, m - 1, 1); let lastDay = new Date(y, m, 0); let kingFirstDay = this.formatDate(firstDay, 'YYYY-MM-dd'); let kingLastDay = this.formatDate(lastDay, 'YYYY-MM-dd'); return { kingFirstDay, kingLastDay }; }, // 格式化日期 formatDate(date, type) { date = new Date(date); let myyear = date.getFullYear(); let mymonth = date.getMonth() + 1; let myweekday = date.getDate(); if (!!type) { mymonth < 10 ? (mymonth = '0' + mymonth) : mymonth; myweekday < 10 ? (myweekday = '0' + myweekday) : myweekday; if (type == 'YYYY-MM-dd') { return `${myyear}-${mymonth}-${myweekday}`; } else { return `${myyear}-${mymonth}-${myweekday}`; } } else { return `${mymonth}月${myweekday}日`; } }, /* **获取开始和完结日期两头的所有日期(包含开始和完结日期) **start:开始日期(yyyy-mm-dd) **end:完结日期(yyyy-mm-dd) */ getAllDate(start, end) { let dateArr = []; let startArr = start.split('-'); let endArr = end.split('-'); let db = new Date(); db.setUTCFullYear(startArr[0], startArr[1] - 1, startArr[2]); let de = new Date(); de.setUTCFullYear(endArr[0], endArr[1] - 1, endArr[2]); let unixDb = db.getTime(); let unixDe = de.getTime(); let stamp; const oneDay = 24 * 60 * 60 * 1000; for (stamp = unixDb; stamp <= unixDe; ) { dateArr.push(this.formatAllDate(new Date(parseInt(stamp)))); stamp = stamp + oneDay; } return dateArr; } }};</script><style lang="scss">// 解决picker的快捷方式为12个月的时候,前面两个月在面板下面看不到的问题.kingChangePickPanelPaBo { .el-picker-panel__body-wrapper { .el-picker-panel__sidebar { padding-bottom: 50px; } }}</style>

August 19, 2021 · 2 min · jiezi

关于element-ui:太坑了百度了所有都找不到的答案elementui的table的多级表头固定前n列的问题

废话不多说,先看成果如下,我固定的是前三列,简单表头渲染,是我前一章节说的(https://segmentfault.com/a/11...) 1、elementui的table的多级表头固定前n列(留神:n列是依据width来固定的)的问题所在1.1 发现给了el-column固定宽度,和fixed属性后,其余没有这两个属性的el-column局部被加上了is-hidden的类名(这个要浏览器控制台查看html构造代码才晓得),导致页面渲染的数据被暗藏了,所以要想方法去掉这个类名1.2 通过查看html构造后,应用jquery去掉is-hidden类名(没有想到更好的方法,有其余方法的大神心愿能点拔我一下)2、解决的方法:2.1 外围代码:this.$nextTick(() => { // 如果不是固定列用这个 let myTrList = $('.kingChangeHead .el-table__header .has-gutter tr'); // 第一行表头(表头的款式) let colorTr = myTrList.eq(0); let colorTh = colorTr.find('th').eq(0); $(colorTh).removeClass('is-hidden'); $(colorTh) .find('.cell') .css({ color: '#000', 'font-size': '18px', 'font-weight': 'bold' }); /** * @Date: 2021-08-17 * @author @拿菜刀砍电线 * @Description:为了解决elementui的简单表头,固定前三列的问题 * 问题剖析1、发现给了固定宽度,和fixed属性后,没有固定的局部被加上了is-hidden的类名,导致页面数据被暗藏了,所以要想方法去掉这个类名 * 2、通过查看html构造后,应用jquery去掉is-hidden类名 */ let kingBody = $('.kingChangeHead .el-table__body-wrapper .el-table__body tr'); kingBody.each(function(index, domEle) { $(domEle) .find('td') .each(function(index1, domEle1) { $(domEle1).removeClass('is-hidden'); }); }); if (this.$refs.mutipleTable !== undefined) { this.$refs.mutipleTable.doLayout(); } });2.2 全副代码:<template> <div class="barCodeManageIndex"> <div> <div class="collapseContent"> <div id="searchForm" class="collapseCon"> <el-form label-position="right"> <div class="l-f"> <el-form-item label="年份:" label-width="50px"> <el-date-picker :clearable="false" format="yyyy" value-format="yyyy" v-model="searchForm.year" type="year" placeholder="请抉择"></el-date-picker> </el-form-item> <el-form-item label="月份:" label-width="50px"> <el-select :clearable="false" v-model.trim="searchForm.month" placeholder="请抉择"> <el-option v-for="(item, index) in monthList" :key="index" :label="item.label" :value="item.value"></el-option> </el-select> </el-form-item> </div> </el-form> </div> </div> </div> <div class="collapseContent"> <div @click.self="show = !show" class="l-f l-flex-c collapseCon pointer"> <i @click.self="show = !show" class="el-icon-arrow-up o-mr-40" :class="{ isRotate: !show }"></i> <el-button class="o-ml-12" icon="el-icon-zoom-in" v-preventReClick type="goon" size="mini" @click="searchAll">查问</el-button> <el-button class="o-ml-12" icon="el-icon-my-export" v-preventReClick type="success" size="mini" @click="exportFile">导出</el-button> <el-button class="o-ml-12 kingButton" icon="el-icon-full-screen" v-preventReClick type="success" size="mini" @click="clickFullscreen('kingFullScreen')"> 全屏显示 </el-button> </div> <div> <el-collapse-transition> <div v-show="show"> <div class="showToolTip changeElBoCoSt kingChangeHead"> <el-table id="kingFullScreen" v-loading="loading" :cell-style="sca_CellStyle" border highlight-current-row :height="clientHeight" resizable :data="tableData" ref="mutipleTable" :span-method="objectSpanMethod" :header-cell-style="headerCellStyleNameKing" :row-style="selectedHighlight_custom" > <el-table-column fixed width="300" :label="subCompanyMonth + '月-五大战区各项品质汇总'" align="center"> <el-table-column fixed :index="kingIndex" type="index" label="序号" width="60" align="center"></el-table-column> <el-table-column fixed prop="type" label="类型" width="120" align="center"> <template slot-scope="scope"> <span v-if="scope.$index == 0" style="font-weight: bold;"> 各区排名 <span style="color: blue;">第一</span> 我的项目个数 </span> <span v-else-if="scope.$index == 1" style="font-weight: bold;"> 各区排名 <span style="color: red;">最初</span> 我的项目个数 </span> <span v-else>{{ scope.row.type }}</span> </template> </el-table-column> <el-table-column fixed prop="project" label="我的项目" width="120" align="center"></el-table-column> <el-table-column v-if="tableData && tableData.length > 0" v-for="(value1, key, index) in tableDataDetail" :key="index + 'day'" :label="key" align="center" > <el-table-column v-for="(value2, key2, index2) in value1" :key="index2" :label="key2" align="center"> <el-table-column v-for="(item1, index1) in value2" :key="index1" :label="item1.name" align="center"> <template slot-scope="scope"> <span :style="{ color: scope.row.daySale[key][key2][index1]['color'], fontWeight: scope.row.daySale[key][key2][index1]['fontBold'] }" > {{ scope.row.daySale[key][key2][index1]['value'] }} </span> </template> </el-table-column> </el-table-column> </el-table-column> </el-table-column> </el-table> </div> </div> </el-collapse-transition> </div> </div> </div></template><script>export default { name: 'brCoInAn_daRe_ovSuOfThZone', data() { return { // 代表的月份 subCompanyMonth: '', formLabelWidth: '120px', searchFormLableWidth: '100px', // 查问参数 searchForm: { month: '', year: null }, show: true, tableData: [], // 表格高度 clientHeight: null, // 统计合并多少行 needMergeArr: ['type'], // 有合并项的列 rowMergeArrs: {} // 蕴含须要一个或多个合并项信息的对象 }; }, computed: { monthList() { let monthList = []; for (var i = 1; i < 13; i++) { monthList.push({ label: `${i}月`, value: i }); } return monthList; }, loading() { return this.GetStore('globalNotice', 'kingLoading'); }, tableDataDetail() { let tableData = []; if (this.tableData && this.tableData.length > 0) { tableData = this.tableData[0]['daySale']; } return tableData; } }, mounted() { this.searchForm.year = this.GetCurrentTime().orderYear; this.searchForm.month = Number(this.GetCurrentTime().yearMonth.substring(5, 7)); // 自定义table的宽度,为了固定表头 this.clientHeight = document.body.clientHeight - 230; const that = this; window.onresize = () => { return (() => { window.clientHeight = document.body.clientHeight; that.clientHeight = window.clientHeight - 230; })(); }; }, updated() { this.$nextTick(() => { if (this.$refs.mutipleTable !== undefined) { this.$refs.mutipleTable.doLayout(); } }); }, methods: { // 第一第二行背景色 selectedHighlight_custom({ row, rowIndex }) { // if (rowIndex == 0 || rowIndex == 1) { // return { // 'background-color': '#ddd' // }; // } }, // 点击导出按钮 exportFile() { this.exportFile_king(this.$api.reBrGuAnalyAreaexportReport, this.searchForm); }, /** * @description 实现合并行或列 * @param row:Object 须要合并的列name 如:'name' 'id' * @param column:Object 以后行的行数,由合并函数传入 * @param rowIndex:Number 当前列的数据,由合并函数传入 * @param columnIndex:Number 当前列的数据,由合并函数传入 * * @return 函数能够返回一个蕴含两个元素的数组,第一个元素代表rowspan, * 第二个元素代表colspan。 也能够返回一个键名为rowspan和colspan的对象 */ objectSpanMethod({ row, column, rowIndex, columnIndex }) { // 第一行的达成,环比,排名,列合并 if (rowIndex === 0 || rowIndex === 1) { if (column.label == '达成') { return [1, 3]; } else if (column.label == '环比') { return [0, 0]; } else if (column.label == '排名') { return [0, 0]; } } // 第一,第二行的1,2,3列合并 if (rowIndex === 0 || rowIndex === 1) { if (columnIndex === 0) { return [0, 0]; } else if (columnIndex === 1) { return [1, 3]; } else if (columnIndex === 2) { return [0, 0]; } } // 办法二:(合并行) for (let key in this.rowMergeArrs) { if (column.property == key) { let _row = this.rowMergeArrs[key].rowArr[rowIndex]; let _col = _row > 0 ? 1 : 0; return [_row, _col]; } } }, // 用来合并表头的(label为“整体”的高低两行合并) headerCellStyleNameKing({ row, column, rowIndex, columnIndex }) { if (rowIndex === 0) { this.$nextTick(() => { if ($('.' + column.id).length !== 0) { $('.' + column.id + ' .cell').css({ color: '#111', 'font-weight': 'bold' }); } }); return column; } else if (rowIndex === 2) { if (column.label == '整体') { this.$nextTick(() => { if ($('.' + column.id).length !== 0) { $('.' + column.id + ' .cell').css({ color: '#111', 'font-weight': 'bold', 'font-size': '20px' }); $('.' + column.id).attr('rowspan', 2); // var _c = document.getElementsByClassName(column.id); // document.getElementsByClassName(column.id)[0].setAttribute('rowSpan', 2); } }); return column; } else { return { textAlign: 'center', color: '#111111', fontSize: '16px', fontWeight: 400 }; } } else if (rowIndex === 3) { if (column.label == '整体') { return { display: 'none' }; } else { return { textAlign: 'center', color: '#111111', fontSize: '16px', fontWeight: 400 }; } } else { return { textAlign: 'center', color: '#111111', fontSize: '16px', fontWeight: 400 }; } }, // 解决下标从第二行开始,(数字要从1开始) kingIndex(index) { if (index != 0 || index != 1) { return index - 1; } }, searchAll() { this.tableData = []; this.getList(); }, getList() { // 因为工夫是肯定要的,如果用户没有抉择工夫,要强制 if (!this.searchForm.year) { this.searchForm.year = this.GetCurrentTime().orderYear; } if (!this.searchForm.month) { this.searchForm.month = Number(this.GetCurrentTime().yearMonth.substring(5, 7)); } // 表头数据 this.subCompanyMonth = this.searchForm.month || ''; this.$store.commit('Edit_loading', true); let param = this.searchForm; this.$method(this.$api.reBrGuAnalygetAreaSumReport, 'post', param).then(res => { if (res.data && res.data.length > 0) { res.data.forEach((item, index) => { for (let key in item.daySale) { for (let key1 in item.daySale[key]) { item.daySale[key][key1].forEach((item1, index1) => { // 色彩和加粗 item1.color = null; item1.fontBold = null; // 如果有值 if (item1.value != null) { // 有没有变色 if (item1.isRanking == 1) { item1.color = 'blue'; item1.fontBold = 'bold'; } else if (item1.isRanking == 2) { item1.color = 'red'; item1.fontBold = 'bold'; } // 看是不是整数类型 // 2代表为整数 if (item1.algorithm != 2 && item1.algorithm != 4 && item1.algorithm != null) { item1.value = this.Big(item1.value).mul(100) + '%'; } } else { item1.value = '-'; } }); } } }); } this.tableData = res.data; // 解决数据 this.rowMergeArrs = this.rowMergeHandle(this.needMergeArr, this.tableData); this.$nextTick(() => { // 如果不是固定列用这个 let myTrList = $('.kingChangeHead .el-table__header .has-gutter tr'); // 第一行表头(表头的款式) let colorTr = myTrList.eq(0); let colorTh = colorTr.find('th').eq(0); $(colorTh).removeClass('is-hidden'); $(colorTh) .find('.cell') .css({ color: '#000', 'font-size': '18px', 'font-weight': 'bold' }); /** * @Date: 2021-08-17 * @author @拿菜刀砍电线 * @Description:为了解决elementui的简单表头,固定前三列的问题 * 问题剖析1、发现给了固定宽度,和fixed属性后,没有固定的局部被加上了is-hidden的类名,导致页面数据被暗藏了,所以要想方法去掉这个类名 * 2、通过查看html构造后,应用jquery去掉is-hidden类名 */ let kingBody = $('.kingChangeHead .el-table__body-wrapper .el-table__body tr'); kingBody.each(function(index, domEle) { $(domEle) .find('td') .each(function(index1, domEle1) { $(domEle1).removeClass('is-hidden'); }); }); if (this.$refs.mutipleTable !== undefined) { this.$refs.mutipleTable.doLayout(); } }); }); } }};</script><style lang="scss">.changeElBoCoSt { .el-table .cell { color: #333; } .el-table__header { // border-right: 1px solid #000; border-top: 1px solid #000; border-left: 1px solid #000; } .el-table__body { // border-right: 1px solid #000; // border-bottom: 1px solid #000; border-left: 1px dashed #000; } .el-table--border td { border-right: 1px dashed #000; } .el-table--border th { border-right: 1px solid #000; } .el-table__body-wrapper .el-table--border.is-scrolling-left ~ .el-table__fixed { border-right: 1px dashed #000; } .el-table--border th { border-bottom: 1px solid #000; } .el-table__fixed-right-patch { border-bottom: 1px dashed #000; } .el-table td { border-bottom: 1px dashed #000; } .el-table th.is-leaf { border-bottom: 1px solid #000; } .el-table__header tr, .el-table__header th { background-color: #ffc000 !important; } // // body的每一行的最初一个单元格 // .el-table__body tr td:last-child { // border-right: 1px solid #000; // } // // body的最初一行 // .el-table__body tr:last-child td { // border-bottom: 1px solid #000; // } // //(刚好最初两行的第一列有合并才要这个) // .el-table__body tr:first-child td:first-child { // border-bottom: 1px solid #000; // } // 双下划线(表体) // .kingRowIndex td { // border-bottom: 2px solid #000000 !important; // } // 表头 // .kingRowIndex1 { // border-right: 2px solid #000000 !important; // }}</style>

August 17, 2021 · 6 min · jiezi

关于element-ui:浪迹天涯king教你用elementui做复杂的表格去处理报表数据合并表头合并表体行和列

掘金链接(掘金-简单的报表开发(elementui)) 1、不必多说了,先上图片 2、性能个性1.表头的背景色,题目的虚线边框2.表头的个别单元格款式3. 表头合并行性能4. 简单的动静表头性能5. 表体渲染下标从第n行开始6. 表体第一行,第二行的1,2,3列合并7. 表体第一行,第二行的,“达成”,“环比”,“排名”合并8. 表体的个别单元格款式3、代码(间接复制粘贴看成果) <template> <div class="changeElBoCoSt kingChangeHead"> <el-table :data="tableData" style="width: 100%" :span-method="objectSpanMethod" :row-class-name="rowClassName" :cell-class-name="cellClassNameKing" :header-cell-class-name="headerCellClassNameKing" :header-cell-style="headerCellStyleNameKing" > <el-table-column label="7月-罗湖东子公司各项品质达成汇总" align="center"> <el-table-column :index="kingIndex" type="index" label="序号" align="center"></el-table-column> <el-table-column label="类型" width="120" align="center"> <template slot-scope="scope"> <span v-if="scope.$index == 0" style="font-weight: bold;"> 各区排名 <span style="color: blue;">第一</span> 我的项目个数 </span> <span v-else>{{ scope.row.type }}</span> </template> </el-table-column> <el-table-column prop="project" label="我的项目" width="120" align="center"></el-table-column> <el-table-column v-for="(value1, key, index) in tableData[0]['daySale']" :key="index + 'day'" :label="key" align="center"> <el-table-column v-for="(value2, key2, index2) in value1" :key="index2" :label="key2" align="center"> <el-table-column v-for="(item1, index1) in value2" :key="index1" :label="item1.name" align="center"> <template slot-scope="scope"> <span :style="{ color: scope.row.daySale[key][key2][index1]['isColor'] == 1 ? 'blue' : scope.row.daySale[key][key2][index1]['isColor'] == 2 ? 'red' : '', fontWeight: scope.row.daySale[key][key2][index1]['isColor'] == 1 || scope.row.daySale[key][key2][index1]['isColor'] == 2 ? 'bold' : '' }">{{ scope.row.daySale[key][key2][index1]['value'] }}</span> </template> </el-table-column> </el-table-column> </el-table-column> </el-table-column> </el-table> </div></template><script>export default { data() { return { tableData: [ { type: '各区排名第一我的项目个数', project: '各区排名第一我的项目个数', daySale: { '7月': { 整体: [ { name: '整体', value: 0.32, isColor:null, } ], 宝安: [ { name: '达成', value: 0.33, isColor:null, }, { name: '环比', value: 0.33, isColor:null, }, { name: '排名', value: 0.33, isColor:null, } ], 龙岗: [ { name: '达成', value: 0.331, isColor:null, }, { name: '环比', value: 0.341, isColor:null, }, { name: '排名', value: 0.351, isColor:null, } ] }, '第一周(7月1日-6日)': { 整体: [ { name: '整体', value: 0.322, isColor:null, } ], 宝安: [ { name: '达成', value: 0.332, isColor:null, }, { name: '环比', value: 0.342, isColor:null, }, { name: '排名', value: 0.352, isColor:null, } ], 龙岗: [ { name: '达成', value: 0.332, isColor:null, }, { name: '环比', value: 0.342, isColor:null, }, { name: '排名', value: 0.352, isColor:null, } ] } } }, { type: '各区排名最初我的项目个数', project: '各区排名最初我的项目个数', daySale: { '7月': { 整体: [ { name: '整体', value: 0.32, isColor:1, } ], 宝安: [ { name: '达成', value: 0.33, isColor:null, }, { name: '环比', value: 0.34, isColor:2, }, { name: '排名', value: 0.35, isColor:null, } ], 龙岗: [ { name: '达成', value: 0.331, isColor:null, }, { name: '环比', value: 0.341, isColor:null, }, { name: '排名', value: 0.351, isColor:null, } ] }, '第一周(7月1日-6日)': { 整体: [ { name: '整体', value: 0.322, isColor:null, } ], 宝安: [ { name: '达成', value: 0.332, isColor:null, }, { name: '环比', value: 0.342, isColor:null, }, { name: '排名', value: 0.352, isColor:null, } ], 龙岗: [ { name: '达成', value: 0.332, isColor:null, }, { name: '环比', value: 0.342, isColor:null, }, { name: '排名', value: 0.352, isColor:null, } ] } } }, { type: '收件1', project: '收件滞留率1', daySale: { '7月': { 整体: [ { name: '整体', value: 0.328, isColor:null, } ], 宝安: [ { name: '达成', value: 0.338, isColor:null, }, { name: '环比', value: 0.348, isColor:null, }, { name: '排名', value: 0.358, isColor:null, } ], 龙岗: [ { name: '达成', value: 0.3318, isColor:null, }, { name: '环比', value: 0.3418, isColor:null, }, { name: '排名', value: 0.3518, isColor:null, } ] }, '第一周(7月1日-6日)': { 整体: [ { name: '整体', value: 0.3229, isColor:null, } ], 宝安: [ { name: '达成', value: 0.3329, isColor:null, }, { name: '环比', value: 0.3429, isColor:null, }, { name: '排名', value: 0.3529, isColor:null, } ], 龙岗: [ { name: '达成', value: 0.3329, isColor:null, }, { name: '环比', value: 0.3429, isColor:null, }, { name: '排名', value: 0.3529, isColor:null, } ] } } } ], selectData: [], // 统计合并多少行 needMergeArr: ['type'], // 有合并项的列 rowMergeArrs: {} // 蕴含须要一个或多个合并项信息的对象 }; }, mounted() { this.getList(); }, updated() { this.$nextTick(() => { if (this.$refs.mutipleTable !== undefined) { this.$refs.mutipleTable.doLayout(); } }); }, methods: { /** * @description 实现合并行或列 * @param row:Object 须要合并的列name 如:'name' 'id' * @param column:Object 以后行的行数,由合并函数传入 * @param rowIndex:Number 当前列的数据,由合并函数传入 * @param columnIndex:Number 当前列的数据,由合并函数传入 * * @return 函数能够返回一个蕴含两个元素的数组,第一个元素代表rowspan, * 第二个元素代表colspan。 也能够返回一个键名为rowspan和colspan的对象 */ objectSpanMethod({ row, column, rowIndex, columnIndex }) { // 第一行的达成,环比,排名,列合并 if (rowIndex === 0) { if (column.label == '达成') { return [1, 3]; } else if (column.label == '环比') { return [0, 0]; } else if (column.label == '排名') { return [0, 0]; } } // 第一,第二行的1,2,3列合并 if (rowIndex === 0 || rowIndex === 1) { if (columnIndex === 0) { return [0, 0]; } else if (columnIndex === 1) { return [1, 3]; } else if (columnIndex === 2) { return [0, 0]; } } // 办法二:(合并行) for (let key in this.rowMergeArrs) { if (column.property == key) { let _row = this.rowMergeArrs[key].rowArr[rowIndex]; let _col = _row > 0 ? 1 : 0; return [_row, _col]; } } }, // 用来合并表头的(label为“整体”的高低两行合并) headerCellStyleNameKing({ row, column, rowIndex, columnIndex }) { if(rowIndex === 0){ this.$nextTick(() => { if ($('.'+column.id).length !== 0) { $('.'+column.id+' .cell').css({'color':'#111','font-weight': 'bold'}); } }); return column; } else if (rowIndex === 2) { if (column.label == '整体') { this.$nextTick(() => { if ($('.'+column.id).length !== 0) { $('.'+column.id+' .cell').css({'color':'#111','font-weight': 'bold'}); $('.'+column.id).attr('rowspan', 2); // var _c = document.getElementsByClassName(column.id); // document.getElementsByClassName(column.id)[0].setAttribute('rowSpan', 2); } }); return column; } } else if (rowIndex === 3) { if (column.label == '整体') { return { display: 'none' }; } } }, // 解决下标从第二行开始,(数字要从1开始) kingIndex(index) { if (index != 0 || index != 1) { return index - 1; } }, // 解决表头的双下划线 headerCellClassNameKing({ row, column, rowIndex, columnIndex }) { if (columnIndex == 6) { return 'kingRowIndex1'; } }, cellClassNameKing({ row, column, rowIndex, columnIndex }) { if (columnIndex == 6) { return 'kingRowIndex1'; } }, // 给行增加类名(用于单元格的下划线问题) rowClassName({ row, rowIndex }) { if (rowIndex == this.kingRowIndex - 1) { return 'kingRowIndex'; } }, getList() { // 实线加粗 this.kingRowIndex = 1; // 解决数据 this.rowMergeArrs = this.rowMergeHandle(this.needMergeArr, this.tableData); } }};</script><style lang="scss">.changeElBoCoSt { .el-table__header { // border-right: 1px solid #000; border-top: 1px solid #000; border-left: 1px solid #000; } .el-table__body { // border-right: 1px solid #000; // border-bottom: 1px solid #000; border-left: 1px dashed #000; } .el-table--border td { border-right: 1px dashed #000; } .el-table--border th { border-right: 1px solid #000; } .el-table__body-wrapper .el-table--border.is-scrolling-left ~ .el-table__fixed { border-right: 1px dashed #000; } .el-table--border th { border-bottom: 1px solid #000; } .el-table__fixed-right-patch { border-bottom: 1px dashed #000; } .el-table td { border-bottom: 1px dashed #000; } .el-table th.is-leaf { border-bottom: 1px solid #000; } .el-table__header tr, .el-table__header th { background-color: #ffc000 !important; } // // body的每一行的最初一个单元格 // .el-table__body tr td:last-child { // border-right: 1px solid #000; // } // // body的最初一行 // .el-table__body tr:last-child td { // border-bottom: 1px solid #000; // } // //(刚好最初两行的第一列有合并才要这个) // .el-table__body tr:first-child td:first-child { // border-bottom: 1px solid #000; // } // 双下划线(表体) // .kingRowIndex td { // border-bottom: 2px solid #000000 !important; // } // 表头 // .kingRowIndex1 { // border-right: 2px solid #000000 !important; // }}</style>

August 9, 2021 · 5 min · jiezi

关于element-ui:饿了么UI中的eltable常见的翻页勾选和序号递增功能实现步骤

失常状况下,在一个后盾管理系统中,都会有勾选选中性能,也都会有翻页性能。本文记录一下,比拟常见的翻页勾选性能和翻页序号递增性能的实现形式翻页勾选保留性能第一步和第二步<template> <div id="box"> <!-- 第二步:指定一个key去确认标识这一行的数据,因为若要翻页保留,就须要确认保留的数据是哪一个, 所以咱们就给每一行确定个举世无双的身份标识,这里咱们在el-table标签上 应用row-key去失去每一行的身份标识 --> <el-table :row-key="getRowKey" ref="multipleTable" :data="tableData" tooltip-effect="dark" style="width: 100%" @selection-change="handleSelectionChange" > <!-- 第一步:开启选中翻页保留模式 即::reserve-selection="true" 默认是false。即 默认选中翻页不保留之前勾选的数据 --> <el-table-column type="selection" width="55" :reserve-selection="true" ></el-table-column> <el-table-column prop="name" label="姓名" width="120"> </el-table-column> <el-table-column prop="age" label="年龄" width="120"> </el-table-column> <el-table-column prop="home" label="他乡住址" show-overflow-tooltip> </el-table-column> </el-table> </div></template>第三步methods: { /* 第三步,个别咱们都是用id作为每一行数据的非凡标识,所以这里返回的是row上面的id作为标识。当然 这里不return row上面的id也行,只有可能确保某个字段是举世无双的,不会反复的,就可return return row上面的这个字段也是能够的 */ getRowKey(row) { console.log("看看每一行的数据", row); return row.id; }, }翻页序号递增性能翻页序号递增性能不像翻页勾选保留性能那样还须要每一条数据做标识,而是通过计算得进去的。 第一步<!-- 序号列:index绑定计算方法indexMethod --> <el-table-column :index="indexMethod" label="序号" type="index" width="50" fixed > </el-table-column>第二步methods: { // 序号翻页递增 indexMethod(index) { console.log('索引数下标',index) let nowPage = this.tablePages.pageIndex; //以后第几页,依据组件取值即可 let nowLimit = this.tablePages.pageSize; //以后每页显示几条,依据组件取值即可 return index + 1 + (nowPage - 1) * nowLimit ; // 这里能够了解成一个公式 }, }好忘性不如烂笔头

August 9, 2021 · 1 min · jiezi

关于element-ui:elementui源码

Scriptsbootstrap// 下载我的项目的依赖"bootstrap": "yarn || npm i"build:file"build:file": "node build/bin/iconInit.js & node build/bin/build-entry.js & node build/bin/i18n.js & node build/bin/version.js"1. iconInit.jsclean// 删除lib文件夹和packages目录下的lib文件夹以及test文件夹下的coverage文件夹"clean": "rimraf lib && rimraf packages/*/lib && rimraf test/**/coverage"rimraf次要用删除文件夹 UNIX命令rm -rf用于node。参考文章psotcss文档

July 19, 2021 · 1 min · jiezi

关于element-ui:elementUI中form表单验证upload上传相关问题

实例代码:上传图片是必填项,加ref和prop<el-form-item label="整改前现场照片" ref="beforeImg" prop="imageUrl"> <el-upload ref="upload" action="/webCenter/file/api/uploadAttachment" multiple :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :on-success="fileUploadSuccess" :before-upload="beforeUpload" :data="fileData" :show-file-list=false accept="image/*" > <el-button size="small" type="primary">点击上传</el-button> </el-upload></el-form-item>问题1:在上传图片后还是会呈现提醒音讯 fileUploadSuccess(res) { this.$refs.beforeImg.clearValidate() this.$message.success(res.msg)}解决:在上传胜利后,须要通过this.$refs.beforeImg.clearValidate()独自对表单项勾销验证,这样提醒音讯就会隐没。 问题2:曾经上传图片,但在提交表单时,验证规定还是不通过,显示为false 解决:在提交表单或者在关上表单之前,对上传文件列表是否有值进行判断,若有值,则勾销校验。 import _ from "lodash";if (this.filelist.length) { _.unset(this.rules, ["imageUrl"]);}

July 8, 2021 · 1 min · jiezi

关于element-ui:elementUI如何过滤table组件的中单元格的数据formatter

ElementUI: formatter同学们因为在开发过程中会遇到后盾返回的数据须要前端进行二次转译,比方: // 数据源[{sex: 1, name: "zhangsan"}, {sex: 0, name: "lisi"}]而其中sex就是须要去翻译的状况,比方 1是男,0是女,具体的代码中咱们就能够这样写: // HTML<el-table-column prop="sex" label="性别" :formatter="formatParam"></el-table-column>// methods中formatParam(row, column, cellValue, index) { // row 是以后行的数据 {sex: 1, name: "zhangsan"} // colunm 以后表格单元的属性,罕用的比方 label:性别, property:sex, // cellValue 以后的数据 1 // index 以后所在第几条数据 0 let result = cellValue == 1? "男": "女"; return result;}这样的益处是不必去过滤数据源,间接对以后单元格的数据进行操作,不便了很多。

July 6, 2021 · 1 min · jiezi

关于element-ui:图标快速定位工具-ElementUI-FontAwesome-iView

图标疾速定位工具 ElementUI FontAwesome iView为了不便查找图标,和复制图标名,写了一个小工具。蕴含了 Element-UI FontAwesome iView 三个库的图标, 地址:https://kylebing.cn/tools/icons/ 成果如图

June 20, 2021 · 1 min · jiezi

关于element-ui:elementui使用技巧收集

1. table表格开展行(1)性能需要:点击table某行任意地位,则开展该行二级表格,同时收起其余行开展。(2)实现办法: //template<el-table :data="tableData" @row-click="getRowClick" row-key="no" :expand-row-keys="expands"> <el-table-column prop="no" label="序号" width="65"></el-table-column> <el-table-column prop="recordId" label="入库编号"></el-table-column> <el-table-column type="expand"> //二级表格 <template slot-scope="scope"> <div class="childrenClass"> <el-table :data="scope.row.productDetails"> <el-table-column prop="name" label="产品名称"> </el-table-column> </el-table> </div> </template> </el-table-column></el-table>//scriptexpands: [];//获取须要开展行的no属性,并赋值给开展行办法的数组getRowClick(row: any) { if (this.expands.indexOf(row.no) < 0) { this.expands = []; this.expands.push(row.no); } else { this.expands = []; }}(3)办法介绍:@row-click:当某一行被点击时会触发该事件;row-key:行数据的 Key,用来优化 Table 的渲染,此我的项目应用tableData中的no属性作为key;expand-row-keys:能够通过该属性设置 Table 目前的开展行,须要设置 row-key 属性能力应用,该属性为开展行的 keys 数组。粗体(4)实现成果:

June 9, 2021 · 1 min · jiezi

关于element-ui:ElementUI的elpopover实现同一个popover重复使用多次类似MessageBox

因为el-popover与reference元素是一对一的绑定关系,当一个页面内有多处须要弹出相似的popover框时,如应用现有官网计划,就得每个弹出点都做一个<el-popover>。如果有10个弹出点,就要有10个雷同的el-popover。尽管能实现,但对于强迫症来说,切实有点难承受。 当然这里说的都是带指向箭头、主动定位的popover,而不是那种固定地位的。 冀望是:一个组件内不论有多少中央须要弹出popover,popover组件也只须要有一个,大家都调用同一个就行了。于是钻研了源码,找到一个计划如下: 点击预览成果 <html class="full"><head> <!-- 引入款式 --> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> <!-- 引入组件库 --> <script src="https://unpkg.com/vue@2.6.13/dist/vue.js"></script> <script src="https://unpkg.com/element-ui/lib/index.js"></script></head><style> .full { height: 100%;width:100% }</style><body class="full"> <div id="app"> <el-popover ref="pop1" placement="bottom-start" width="460" v-model="visible"> <div>以后:{{curObj}}</div> </el-popover> <a v-for="(obj,index) in objs" :key="obj" style="cursor:pointer" @click="e=> showPop(e, obj)"> <i class="el-icon-aim aim-icon"></i> Pop{{obj}} </div> </div> <script> new Vue({ el:'#app', data() { return { objs: [1,2,3,4,5], visible: false, curObj: '' } }, methods:{ showPop(e, obj){ this.curObj = obj //要害代码: //先暗藏并销毁之前显示的 this.visible = false this.$refs.pop1.doDestroy(true) this.$nextTick(() => { //显示新的 this.$refs.pop1.referenceElm = e.target this.visible = true }) } } }); </script></body></html>用下来暂没发现什么副作用,如有问题欢送斧正。 ...

June 4, 2021 · 1 min · jiezi

关于element-ui:vueelement-实现tagsView功能

vue+element 实现tagsView性能 胜利后示例 vuex store去存储浏览过的菜单;目录构造//新建tagsView.jsconst tagsView = { state: { visitedViews: [], cachedViews: [] }, mutations: { ADD_VISITED_VIEWS: (state, view) => { if (state.visitedViews.some(v => v.path === view.path)) return state.visitedViews.push(Object.assign({}, view, { title: view.meta.title || 'no-name' })) if (!view.meta.noCache) { state.cachedViews.push(view.name) } }, DEL_VISITED_VIEWS: (state, view) => { for (const [i, v] of state.visitedViews.entries()) { if (v.path === view.path) { state.visitedViews.splice(i, 1) break } } for (const i of state.cachedViews) { if (i === view.name) { const index = state.cachedViews.indexOf(i) state.cachedViews.splice(index, 1) break } } }, DEL_OTHERS_VIEWS: (state, view) => { for (const [i, v] of state.visitedViews.entries()) { if (v.path === view.path) { state.visitedViews = state.visitedViews.slice(i, i + 1) break } } for (const i of state.cachedViews) { if (i === view.name) { const index = state.cachedViews.indexOf(i) state.cachedViews = state.cachedViews.slice(index, i + 1) break } } }, DEL_ALL_VIEWS: (state) => { state.visitedViews = [] state.cachedViews = [] } }, actions: { addVisitedViews({ commit }, view) { commit('ADD_VISITED_VIEWS', view) }, delVisitedViews({ commit, state }, view) { return new Promise((resolve) => { commit('DEL_VISITED_VIEWS', view) resolve([...state.visitedViews]) }) }, delOthersViews({ commit, state }, view) { return new Promise((resolve) => { commit('DEL_OTHERS_VIEWS', view) resolve([...state.visitedViews]) }) }, delAllViews({ commit, state }) { return new Promise((resolve) => { commit('DEL_ALL_VIEWS') resolve([...state.visitedViews]) }) } } } export default tagsView文件夹store中index.js引入方才新建的tagsView.js,并放入modules模块中去import tagsView from './modules/tagsView'//后面state,mutations,getters,actions...省略 modules: { tagsView }新建tagsView文件夹(index.vue,scrollPane.vue)目录构造本人定,我是放在了components里的common文件夹;//index.vue<template> <div class="tags-view-container"> <scroll-pane class="tags-view-wrapper" ref="scrollPane"> <router-link ref="tag" :class="isActive(tag)?'active':''" class="tags-view-item" :to="tag" @contextmenu.prevent.native="openMenu(tag,$event)" v-for="tag in Array.from(visitedViews)" :key="tag.path" > {{tag.title}} <span class="el-icon-close" @click.prevent.stop='closeSelectedTag(tag)'></span> </router-link> </scroll-pane> <ul class='contextmenu' v-show="visible" :style="{left:left+'px',top:top+'px'}"> <li @click="closeSelectedTag(selectedTag)">敞开</li> <li @click="closeOthersTags">敞开其余</li> <li @click="closeAllTags">敞开所有</li> </ul> </div></template> <script>//留神文件门路 import ScrollPane from '@/components/common/TagsView/ScrollPane' export default { name: "tags-view", components: { ScrollPane }, data(){ return{ visible: false, top: 0, left: 0, selectedTag: {} } }, computed:{ visitedViews(){ console.log('tabView') console.log(this.$store.state.tagsView) // console.log(this.$store.state) return this.$store.state.tagsView.visitedViews } }, watch:{ $route(){ this.addViewTags() this.moveToCurrentTag() }, visible(value) { if (value) { document.body.addEventListener('click', this.closeMenu) } else { document.body.removeEventListener('click', this.closeMenu) } } }, mounted() { this.addViewTags() }, methods:{ generateRoute(){ // console.log(this.$route.name) if (this.$route.path) { return this.$route } return false }, isActive(route) { return route.path === this.$route.path }, addViewTags() { const route = this.generateRoute() // console.log(route) if (!route) { return false } this.$store.dispatch('addVisitedViews', route) }, moveToCurrentTag() { const tags = this.$refs.tag this.$nextTick(() => { for (const tag of tags) { if (tag.to.path === this.$route.path) { this.$refs.scrollPane.moveToTarget(tag.$el) break } } }) }, closeSelectedTag(view) { this.$store.dispatch('delVisitedViews', view).then((views) => { if (this.isActive(view)) { const latestView = views.slice(-1)[0] if (latestView) { this.$router.push(latestView) } else { this.$router.push('/') } } }) }, closeOthersTags() { this.$router.push(this.selectedTag) this.$store.dispatch('delOthersViews', this.selectedTag).then(() => { this.moveToCurrentTag() }) }, closeAllTags() { this.$store.dispatch('delAllViews') this.$router.push('/') }, openMenu(tag, e) { this.visible = true this.selectedTag = tag const offsetLeft = this.$el.getBoundingClientRect().left // container margin left this.left = e.clientX - offsetLeft + 15 // 15: margin right this.top = e.clientY }, closeMenu() { this.visible = false } } }</script> <style scoped> .tags-view-wrapper { background: #fff; height: 54px; border-bottom: 1px solid #d8dce5; box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04); } .tags-view-item { display: inline-block; position: relative; height: 30px; line-height: 30px; border: 1px solid #d8dce5; color: #495060; background: #fff; padding: 0 8px; font-size: 12px; margin-left: 5px; margin-top: 4px; } .tags-view-item:first-of-type { margin-left: 15px; } .tags-view-item.active{ background-color: #42b983; color: #fff; border-color: #42b983; } .tags-view-item.active::before{ content: ''; background: #fff; display: inline-block; width: 8px; height: 8px; border-radius: 50%; position: relative; top: -1px; margin-right: 2px; } .contextmenu { margin: 0; background: #fff; z-index: 100; position: absolute; list-style-type: none; padding: 5px 0; border-radius: 4px; font-size: 12px; font-weight: 400; color: #333; box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3); } .contextmenu li{ margin: 0; padding: 7px 16px; cursor: pointer; } .contextmenu li:hover{ background: #eee; } .tags-view-item .el-icon-close{ width: 16px; height: 16px; border-radius: 50%; text-align: center; transition: all .3s cubic-bezier(.645, .045, .355, 1); transform-origin: 100% 50%; } .el-icon-close:before{ transform: scale(.6); display: inline-block; }</style> //ScrollPane.vue<template> <div class="scroll-container" ref="scrollContainer" @wheel.prevent="handleScroll"> <div class="scroll-wrapper" ref="scrollWrapper" :style="{left: left + 'px'}"> <slot></slot> </div> </div></template> <script> const padding = 15 // tag's padding export default { name: 'scrollPane', data() { return { left: 10 } }, methods: { handleScroll(e) { const eventDelta = e.wheelDelta || -e.deltaY * 3//wheelDelta:-120;deltaY:-120 const $container = this.$refs.scrollContainer//里面的container const $containerWidth = $container.offsetWidth//里面的container的宽度 const $wrapper = this.$refs.scrollWrapper//外面 const $wrapperWidth = $wrapper.offsetWidth//外面的宽度 if (eventDelta > 0) { this.left = Math.min(0, this.left + eventDelta)//min() 办法可返回指定的数字中带有最低值的数字。 } else { if ($containerWidth - padding < $wrapperWidth) { if (this.left < -($wrapperWidth - $containerWidth + padding)) { this.left = this.left } else { this.left = Math.max(this.left + eventDelta, $containerWidth - $wrapperWidth - padding) } } else { this.left = 0 } } }, moveToTarget($target) { const $container = this.$refs.scrollContainer const $containerWidth = $container.offsetWidth const $targetLeft = $target.offsetLeft const $targetWidth = $target.offsetWidth if ($targetLeft < -this.left) { // tag in the left this.left = -$targetLeft + padding } else if ($targetLeft + padding > -this.left && $targetLeft + $targetWidth < -this.left + $containerWidth - padding) { // tag in the current view // eslint-disable-line } else { // tag in the right this.left = -($targetLeft - ($containerWidth - $targetWidth) + padding) } } } }</script> <style scoped> .scroll-container { white-space: nowrap; position: relative; overflow: hidden; width: 100%; } .scroll-wrapper { position: absolute; top: 8px; }</style>注意事项: ...

May 31, 2021 · 4 min · jiezi

关于element-ui:使用-ElementUI-image-处理富文本中的图片显示

应用 ElementUI image 解决富文本中的图片显示成果 需要剖析因为富文本有 v-html 加载的,无奈应用 el-image,然而咱们又须要用到 el-image 组件须要预览视频富文本中的视频图片解决办法imageUrl: '',imageUrls: []> el-image 占用<div class="elImage" style="display: none" v-if="imageUrl"> <el-image ref="imageUrl" style="width: 100px; height: 100px;" :src="imageUrl" :preview-src-list="imageUrls"> </el-image></div>bindImagesLayer() { let that = this; that.imageUrls = []; $('.content img').map(function(item) { that.imageUrls.push($(this).attr('src')); }); $('body').on('click', '.content img', function() { let url = $(this).attr('src'); if (!that.imageUrls.includes(url)) { that.imageUrls.push(url); } that.imageUrl = url; setTimeout(() => { $('.elImage img').click(); }, 100); }); } async created() { await this.bindImagesLayer();}.content 为文章内容的 class,获取到其中所有的图片而后再填充到占用的 el-image 中,再手动触发 el-image 的点击事件 ...

May 13, 2021 · 2 min · jiezi

关于element-ui:vueelementui自定义上传文件

vue+elementui自定义上传文件 <el-upload class="upload-demo" action="#" ref="upload" :http-request="httpRequest" :on-preview="handlePreview" :on-remove="handleRemove" :on-change="onChange" multiple :on-exceed="handleExceed" :file-list="fileList" :auto-upload="false" accept=".txt,.csv" > <el-button slot="trigger" size="small" ><IconClass icon-class="iconcloud-upload" />上传文件</el-button > <div slot="tip" class="el-upload__tip"> 反对.txt、 .csv格局 </div> </el-upload>submitUpload() { return new Promise((resolve, reject) => { this.$refs.upload.submit(); const data = new FormData(); this.fileList.forEach(file => { data.append("file", file.raw); //此处肯定是append file.raw 上传文件只需保护fileList file.raw.name要加上 }); //后盾接口 uploadDatasource(data) .then(res => { if (res.code == 200) { resolve(res.data); } else { reject(res.msg); } this.fileList = []; }) .catch(err => { this.fileList = []; console.log(err); }); }); },

May 7, 2021 · 1 min · jiezi

关于element-ui:elementUI-upload组件的妙用

其实说多了也只是泪,依照原本的我失常的逻辑都是这样的:用upload组件,抉择图片的时候就会立即上传到指定的地址,最多也就配置一下header,再大不了就手写限度一下文件的大小。然而我这边的需要是这样的:上传的时候用的是文件流,就是间接把文件流赋值给参数,而后回显的时候后端会返回一个图片的id,我通过拼接地址的形式去显示图片。我第一工夫的情绪的这样的: 然而没方法啊,后端他们不打算改,只能前端苦逼的寻找问题的解决办法。通过屡次的尝试(掉了很多的头发),终于发现了如何去解决这个问题了。上面介绍配角: 上传图片应用文件流模式上面的代码参考: <el-upload class="avatar-uploader" action="#" list-type="picture-card" :file-list="form.codeArray" :limit="1" accept="image/jpg, image/jpeg,image/png" :auto-upload="false" :on-exceed="handleExceed" :on-change="handleChange" :on-remove="handleRemove"> <i class="el-icon-plus"></i> <div slot="tip" class="el-upload__tip"> 倡议上传1:1尺寸图片,防止显示不全 <strong >(只能上传一张图片)</strong> </div></el-upload>复制代码参数不做阐明,详情能够参考这里。将auto-upload设置为false的时候,你会发现你之前应用的钩子很多都没有用,唯独有一个钩子会触发的,能够让你获取到文件的,那就是on-change事件。来看看官网文档的介绍:当咱们增加图片的时候onchange事件会有上面的输入还记的我的需要吗?没错,就是上传的时候把文件流赋值给参数,下面参数中raw就是咱们须要的,咱们只有把这些货色给赋值变量就能够了。 回显应用图片地址回显的时候就绝对简略了,就是间接依照官网的格局放进去数组就完事了 { title: 'aaa', url: 'aaa.jpg' }复制代码移除的时候就绝对应的是用on-remove的事件去移除数组中的元素就能够了。 总结总体的步骤不算难,难点就可能是在发现的过程吧,第一就是这个auto-upload,文档中只是简略的说不会立刻上传,然而阐明理论有什么用处,再就是设置这个属性值为false的时候会触发那些钩子也没有阐明,最初是我一个个钩子的去尝试,查看有什么应用区别。(当然你也能够说博主的理解能力差吧,这个我不会否定的。)

December 14, 2020 · 1 min · jiezi

关于element-ui:ElementUI使用篇eltab的使用样式修改集锦

el-tab是tab切换页面 一、性能篇1.1、手动切换tab应用场景:tab1中点按钮,主动切换到tab2中 实现: searchBtnHandle(){ this.activeName="tab2的name"; //每个tab有个name属性,能够找到这个tab,activename属性绑 定了以后处于激活状态的tab },二、款式篇2.1、批改tab项的款式(包含头与内容) .el-tabs__item { padding: 0 20px; height: 40px; -webkit-box-sizing: border-box; box-sizing: border-box; line-height: 40px; display: inline-block; list-style: none; font-size: 15px; font-weight: 500; color: #303133; position: relative;}2.2 批改tab页面内容.el-tabs__content{ height: calc(100% - 40px); }2.3 批改tab表头.el-tabs--card>.el-tabs__header { border-bottom: 1px solid #E4E7ED; background-color: gainsboro; //批改背景色}2.4 批改激活表头款式 .el-tabs__item.is-active { color: #FFDEAD; //批改激活表头字体色彩,默认是蓝色 }2.5 批改鼠标挪动到表头时候的款式 .el-tabs__item:hover { color: #FFDEAD; //批改鼠标挪动到表头时候字体色彩,默认淡蓝色 cursor: pointer; //鼠标挪动到表头时候鼠标款式,默认小手 }

December 11, 2020 · 1 min · jiezi

关于element-ui:Element-UI-框架中表单数据的验证方式

前言Element UI 框架中的表单验证应用 async-validator(异步校验)第三方库实现,该库在 GitHub的地址是 https://github.com/yiminghe/async-validator,至今在 GitHub 上曾经有了 5.1+的 star,是多 款 前 端 框 架 使 用 的 表 单 验 证 机 制 。 该 库 在 npm 中 的 API 文 档 地 址 为 :http://npm.taobao.org/package/async-validator。 一、Element UI中表单元素的验证规定在 Element UI 框架中,表单是应用el-form标记对和el-form-item标记对实现的。其中表单的验证应用el-form标记对的 rules 属性来进行设置。 在 Element UI 框架中, 对表单数据进行验证须要对el-form标记对和el-form-item标记对进行设置,设置规定如下所示。 el-form标记对的 rules 属性在数据区绑定为一个对象型数据。rules 对象的键名必须与表单元素利用 v-model绑定的变量名统一。rules 对象的键名取值为一个数组,数组元素是表单元素的多个验证规定。el-form-item标记对应用 prop 属性来为表单元素设置须要满足的验证规定。示例代码如下所示: <el-form :model="formData" :rules="rules"> <el-form-item prop="userNick"> <el-input v-model="formData.userNick"> </el-input> </el-form-item></el-form>data:function(){ return { rules:{ userNick:[ {required:true, message:'用户昵称不得为空', trigger:'blur'} ] } }}二、async-validator 的验证规定1、required性能:验证表单元素是否为必填项,取值为逻辑值。2、type性能:验证表单元素输出的数据必须遵循的数据类型。取值: ...

December 8, 2020 · 1 min · jiezi

关于element-ui:elmentUI同一页面展示多个Dialog

要实现的成果如下:首先官网文档是这样形容的:然而我写了个小demo发现并不能间接平级搁置即可,一样会存在先后顺序不同造成的笼罩以及遮罩层导致不能点击被遮蔽的dialog。起因如下:因为dialog先后顺序不同z-index设置的层级不同,所以必定会笼罩遮挡 那么咱们要实现一个这样的成果不仅仅平级搁置即可,就要用到外面的一个属性:modal上面贴上代码: 总的思路就是:dialog先后顺序重叠问题,应用便宜去让它们错开;而后就是遮罩层导致不能点击z-index层级低的弹框,就要用到modal去敞开z-index层级高的遮罩层。(还能够额定应用close-on-click-modal来勾销通过点击 modal 敞开 Dialog)

November 19, 2020 · 1 min · jiezi

关于element-ui:从-ElementUI-源码的构建流程来看前端-UI-库设计

引言因为业务须要,近期团队要搞一套本人的UI组件库,框架方面还是Vue。而业界曾经有比拟成熟的一些UI库了,比方ElementUI、AntDesign、Vant等。 联合框架Vue,咱们抉择在ElementUI根底上进行革新。但造轮子绝非易事,首先须要先去理解它整个但构建流程、目录设计等。 本文通过剖析ElementUI残缺的构建流程,最初给出搭建一个齐备的组件库须要做的一些工作,心愿对于想理解ElementUI源码或者也有搭建UI组件库需要的你,能够提供一些帮忙! 咱们先来看下ElementUI的源码的目录构造。 目录构造解析github:寄存了Element UI奉献指南、issue和PR模板build:寄存了打包相干的配置文件examples:组件相干示例 demopackages:组件源码src:寄存入口文件和一些工具辅助函数test:单元测试相干文件,这也是一个优良的开源我的项目必备的types:类型申明文件说完文件目录,剩下还有几个文件(常见的.babelrc、.eslintc这里就不开展阐明了),在业务代码中是不常见的: .travis.yml:继续集成(CI)的配置文件CHANGELOG:更新日志,这里Element UI提供了四种不同语言的,也是很贴心了components.json:表明了组件的文件门路,不便 webpack 打包时获取组件的文件门路。FAQ.md:ElementUI 开发者对常见问题的解答。LICENSE:开源许可证,Element UI应用的是MIT协定Makefile:Makefile 是一个实用于 C/C++ 的工具,在领有 make 环境的目录下, 如果存在一个 Makefile 文件。 那么输出 make 命令将会执行 Makefile 文件中的某个指标命令。深刻理解构建流程前,咱们先来看下ElementUI 源码的几个比拟次要的文件目录,这对于前面钻研ElementUI的残缺流程是有帮忙的。 package.json通常咱们去看一个大型项目都是从package.json文件开始看起的,这外面蕴含了我的项目的版本、入口、脚本、依赖等要害信息。 我这里拿出了几个关键字段,一一的去剖析、解释他的含意。 main我的项目的入口文件 import Element from 'element-ui' 时候引入的就是main中的文件lib/element-ui.common.js是commonjs标准,而lib/index.js是umd标准,这个我在前面的打包模块会具体阐明。 files指定npm publish发包时须要蕴含的文件/目录。 typingsTypeScript入口文件。 home我的项目的线上地址 unpkg当你把一个包公布到npm上时,它同时应该也能够在unpkg上获取到。也就是说,你的代码既可能在NodeJs环境也可能在浏览器环境执行。为此你须要用umd格局打包,lib/index.js是umd标准,由webpack.conf.js生成。 style申明款式入口文件,这里是lib/theme-chalk/index.css,前面也会具体阐明。 scripts开发、测试、生产构建,打包、部署,测试用例等相干脚本。scripts算是package.json中最重要的局部了,上面我会一一对其中的重要指令进行阐明。 bootstrap"bootstrap": "yarn || npm i"装置依赖, 官网举荐优先选用yarn(吐槽一句:我刚开始没看明确,想着bootstrap不是之前用过的那个 ui 库吗 ????,起初看了下,原来bootstrap翻译过去是疏导程序的意思,这样看看也就大略了解了 ????) build:file该指令次要用来自动化生成一些文件。 "build:file": "node build/bin/iconInit.js & node build/bin/build-entry.js & node build/bin/i18n.js & node build/bin/version.js"这条指令较长,咱们拆开来看: ...

November 13, 2020 · 6 min · jiezi

关于element-ui:ElementUI表格组件合并行或列

介绍 1. 官网文档 合并行或列的办法官网文档为: 参数阐明类型可选值默认值span-method合并行或列的计算方法Function({ row, column, rowIndex, columnIndex })————通过给table传入span-method办法能够实现合并行或列,办法的参数是一个对象,四个参数row、column、rowIndex、columnIndex别离为以后行、当前列、以后行索引和当前列索引。 2. 两种返回形式 数组: [1, 2] // 合并1行,2列对象: { rowspan: 3, // 合并3行 colspan: 1 // 合并1列} 3. 表格渲染程序 从第一行开始,rowIndex为0,列从左到右(columnIndex从0到最初一列);而后第二行,rowIndex为1,列从左到右…… 4. 置空操作 合并单元格时,零碎会取第一个单元格的值。Element在操作单元格时,也是取第一个单元格的值,然而不会将第二个单元格的值置空,这就会导致多出的值没有做解决,因而,咱们须要手动解决,定位到被合并的行或者列,将其值置为空,即返回 [0, 0] 。 Demo分享先展现一下成果demo1 demo2 Demo1(别离合并行或列)<!DOCTYPE html><html><head> <title>ElementUI合并行或列</title> <meta charset="utf-8"> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/element-ui@2.14.0/lib/index.js"></script> <link rel="stylesheet" type="text/css" href="https://unpkg.com/element-ui@2.14.0/lib/theme-chalk/index.css"></head><body> <div id="app"> <template> <div> <p>合并列</p> <el-table :data="tableData" :span-method="arraySpanMethod" border style="width: 100%"> <el-table-column prop="id" label="ID" width="180"></el-table-column> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="amount1" sortable label="数值 1"></el-table-column> <el-table-column prop="amount2" sortable label="数值 2"></el-table-column> <el-table-column prop="amount3" sortable label="数值 3"></el-table-column> </el-table> <p>合并行</p> <el-table :data="tableData" :span-method="objectSpanMethod" border style="width: 100%; margin-top: 20px"> <el-table-column prop="id" label="ID" width="180"></el-table-column> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="amount1" label="数值 1(元)"></el-table-column> <el-table-column prop="amount2" label="数值 2(元)"></el-table-column> <el-table-column prop="amount3" label="数值 3(元)"></el-table-column> </el-table> </div> </template> </div> <script type="text/javascript"> var Main = { data() { return { tableData: [ { id: '12987122', name: '王小虎', amount1: '234', amount2: '3.2', amount3: 10 }, { id: '12987123', name: '王小虎', amount1: '165', amount2: '4.43', amount3: 12 }, { id: '12987124', name: '王小虎', amount1: '324', amount2: '1.9', amount3: 9 }, { id: '12987125', name: '王小虎', amount1: '621', amount2: '2.2', amount3: 17 }, { id: '12987126', name: '王小虎', amount1: '539', amount2: '4.1', amount3: 15 } ] }; }, methods: { arraySpanMethod({ row, column, rowIndex, columnIndex }) { if (rowIndex % 2 === 0) { if (columnIndex === 0) { // 返回行和列的合并数量,返回一个数组或对象 // 返回对象 return { rowspan: 1, colspan: 3 } // 返回数组 // return [1, 3]; // 省略第二和第三列数据,避免合并列的原始数据填充到合并单元格后的表格里 } else if (columnIndex === 1 || columnIndex === 2) { return [0, 0]; } } }, objectSpanMethod({ row, column, rowIndex, columnIndex }) { if (columnIndex === 0) { if (rowIndex % 2 === 0) { return { rowspan: 2, colspan: 1 }; } else { return { rowspan: 0, colspan: 0 }; } } } } }; var Ctor = Vue.extend(Main) new Ctor().$mount('#app') </script></body></html>demo2<!DOCTYPE html><html><head> <title>ElementUI合并行或列</title> <meta charset="utf-8"> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/element-ui@2.14.0/lib/index.js"></script> <link rel="stylesheet" type="text/css" href="https://unpkg.com/element-ui@2.14.0/lib/theme-chalk/index.css"></head><body> <div id="app"> <template> <div> <el-table :data="tableData" :span-method="arraySpanMethod" border style="width: 100%"> <el-table-column prop="date" label="日期" width="150"></el-table-column> <el-table-column label="配送信息"> <el-table-column prop="name" label="姓名" width="120"></el-table-column> <el-table-column label="地址"> <el-table-column prop="province" label="省份"></el-table-column> <el-table-column prop="city" label="市区"></el-table-column> <el-table-column prop="address" label="地址"></el-table-column> <el-table-column prop="zip" label="邮编"></el-table-column> </el-table-column> </el-table-column> </el-table> <div> </template> </div> <script type="text/javascript"> var combineArr = []; var Main = { data() { return { tableData: [{ date: '2016-05-01', name: '王小虎', province: '上海', city: '普陀区0', address: '上海市普陀区金沙江路 1518 弄', zip: 500 }, { date: '2016-05-02', name: '王小虎', province: '上海', city: '普陀区1', address: '上海市普陀区金沙江路 1519 弄', zip: 300 },{ date: '2016-05-02', name: '王小虎', province: '上海', city: '普陀区1', address: '上海市普陀区金沙江路 1520 弄', zip: 200 }, { date: '2016-05-02', name: '王小虎', province: '上海', city: '普陀区1', address: '上海市普陀区金沙江路 1521 弄', zip: 100 }, { date: '2016-05-03', name: '王小虎', province: '上海', city: '普陀区2', address: '上海市普陀区金沙江路 1522 弄', zip: 100 }, { date: '2016-05-04', name: '王小虎', province: '上海', city: '普陀区3', address: '上海市普陀区金沙江路 1523 弄', zip: 100 }, { date: '2016-05-04', name: '王小虎', province: '上海', city: '普陀区3', address: '上海市普陀区金沙江路 1524 弄', zip: 200 }, { date: '2016-05-05', name: '王小虎', province: '上海', city: '普陀区4', address: '上海市普陀区金沙江路 1525 弄', zip: 300 }] }; }, methods: { flitterData(arr) { let spanOneArr = [] let concatOne = 0 arr.forEach(function(item,index) { if (index === 0) { spanOneArr.push(1); } else { if(item.date === arr[index - 1].date) { //第一列需合并雷同内容的判断条件 spanOneArr[concatOne] += 1; spanOneArr.push(0); } else { spanOneArr.push(1); concatOne = index; }; } }); return { one: spanOneArr, } }, arraySpanMethod({ row, column, rowIndex, columnIndex }) { if (rowIndex === 0) { if (columnIndex === 0) { return [1, 6]; } if (columnIndex < 6) { return [0, 0]; } } else { if (columnIndex === 0 ) { const _row = (this.flitterData(this.tableData).one)[rowIndex]; const _col = _row > 0 ? 1 : 0; combineArr = [_row, _col]; return combineArr; } else if (columnIndex === 3 || columnIndex === 5) { return combineArr; } } } } }; var Ctor = Vue.extend(Main) new Ctor().$mount('#app') </script></body></html>

November 12, 2020 · 3 min · jiezi

关于element-ui:element中eldialog踩坑一

element中el-dialog踩坑一1.开发环境 vue+element2.电脑系统 windows10专业版3.在应用 vue+element开发的过程中,咱们可能会应用到el-dialog,上面是我对el-dialog分享,心愿对你有所帮忙!4.在template中增加如下代码: <el-dialog :visible.sync="centerDialogVisible" width="70%" center > </el-dialog>5.在css中增加如下代码: //笼罩默认高度和默认间距.el-dialog { height: 90%; margin-top: 8vh !important;}//批改两头模块的高度.el-dialog__body { height: 94%; padding: 0 !important;}/* 笼罩 el-dialog的默认高度 完结啦 *//* 笼罩 el-dialog 默认的背景色 */.el-dialog,.el-pager li { background-image: url("../assets/images/nybj.png") !important; background-repeat: no-repeat;}//留神 : el-dialog 的父级肯定要有宽和高,不然不失效5.效果图如下:6.本期的成果到了这里就完结啦,是不是很nice,心愿对你有所帮忙,让咱们一起致力走向巅峰!

November 4, 2020 · 1 min · jiezi

关于element-ui:类似elementui的列定义写法的TableBeeGridTable

Home一个基于Vuejs2.x的table表格组件领有丰盛的性能和好用的API 语法糖篇$\color{MediumTurquoise}{1、列定义语法糖}$ <BeeGridTable border height="560" :showSummary="false" fixed="left" :data="data" > <BeeColumn field="code" title="Code"></BeeColumn> <BeeColumn field="name" title="Name" resizable></BeeColumn> <BeeColumn field="sex" title="Sex" type="number"> </BeeColumn> </BeeGridTable> data() { return { // columns: [], data: [], ... }; }, BeeColumn 是一个能够用来定义列信息的组件$\color{MediumTurquoise}{2、列头定义语法糖}$ <BeeGridTable border height="560" :showSummary="false" fixed="left" :data="data" > <BeeColumn field="code" title="Code"></BeeColumn> <BeeColumn field="name" title="Name" resizable></BeeColumn> <BeeColumn field="sex" title="Sex" type="number"> <template slot-scope="{ row }"> <i style="font-size: x-large" class="bee-sys-icon md-man" v-if="row.sex === 0" ></i> <i style="font-size: x-large; color: red" class="bee-sys-icon md-woman" v-else ></i> </template> </BeeColumn> <BeeColumnHeader field="sex"> <template slot-scope="{ column }"> <Button style="color: red">{{ column.title }}</Button> </template> </BeeColumnHeader> </BeeGridTable> data() { return { // columns: [], data: [], ... }; }, BeeColumn 默认slot,传入参数有以后渲染行 row ,能够自定义数据展现,此处的性别渲染成了 icon 图标BeeColumnHeader 能够自定义表头,比方此处的sex字段的表头渲染成了Button按钮$\color{MediumTurquoise}{3、列筛选区定义语法糖}$ ...

October 26, 2020 · 2 min · jiezi

关于element-ui:记录elementui的eltable树形表格多选解决方法

因为业务需要,用element-ui的table做树形构造,并且还须要有多选好了 上代码 次要问题是在抉择的时候须要本人创立一个数组贮存已选 <template> <div class="content"> {{ selectedList }} <hr /> {{ selectedList.length }} <hr /> {{ selectedList.map((ele) => ele.name) }} <div class="is-distribute"> <el-table ref="jojoTable" :data="tableData" border tooltip-effect="dark" :key="1" row-key="key" @select-all="handleAllSelection" @select="(selection, row) => handleSelectionChange(selection, row)" :tree-props="{ children: 'children' }" > <!-- :selectable="(row) => getDisable(row, 'unpub')" --> <el-table-column align="center" type="selection" width="55" ></el-table-column> <el-table-column align="center" prop="version" width="155" label="篇名" ></el-table-column> <el-table-column align="center" prop="name" width="130" label="人物名" ></el-table-column> <el-table-column align="center" prop="skill" width="130" label="技能/替身" ></el-table-column> </el-table> </div> </div></template><script>export default { name: "TaskManage", data() { return { selectedList: [], tableData: [ { version: "幻影之血", isChild: false, isSel: false, key: 1, children: [ { version: "幻影之血", name: "齐贝林", skill: "欧巴多啦A梦", key: 2, isChild: true, isSel: false, }, { version: "幻影之血", name: "乔纳森·乔斯达", skill: "欧巴多啦A梦", key: 3, isChild: true, isSel: false, }, { version: "幻影之血", name: "屌·布兰度", skill: "jojo 我不做人啦", key: 4, isChild: true, isSel: false, }, ], }, { version: "战斗潮流", isChild: false, isSel: false, key: 5, children: [ { version: "战斗潮流", name: "西撒", skill: "泡沫阵", key: 6, isChild: true, isSel: false, }, { version: "战斗潮流", name: "乔瑟夫·乔斯达", skill: "欧巴哆啦A梦", key: 7, isChild: true, isSel: false, }, { version: "战斗潮流", name: "丽莎丽莎", skill: "围巾", key: 8, isChild: true, isSel: false, }, { version: "战斗潮流", name: "瓦乌姆", skill: "浑楔飒", key: 9, isChild: true, isSel: false, }, ], }, { version: "星辰斗士", isChild: false, isSel: false, key: 10, children: [ { version: "星辰斗士", name: "空调·承太郎", skill: "欧拉欧拉拳", key: 11, isChild: true, isSel: false, }, { version: "星辰斗士", name: "卡Q因", skill: "绿宝石水花", key: 12, isChild: true, isSel: false, }, { version: "星辰斗士", name: "二乔", skill: "你给路达哟", key: 13, isChild: true, isSel: false, }, { version: "星辰斗士", name: "阿布嘟嘟", skill: "红色魔术师", key: 14, isChild: true, isSel: false, }, { version: "星辰斗士", name: "波鲁那雷夫", skill: "银色战车", key: 15, isChild: true, isSel: false, }, { version: "星辰斗士", name: "伊奇", skill: "愚者", key: 16, isChild: true, isSel: false, }, ], }, ], }; }, methods: { handleAllSelection(a, b, c) { console.log(a, b, c); }, handleSelectionChange(val, row) { let selectedList = this.selectedList, tableData = this.tableData; // 如果点击的子节点 if (row.isChild) { if (row.isSel) { // selectedList.findIndex(ele => ele.key === row.key) selectedList.remove(row); } else { selectedList.push(row); } // 判断多少条是被选中的 let cLength = selectedList.filter((ele) => ele.key == row.key).length; // 查找以后子节点的父节点 let pNode = tableData.find((ele) => ele.version == row.version); console.log(pNode); // 如果长度雷同那就打钩,不同则勾销 this.$refs.jojoTable.toggleRowSelection( pNode, cLength === pNode.children.length ); pNode.isSel = cLength === pNode.children.length; } else { // 点击父节点 // 数据操作 如果是已被勾选那么删除此列所有数据 if (row.isSel) { let delList = selectedList.filter((ele) => ele.key === row.key); for (const item of delList) { item.isSel = false; selectedList.remove(item); } // console.log("remove"); } else { // console.log("push"); // 否则是新增 for (const item of row.children) { if (selectedList.indexOf(item) == -1) { item.isSel = true; selectedList.push(item); } } } row.children.forEach((ele2) => { this.$refs.jojoTable.toggleRowSelection(ele2, !row.isSel); }); } row.isSel = !row.isSel; }, },};</script><style lang='scss' >.has-gutter .el-table-column--selection div { display: none;}</style>

October 23, 2020 · 3 min · jiezi

关于element-ui:vclickoutside的源码分析及改进

1.前言最近遇到一个需要,公司须要做一个相似facebook的搜寻抉择组件,我打算用el-input和el-cascader-panel联合设计。在设计过程中参考了el-cascader的源码,其中的v-clickoutside自定义指令蛮值得钻研的,所以写篇文章记录下。 2.根底知识点(1)v-directivevue文档曾经写的很分明了,这里只贴网址:vue中文文档-自定义指令 (2)v-clickoutside先放element-ui中的源码 //element-ui/src/utils/clickoutside.jsimport Vue from 'vue';import { on } from 'element-ui/src/utils/dom';const nodeList = [];const ctx = '@@clickoutsideContext';let startClick;let seed = 0;!Vue.prototype.$isServer && on(document, 'mousedown', e => (startClick = e));!Vue.prototype.$isServer && on(document, 'mouseup', e => { nodeList.forEach(node => node[ctx].documentHandler(e, startClick));});function createDocumentHandler(el, binding, vnode) { return function(mouseup = {}, mousedown = {}) { if (!vnode || !vnode.context || !mouseup.target || !mousedown.target || el.contains(mouseup.target) || el.contains(mousedown.target) || el === mouseup.target || (vnode.context.popperElm && (vnode.context.popperElm.contains(mouseup.target) || vnode.context.popperElm.contains(mousedown.target)))) return; if (binding.expression && el[ctx].methodName && vnode.context[el[ctx].methodName]) { vnode.context[el[ctx].methodName](); } else { el[ctx].bindingFn && el[ctx].bindingFn(); } };}/** * v-clickoutside * @desc 点击元素里面才会触发的事件 * @example * ```vue * <div v-element-clickoutside="handleClose"> * ``` */export default { bind(el, binding, vnode) { nodeList.push(el); const id = seed++; el[ctx] = { id, documentHandler: createDocumentHandler(el, binding, vnode), methodName: binding.expression, bindingFn: binding.value }; }, update(el, binding, vnode) { el[ctx].documentHandler = createDocumentHandler(el, binding, vnode); el[ctx].methodName = binding.expression; el[ctx].bindingFn = binding.value; }, unbind(el) { let len = nodeList.length; for (let i = 0; i < len; i++) { if (nodeList[i][ctx].id === el[ctx].id) { nodeList.splice(i, 1); break; } } delete el[ctx]; }};//element-ui/src/utils/domexport const on = (function() { if (!isServer && document.addEventListener) { return function(element, event, handler) { if (element && event && handler) { element.addEventListener(event, handler, false); } }; } else { return function(element, event, handler) { if (element && event && handler) { element.attachEvent('on' + event, handler); } }; }})();v-clickoutside用于解决指标节点外的点击事件,最次要的是下拉框等开展内容的敞开。 ...

October 2, 2020 · 2 min · jiezi

关于element-ui:自定义elementui中的图标

前提elementui图标库图标较少当你想用elementui的控件而不想用它的图标时,就能够应用自定义的形式来实现 实现el-icon-my-export为我自定义的图标命名 <el-button class="default" icon="el-icon-my-export">导出</el-button>//应用图片来替换//before属性中的content文本是用来占位的,必须有//能够设置字体大小来确定大小//应用visibility: hidden;来暗藏文字.el-icon-my-export{ background: url(/officeHouse/resources/images/export.png) center no-repeat; background-size: cover;}.el-icon-my-export:before{ content: "替"; font-size: 16px; visibility: hidden;}//如果间接应用字体图片//间接在before属性设置对应的content就行.el-icon-my-export{ font-size: 16px;}.el-icon-my-export:before{ content: "e611";}content外面应用汉字大小会比拟失常,然而汉字有时候会呈现乱码,能够应用Unicode编码 //编码后的的替为 u66ff//书写到css外面的时候须要去掉u.el-icon-my-export:before{ content: "66ff"; font-size: 16px; visibility: hidden;}

September 30, 2020 · 1 min · jiezi

关于element-ui:elementui之eltable的二次封装带条件查询及翻页功能

在很多前端的后管我的项目中会存在很多表格,表格数据过多就须要分页和按条件筛选搜寻查问,于是就对el-table进行了二次封装。 页面构造如图: PS:以前做的组件了,大家能够酌情参考,也可依据理论状况进行批改扩大。 1、首先创立一个 searchForm.vue 文件,搁置筛选查问条件和按钮。 <template> <el-form :label-width="labelWidth" label-position="right" size="small" class="search-form"> <el-container> <el-row ref="target" type="flex" class="search-form_row"> <slot></slot> <div class="el-form-item el-form-item--small"> <div class="el-form-item__content"> <el-button type="primary" size="small" @click="$emit('query')">查 询</el-button> <el-button size="small" v-if="$slots.default" @click="$emit('reset')">重 置</el-button> </div> </div> </el-row> </el-container> </el-form></template><script> export default { name: 'SearchForm', props: { labelWidth: { type: String, default: '70px' }, } }</script>2、创立 searchTable.vue 文件 <template> <el-container class="search-table"> <el-header class="search-table__header" v-if="$slots.row"> <search-form ref="form" :label-width="labelWidth" @query="$emit('query')" @reset="$emit('reset')"> <template> <slot name="row"></slot><!-- 搜寻条件 & 按钮 --> </template> </search-form> </el-header> <el-main class="search-table__body"> <el-row ref="actions" v-if="$slots.actions" class="search-table__action"> <el-col :span="24"> <slot name="actions"></slot><!-- 操作按钮 --> </el-col> </el-row> <el-table ref="tableRef" :height="tableHeight" :data="tableData" :empty-text="emptyText" stripe border highlight-current-row :row-class-name="rowClassName" tooltip-effect="light" :header-cell-style="{ fontWeight: 'bold' }" size="mini" :row-key="rowKeys" v-loading="tableLoading" :default-sort="defaultSort" @sort-change="handleSortChange" @selection-change=" selection => { this.$emit('selectionChange', selection) }" @select-all=" selection => { this.$emit('selectAll', selection) }" > <slot></slot> </el-table> </el-main> <el-footer class="search-table__footer" height="42px" v-if="$slots.footer"> <slot name="footer"></slot> </el-footer> </el-container></template><script>import SearchForm from './searchForm'export default { name: 'SearchTable', components: { SearchForm }, props: { labelWidth: { type: String, default: '70px' }, tableData: { type: Array, default: () => [] }, emptyText: { type: String, default: '' }, rowClassName: { type: Function }, rowKeys: { type: Function }, tableLoading: Boolean, defaultSort: { type: Object, default: () => {} }, }, data() { return { tableHeight: '200px' //table表格高度 } }, methods: { // 表格排序 handleSortChange(event) { const { prop, order } = event this.$emit('sortChange', { prop, order: order ? String.prototype.replace.call(order, 'ending', '') : null }) } }}</script>3、在组件中应用 ...

September 27, 2020 · 2 min · jiezi

关于element-ui:带有全部选项的elselect组件

el-select-all形容:带有全副选项的el-select组件应用:装置依赖包npm i el-select-allmain.js里引入import ElSelectAll from 'el-select-all'Vue.use(ElSelectAll)组件用例<ElSelectAll v-model="storeCodes" filterable multiple collapse-tags @change="onChange" :options="mdoptionsList" />预览地址:https://fred-hu.github.io/el-select-allnpm包地址:el-select-all示例:

September 18, 2020 · 1 min · jiezi

关于element-ui:elementUI小功能合集

前言本文章次要更新elementUI应用过程中一些小需要的实现,遇到问题就会更新,欢送大家探讨交换一、elementui中el-table-column里显示两个后盾字段需要:<el-table-column></el-table-column>要展现的数据来自后盾返回的两个字段代码如下:<el-table-column prop="specs,quantityUnit" label="规格">      <template slot-scope="scope">             {{scope.row.specs}}/{{scope.row.quantityUnit}}        </template> </el-table-column>二、vue+elementui设置表格分页需要:elementUI的表格可能分页,联合el-pagination应用步骤: 1.拿到后端传回的数据数组 2.在data内定义页数、每页多少条数据这两个变量 3.在el-table的data属性中通过slice函数宰割数据 4.依据官网的分页办法实现切换数据的成果代码如下: //在data中注册应用的数据data:function(){ return { total:0,//默认数据总数(也可由数据数组长度) pagesize:7,//每页的数据条数 currentPage:1,//默认开始页面 } }//将数据绑定到el-table上<el-table :data="searchInfo.slice((currentPage-1)*pagesize,currentPage*pagesize)">三、vue+element实现动静表格:依据后盾返回的属性名和字段动静生成可变表格需要:

September 4, 2020 · 1 min · jiezi

关于element-ui:vuecli30elementui-按需引入的自定义主题问题

按需引入胜利之后,我想要自定义主题 百度最举荐的办法是去线上主题生成,而后下载引入应用。然而我这里始终说下载包有问题我就放弃,看了很多文章找到了一篇写得不错的,并且解决了问题的办法,这里本人记录一下。1、首先装置依赖npm install babel-plugin-component -D装置当前要记得把sass-loader和node-sass装置一下,不然会报错npm install node-sass sass-loader --save-dev2、新建element-variables.scss文件3、在main.ts中引入。留神放在elementui引入的前面 import './plugins/element.js'import '@a/styles/element-variables.scss'4、依据须要编辑element-variables.scss文件,这里打个比方 /*主题色彩变量*/$--color-primary: #f0f;/*icon字体门路变量*/$--font-path: '~element-ui/lib/theme-chalk/fonts';/*按需引入用到的组件的scss文件和根底scss文件*/@import '~element-ui/packages/theme-chalk/src/base.scss';@import '~element-ui/packages/theme-chalk/src/rate.scss';@import '~element-ui/packages/theme-chalk/src/button.scss';@import '~element-ui/packages/theme-chalk/src/row.scss';本文原链接在这

August 12, 2020 · 1 min · jiezi

关于element-ui:elementui-使用

el-selectel-select 的v-model个别绑定的是boolean / string / number,如果想绑定对象 则须要指定其惟一value-key value-key:作为 value 惟一标识的键名,绑定值为对象类型时必填<el-select v-model="user" value-key="id" @change="get" placeholder="请抉择"> <el-option v-for="user in users" :key="user.id" :label="user.name" :value="user"></el-option> </el-select>

July 27, 2020 · 1 min · jiezi

关于element-ui:封装elementui表格我是这样做的

日日加班至夜半,环视四周无人走;明晚八点准时走,谁不打卡谁是狗。 应用过element-ui的表格的同学应该都有这样的领会,做一个简略的表格还比拟容易,但如果这个表格蕴含了顶部的按钮,还有分页,甚至再蕴含了行编辑,那开发工作量就成倍的减少,特地是在开发管理系统的时候,表格一个接一个的去开发, 即浪费时间,还对集体没有什么晋升。明天小编带来了本人封装的一个表格,让你用JSON就能够简略的生成表格。 本文次要集中于应用阐明与外围代码阐明,残缺代码请拜访 https://github.com/snowzijun/vue-element-table,如果感觉有用,麻烦给小编一个star,你的每一个star都是对小编的反对,以后性能比拟简陋,本仓库将继续更新。同时您也能够微信搜寻【前端有的玩】公众号,与小编进行沟通。表格需要个别管理系统对表格会有以下需要 能够分页(须要有分页条)能够多选(表格带复选框)顶部须要加一些操作按钮(新增,删除等等)表格每行行尾有操作按钮表格行能够编辑如下图为一个示例表格 如果咱们间接应用element-ui提供的组件的话,那么开发一个这样的表格就须要应用到以下内容 须要应用表格的插槽性能,开发每一行的按钮须要通过款式调整顶部按钮,表格,分页条的布局款式须要监听分页的事件而后去刷新表格数据顶部按钮或操作按钮如果须要获取表格数据,须要调用表格提供的api对于有行编辑的需要,还须要通过插槽去渲染行编辑的内容,同时要管制行编辑的开关不仅仅开发表格比拟麻烦,而且还要思考团队合作,如果每个人实现表格的形式存在差异,那么可能前期的保护老本也会变得很高。那怎么办呢? 表格配置为了满足团队疾速开发的须要,小编对下面提出来的需要进行了封装,而后应用的时候,开发人员只须要配置一些JSON便能够实现以上性能的开发。 根底配置一个根底的表格蕴含了数据和列信息,那么如何用封装的表格去配置呢? <template> <zj-table :columns="columns" :data="data" :pagination="false" /></template><script>export default { data() { return { // 表格的列信息, 数组每一项代表一个字段,能够应用element 列属性的所有属性,以下仅为示例 columns: Object.freeze([ { // 表头显示的文字 label: '姓名', // 对应数据外面的字段 prop: 'name' }, { label: '性别', prop: 'sex', // 格式化表格,与element-ui 的表格属性雷同 formatter(row, column, cellValue) { return cellValue === 1 ? '男' : '女' } }, { label: '年龄', prop: 'age' } ]), data: [ { name: '子君', sex: 1, age: 18 } ] } }}</script>通过下面的配置,就能够实现一个根底表格的开发,残缺代码见 https://github.com/snowzijun/vue-element-table/blob/master/example/views/demo/base.vue,成果如下图所示 ...

July 27, 2020 · 5 min · jiezi

element中vpopover使用的小例子

应用自定义指令v-popover指向 Popover 的索引ref的例子: ` <el-form-item label="链接:" prop="dbUrl"> <el-input v-model="dataSourceDetail.dbUrl" v-popover:popover1 placeholder="请输出链接" > </el-input> <el-popover ref="popover1" placement="bottom" width="450" trigger="hover" :content="dbUrlTip" > </el-popover> </el-form-item> <el-form-item label="驱动类名:" v-popover:popover2 prop="driverClass"> <el-input v-model="dataSourceDetail.driverClass" placeholder="请输出驱动类名" > </el-input> <el-popover ref="popover2" placement="bottom" width="450" trigger="hover" :content="driverClassTip" > </el-popover>`

July 15, 2020 · 1 min · jiezi

element的eltable中记录滚动条位置

场景重现:在项目中使用了keep-alive来缓存组件,且使用element中的table列表,但在项目中是对table进行了二次封装,跟页码合在了一起。按照网上的直接对scrollTop赋值,赋值失败了,还要加上setTimeout才能成功,虽然实现了功能,但是不知道原因,可以的话希望有人能解答。 废话少说,直接赋上代码。 <template> <div class="table"> <el-table ref="table"> ... </el-table> <wp-pager @page-change="pageChange" :total="total" v-if="pager" v-bind="$attrs" v-on="$listeners"></wp-pager> </div></template><script> import { WpPager } from '../pager' export default { data() { return { scrollTop: null } }, activated() { this.saveScroll() }, mounted() { // 监听滚动条的位置 this.$refs.table.bodyWrapper.addEventListener('scroll', (res) => { let height = res.target this.scrollTop = height.scrollTop },false) }, beforeDestroy() { this.$refs.table.bodyWrapper.removeEventListener('scroll', (res) => { let height = res.target this.scrollTop = height.scrollTop },false) }, methods: { // 当页码改变的时候滚动条重新到顶部 pageChange (page) { this.$emit('page-change', page) this.scrollTop = 0 this.saveScroll() },// 这里如果直接赋值给this.$el.querySelector('.el-table__body-wrapper').scrollTop会失效,需要加上setTimeout才行。 saveScroll() { this.$nextTick(()=> { setTimeout(() => { var scrollTop = this.$el.querySelector('.el-table__body-wrapper') scrollTop.scrollTop = this.scrollTop }, 13) }) } } }</script>

November 5, 2019 · 1 min · jiezi

element-ui-eltimepicker赋值HHss后界面不显示

问题: el-time-picker筛选出某个时间点保存,之后从后台获取该时间,页面显示 `<el-time-picker class="my_time_picker_32" :clearable="false" v-model="scope.row.plan[index]" placeholder="时间" format="HH:mm"></el-time-picker>` 解决: 字符串转date const _converTime = ac.plan.map((item: any) => { const _arr: string[] = item.split(':'); return new Date(2010, 10, 10, Number(_arr[0]), Number(_arr[1]));});附:选中的时间点过滤出时分` private dateConversion(value: any): string { const d = new Date(value);let _h = d.getHours() + '';if (_h.length === 1) { _h = '0' + _h;}let _m = d.getMinutes() + '';if (_m.length === 1) { _m = '0' + _m;}return _h + ':' + _m;}` ...

November 5, 2019 · 1 min · jiezi