问题场景1 | 青训营笔记

112 阅读8分钟

1. el-table分页数据+回显+勾选状态+记录数据(map实战)

原以为js中即便是学到了map可实际上也不会用到map,可我今天就遇到一个el-table分页查询,然后需要勾选表格内容,切换页码后回显勾选项的需求。

一开始想的是,把所有已勾选的数据用list来维护,可稍微一思索就发现这样实际执行起来还是有缺陷的,比如用于来回切换页码等场景稍微一复杂就容易乱套。

还是应该记录每一条数据的信息,用户点击勾选的时候,用当前的勾选情况去跟已勾选的数据做一个比对。如果已记录的数据里存在当前列表中的勾选项,同时本次属于勾选状态,则不做处理。

如果处于未勾选状态,则从用于记录的总数据中删除该选项。如果总得记录结果没有改数据,同时该数据本次是勾选状态,则把新数据添加进去。

用map是最好的了,于是就实战一下,试试手~

<el-button @click="query"> 获取新数据</el-button>
<el-table
  ref="myTable"
  :data="tableData"
  style="width: 100%"
  @selection-change="handleSelectionChange"
>
  <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-column type="selection" width="55"> </el-table-column>
</el-table>

选择selection-change ,它会把当前页码的勾选项列出来。 接下来就是它对应的handle函数了,我把处理逻辑用备注的形式写出来

const selectedMap = new Map();
handleSelectionChange(val) {
// val 表示当前勾选项,属于array类型
// 我们首选需要一个list用来记录当前tableData都有哪些备选哪些没有被选上,我这里先用一个map记录当前表格中的备选项
// 然后遍历tableData 把已选项维护到一个list中
  const currSelectMap = new Map();
  for (let i = 0; i < val.length; i++) {
    currSelectMap.set(val[i].name, true);
  }

  const selectList = [];
  this.tableData.forEach((item) => {
    const name = item.name;
    selectList.push({
      name,
      selected: currSelectMap.has(name) ? true : false,
    });
  });
// 遍历selectList,它记录了当前表格中每一项的一个唯一ID(我这里是name是唯一的),以及是否选中两个参数
// 遍历过程中与记录总的被选中的数据做一个比较,代码由本文前面的处理逻辑形成
  selectList.forEach((item) => {
    const name = item.name;
    const selected = item.selected;
    if (selectedMap.has(name) && !selected) {
      selectedMap.delete(name);
    }
    if (!selectedMap.has(name) && item.selected) {
      selectedMap.set(name, item);
    }
  });
  console.log("selectedMap", selectedMap);
},

最后的最后,el-table切换页码时候还需要额外处理一下

getRowKey(row) {
    return row.name;
},
    query() {
        // 查询
        this.tableData = [
            {
                date: "2016-05-02",
                name: "王小虎4",
                address: "上海市普陀区金沙江路 1518 弄",
            },
            {
                date: "2016-05-04",
                name: "王小虎5",
                address: "上海市普陀区金沙江路 1517 弄",
            },
            {
                date: "2016-05-01",
                name: "王小虎6",
                address: "上海市普陀区金沙江路 1519 弄",
            },
            {
                date: "2016-05-03",
                name: "王小虎7",
                address: "上海市普陀区金沙江路 1516 弄",
            },
        ];

        for (let i = 0; i < this.tableData.length; i++) {
            //如果有的话,添加进去,把参数设置为true
            const name = this.tableData[i].name;
            if (selectedMap.has(name)) {
                this.$nextTick(() => {
                    this.$refs.myTable.toggleRowSelection(this.tableData[i], true);
                });
            }
        }
    },

就是切换到新数据时,我们要打勾,但是通过代码打钩的过程会触发handleSelectionChange函数这样就导致,可能就跟我们期待的差很多了,具体差到哪里,读者朋友可以把 this.$nextTick(DOM 更新结束后执行其指定的回调)去掉试试。

2. 修改ElementUI默认样式最直接有效的方法

做项目的过程在难免会遇到要修改ElementUI的默认样式

解决方法:

方式一:全局修改 写一个单独的CSS文件,里面直接用element自带得类名进行样式修改(部分需要添加 !important)。这种方法会将整个项目用到的该组件样式全部修改了。一般用来放公共样式,如表格、弹框、表单会用到。

修改el-dialog

效果

修改el-message-box

效果

css文件单独在main.js中引入就可以了

import "./style/reset.css";

方式二:组件内修改 单独在要修改的组件内再写一对标签,不要加scoped。 然后在里面直接修改样式就行,为了防止可能影响到其他组件的样式,建议加一层父盒子的类名。例如:我想修改类名为login-form的盒子内的 input 样式

<div class="login-form">
    <el-form ref="form" :model="form">
        <el-form-item>
            <el-input
                      placeholder="身份证号码"
                      prefix-icon="el-icon-user"
                      v-model.trim="form.name"
                      ></el-input>
        </el-form-item>
        <el-form-item>
            <el-input
                      placeholder="请输入密码"
                      prefix-icon="el-icon-lock"
                      v-model.trim="form.password"
                      autocomplete="off"
                      type="password"
                      @keypress.native.13="login"
                      />
        </el-form-item>
        <el-form-item>
            <div :underline="false" style="float: right;cursor: pointer;">
                忘记密码?
            </div>
        </el-form-item>
        <el-form-item>
            <div class="clickLogin" @click="login">登录</div>
        </el-form-item>
    </el-form>
</div>
.login-form {
    .el-input__inner {
        color: #999;
    }
}

如果不生效,也请加上 !important

/deep/跟>>>快被淘汰了,不建议使用

3. flex布局 三个div 两个左对齐 一个右对齐

一、问题

有一个盒子flex布局,子元素有 三个div,在不改变dom结构的情况下,实现 前两个左对齐 第三个右对齐。

二、实现方案

在flex布局中如果某个元素的margin为auto那么它的margin将会自动填充为 剩下的空间

三、代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>flex布局</title>
    <style>
        *{
            margin: 0;   
            padding: 0;
        }
        .box {
	        display: flex;
	        justify-content: flex-start;
	    }
	
	    .block {
	        width: 100px;
	        height: 100px;
	        border:1px solid black;
	        
	    }
    </style>
</head>
<body>
<div class="box">
    <div class="block">块1</div>
    <div class="block">块2</div>
     // 此地margin-left:auto;自动填充了剩余空间
    <div class="block" style="margin-left: auto;">块3</div> 
    <div class="block">块4</div>
</div>
</body>
</html>

效果如下:

在这里插入图片描述

4. echart 柱状图y轴要显示成百分比

image-20220715201852513

<template>
    <div id="main" style="width: 600px; height: 400px"></div>
</template>
<script>
import * as echarts from 'echarts'
export default {
  data() {
    return {
        option: {
        xAxis: { //x轴设置
          type: 'category',
          boundaryGap: false,
          data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
        },
        yAxis: { //y轴设置
          type: 'value',
          axisLabel: { //y轴设置为%
            show: true,
            interval: 'auto',
            formatter: '{value} %',
          },
          max: 100,  //最大值
          min: 0,  //最小值
        },
        series: [
          {
            data: [100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            type: 'line',
            areaStyle: {},
          },
        ],
      },
   }
 },
  mounted() {
    let myChart = echarts.init(document.getElementById('main'))
    // 指定图表的配置项和数据
    let option = this.option
    // 使用刚指定的配置项和数据显示图表。
    myChart.setOption(option)
  },
}

5. ECharts在柱状图的柱子上方显示数量的方法

<template>
  <v-chart :options="getOptions()" />
</template>

<script>
export default {
  methods: {
    getOptions() {
      return {
        title: {
          text: '企业诊断区域分布'
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          },
        },
        legend: {
          right: '0'
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: [
          {
            type: 'category',
            data: ['婺城区', '金东区', '武义县', '浦江县', '磐安县', '兰溪市', '义务市', '东阳时', '永康市'],
            axisTick: {
              alignWithLabel: true
            }
          }
        ],
        yAxis: [
          {
            type: 'value',
          }
        ],
        series: [
          {
            name: '诊断数',
            type: 'bar',
            barWidth: '30%',
            data: [1361, 4036, 1776, 1225, 2565, 1231, 1523, 1189, 1956],
            itemStyle: {   // 上方显示数值
              normal: {
                label: { 
                  show: true,  // 开启显示
                  position: 'top', // 在上方显示
                  textStyle: { // 数值样式
                    color: '#999',
                    fontSize: 12
                  }
                }
              }
            }
          },
          {
            name: '改造数',
            type: 'bar',
            barWidth: '30%',
            data: [582, 1918, 1015, 669, 1124, 640, 710, 612, 791],
            itemStyle: {  // 上方显示数值
              normal: {
                label: {
                  show: true, // 开启显示
                  position: 'top', // 在上方显示
                  textStyle: { //数值样式
                    color: '#999',
                    fontSize: 12
                  }
                }
              }
            }
          }
        ]
      }
    },
  },
};
</script>

<style>
</style>

6. 滚动条样式修改

前言

浏览器中的滚动条样式大家一定都不陌生,其样式并不好康。可能很多小伙伴还不知道,这个东东的样式也可以修改(仅支持部分现代浏览器),本次就来带大家用 CSS 修改一下它的样式。

一、认识滚动条

首先我们先来简单看一下滚动条是由哪几部分组成的:

滚动条的组成.png

当横向和纵向都有滚动条时,还会有一个交汇的部分(见下图),但是因为一般网页开发中都不会让横向出现滚动条(因为影响美观),所以这个小方块出现的频率不算太高。下图为同时有垂直滚动条和水平滚动条时交汇的部分:

当同时有垂直滚动条和水平滚动条时交汇的部分.png

二、解决方案

CSS伪类

目前我们可以通过 CSS伪类 来实现滚动条的样式修改,以下为修改滚动条样式用到的CSS伪类:

  • ::-webkit-scrollbar — 整个滚动条
  • ::-webkit-scrollbar-button — 滚动条上的按钮 (上下箭头)
  • ::-webkit-scrollbar-thumb — 滚动条上的滚动滑块
  • ::-webkit-scrollbar-track — 滚动条轨道
  • ::-webkit-scrollbar-track-piece — 滚动条没有滑块的轨道部分
  • ::-webkit-scrollbar-corner — 当同时有垂直滚动条和水平滚动条时交汇的部分
  • ::-webkit-resizer — 某些元素的corner部分的部分样式(例:textarea的可拖动按钮)

此处附上MDN文档传送门:developer.mozilla.org/zh-CN/docs/…

兼容性问题

当然这种解决方案还存在一定的兼容性问题,仅仅在支持WebKit的浏览器 (例如, 谷歌Chrome, 苹果Safari)可以使用。其实一看到 -webkit- 前缀就能明白它是 CSS3 中的 私有属性前缀 ,特定前缀是为了适配特定浏览器内核的。我们前往Can I use对其兼容性一探究竟: “::-webkit-scrollbar”属性兼容性.png

由上图我们可以看到,兼容性并不算太好,不过我们也不用过于在意,毕竟我们只是规则的使用者而非制定者。

三、进行测试

1. 整个滚动条

我们一条属性一条属性来进行测试,首先使用 ::-webkit-scrollbar 。先改变一下它的宽度,测试一下效果:

/* 整个滚动条 */
/* 宽高分别对应纵向滚动条和横向滚动条的宽度 */
::-webkit-scrollbar {
    width: 50px;
}

滚动条样式修改测试-1.gif

我们可以看到,滚动条似乎“消失”了,但是仍然能靠鼠标拖动来滚动页面。我们再给它加一个背景色康康效果:

/* 整个滚动条 */
::-webkit-scrollbar {
    width: 50px;
    background-color: skyblue;
}

滚动条样式修改测试-2.png

增加背景颜色后,滚动条又“出现”了。结合刚才的代码我们不难看出:设置 ::-webkit-scrollbar 属性会使滚动条默认样式失效。既然如此,我们就必须结合其他属性一起使用。

2. 滚动条上的箭头按钮

我们来使用一下 ::-webkit-scrollbar-button 属性,发现当此属性单独使用时无任何效果:

/* 滚动条上的箭头按钮 */
::-webkit-scrollbar-button {
    background-color: slateblue;
}

滚动条样式修改测试-3.png

于是乎我们加上之前的代码再试试:

滚动条样式修改测试-4.png

我们可以看出,两个箭头的按钮位置的背景颜色发生了变化。看来,滚动条的其他伪类属性需要配合第一步中的 ::-webkit-scrollbar 才能生效。

3. 滚动条上的滚动滑块

我们用 ::-webkit-scrollbar-thumb 来改变滚动条中滑块的样式:

/* 整个滚动条 */
::-webkit-scrollbar {
    width: 50px;
    background-color: skyblue;
}

/* 滚动条上的滚动滑块 */
::-webkit-scrollbar-thumb {
    background-color: orange;
}

滚动条样式修改测试-5.gif

4. 滚动条轨道

::-webkit-scrollbar-track 属性修改滚动条轨道样式:

/* 整个滚动条 */
::-webkit-scrollbar {
    width: 50px;
    background-color: skyblue;
}

/* 滚动条上的滚动滑块 */
::-webkit-scrollbar-thumb {
    background-color: orange;
}

/* 滚动条轨道 */
::-webkit-scrollbar-track {
    background-color: hotpink;
}

滚动条样式修改测试-6.png

通过效果图我们可以发现,设置的滚动条轨道背景色遮住了设置的整个滚动条的背景色(天蓝)。那是否可以实现两种背景色里外嵌套的效果呢,目前做出了几种尝试都没有效果,只能暂时放弃,以下为经测试未实现嵌套背景色效果代码:

/* 未实现背景色嵌套效果代码 */
::-webkit-scrollbar {
    /* 无法通过 padding 实现 */
    padding: 4px;
    width: 50px;
    background-color: skyblue;
    box-sizing: border-box;
}

::-webkit-scrollbar-track {
    /* 无法通过调整宽度实现 */
    width: 80%;
    background-color: hotpink;
}

既然如此,我们如果需要调整滚动条的背景颜色,只需要在 ::-webkit-scrollbar::-webkit-scrollbar-track 中任选其一即可。

5. 滚动条没有滑块的轨道部分

这次我们同时设置 ::-webkit-scrollbar-track::-webkit-scrollbar-track-piece 来看效果:

/* 整个滚动条 */
::-webkit-scrollbar {
    width: 50px;
}

/* 滚动条上的滚动滑块 */
::-webkit-scrollbar-thumb {
    background-color: orange;
}

/* 滚动条轨道 */
::-webkit-scrollbar-track {
    background-color: hotpink;
}

/* 滚动条没有滑块的轨道部分 */
::-webkit-scrollbar-track-piece {
    background-color: purple;
}

滚动条样式修改测试-7.png

上述代码符合预期效果,但是我给滑块设置透明的背景色(transparent)则会全是 purple 颜色,也不会出现滑块底部呈现 pink 颜色。所以,如果要改背景色还是选择轨道来修改吧。

6. 测试总结

  1. 设置 ::-webkit-scrollbar 属性会使滚动条默认样式失效
  2. 其他修改滚动条样式的私有属性需要配合 ::-webkit-scrollbar 属性使用
  3. 如果要设置滚动条背景色, ::-webkit-scrollbar 、 ::-webkit-scrollbar-track 、 ::-webkit-scrollbar-track-piece 三个属性设置一个即可。