element table表格 - dialog弹窗 - 日期选择器的一些使用bug及解决方案

171 阅读4分钟

登录页面,密码在请求携带参数中加密

注意:使用什么加密方法 要配合后端去使用,因为加密会后的数据要后端去解构

步骤:

下载 加密的依赖包

npm i jsencrypt

在当前页面引入

1663997790368

获取公钥,再把密码放到对应的函数中即可

1663997813148

加密效果演示


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>测试登录</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        html {
            height: 100%;
        }
        body {
            height: 100%;
        }
        .container {
            height: 100%;
            background-image: linear-gradient(to right, #fbc2eb, #a6c1ee);
        }
        .login-wrapper {
            background-color: #fff;
            width: 358px;
            height: 588px;
            border-radius: 15px;
            padding: 0 50px;
            position: relative;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
        }
        .header {
            font-size: 38px;
            font-weight: bold;
            text-align: center;
            line-height: 200px;
        }
        .input-item {
            display: block;
            width: 100%;
            margin-bottom: 20px;
            border: 0;
            padding: 10px;
            border-bottom: 1px solid rgb(128, 125, 125);
            font-size: 15px;
            outline: none;
        }
        .input-item:placeholder {
            text-transform: uppercase;
        }
        .btn {
            text-align: center;
            padding: 10px;
            width: 100%;
            margin-top: 40px;
            background-image: linear-gradient(to right, #a6c1ee, #fbc2eb);
            color: #fff;
        }
        .msg {
            text-align: center;
            line-height: 88px;
        }
        a {
            text-decoration-line: none;
            color: #abc1ee;
        }
    </style>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/jsencrypt/3.2.1/jsencrypt.min.js"></script>
</head>
<body>
    <div class="container">
        <div class="login-wrapper">
            <div class="header">Login</div>
            <div class="form-wrapper">
                <input type="text" name="username" placeholder="username" class="input-item">
                <input type="password" name="password" placeholder="password" class="input-item">
                <button class="btn" onclick="login1()">登录</button>
            </div>
            <div class="msg">
                Don't have account?
                <a href="#">Sign up</a>
            </div>
        </div>
    </div>
	<script>
		function login1()
		{
			var password_input=document.getElementsByName("password").item(0);
			var password=password_input.value;
			
			var publickey ="-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxQMhy5xEETuAqgk/058RRcNgQp28CaVg3Oyi1PAloBerTwPuI5uYcj3CxG+ZPdaaXICuu+rwpbBZbiEuQhqTyzEolaoa76C33hG9IM9+ChBTU1twaMY/Qq7xkjI9Ej4DM8VSXyPlj6rA4aWH74pXPOEworsctSM/pzRoFqupvE0i4XYWdCpl4rUGTFiJ2uCt5JPwNd8hbSbHmvfeg2JFEmq2FjLHtPSoPyBvOfZ/Ssq5zFA2pL6kgh569Z73rqapvOql8HUxXHsKb/WB0n1S1rGTUzZykteVA7IFbH1TZTHAWhzLd0sbwwYxk/5ZHdYR9w5EsdwSR1woM5Amv/QJNwIDAQAB-----END PUBLIC KEY-----";
			var crypt = new JSEncrypt();
			crypt.setKey(publickey);
			var enc = crypt.encrypt(password);
			window.alert(enc);
		}
	</script>
</body>
</html>

后端设置更新 tokan 接口 - 前端主动去更新

步骤:

  • 登录成功后记录当时 时间戳 存在本地中
  • 在 axios 请求拦截器中 声明一个你想多久开始更新 tokan 的时间,如: 60*1000(1分钟)
  • 在用户每次发起请求的时候获取当前时间戳,再获取之前存储在本地的时间戳,两者减去大于我们设置的1分钟,那么就发起请求更新 token
    • 更新token请求在 vuex 中异步执行,更新完之后也有记录本次的时间戳
  • 还要判断当前记录时间戳是否为一致,避免上次更新token的请求还没回来,又一次发起更新token请求

axios 中的代码

1663998602838

vuex 中的代码

1663998619487

table表格 导出 Excel 表格

代码演示


<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>测试AAA</title>
		<script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.mini.min.js"></script>
	</head>
	<body>
		<button onclick="btn_export()">导出Excel</button>
		<table border="1" id="table1">
		  <tr>
		    <th>班级</th>
		    <th>学号</th>
			<th>姓名</th>
		  </tr>
		  <tr>
		    <th rowspan="2">一班</th>
		    <td>20090101</td>
			<td>张三</td>
		  </tr>
		  <tr>
		    <td>20090102</td>
		  	<td>李四</td>
		  </tr>
		  <tr>
		    <td>二班</td>
		    <td>20090201</td>
		  	<td>王五</td>
		  </tr>
		</table>
		<script>
		        function btn_export() {
		            var table1 = document.getElementById("table1");
		            var sheet = XLSX.utils.table_to_sheet(table1);//将一个table对象转换成一个sheet对象
		            openDownloadDialog(sheet2blob(sheet),'下载.xlsx');
		        }
		
		        // 将一个sheet转成最终的excel文件的blob对象,然后利用URL.createObjectURL下载
		        function sheet2blob(sheet, sheetName) {
		            sheetName = sheetName || 'sheet1';
		            var workbook = {
		                SheetNames: [sheetName],
		                Sheets: {}
		            };
		            workbook.Sheets[sheetName] = sheet; // 生成excel的配置项
		
		            var wopts = {
		                bookType: 'xlsx', // 要生成的文件类型
		                bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
		                type: 'binary'
		            };
		            var wbout = XLSX.write(workbook, wopts);
		            var blob = new Blob([s2ab(wbout)], {
		                type: "application/octet-stream"
		            }); // 字符串转ArrayBuffer
		            function s2ab(s) {
		                var buf = new ArrayBuffer(s.length);
		                var view = new Uint8Array(buf);
		                for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
		                return buf;
		            }
		            return blob;
		        }
		
		        function openDownloadDialog(url, saveName) {
		            if (typeof url == 'object' && url instanceof Blob) {
		                url = URL.createObjectURL(url); // 创建blob地址
		            }
		            var aLink = document.createElement('a');
		            aLink.href = url;
		            aLink.download = saveName || ''; // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
		            var event;
		            if (window.MouseEvent) event = new MouseEvent('click');
		            else {
		                event = document.createEvent('MouseEvents');
		                event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
		            }
		            aLink.dispatchEvent(event);
		        }
		    </script>

	</body>
</html>

原生table-饿了吗 table-多页导出 Excel

要先下载依赖

import * as XLSX from "xlsx";

import FileSaver from "file-saver";

绑定对应的ID即可

//导出方法
diet(){
原生 table 表格导出方法
      var workbook = XLSX.utils.book_new();

      let ws1;
      ws1 = XLSX.utils.table_to_sheet(
        document.querySelector("#tableJz"),
        xlsxParam
      );

      // 这里可以添加多个sheet页
      XLSX.utils.book_append_sheet(workbook, ws1, "街镇");
      let ws2 = XLSX.utils.table_to_sheet(
        document.querySelector("#tableJncs"),
        xlsxParam
      );
      XLSX.utils.book_append_sheet(workbook, ws2, "局内处室");
      let ws3 = XLSX.utils.table_to_sheet(
        document.querySelector("#tableZrzt"),
        xlsxParam
      );
      XLSX.utils.book_append_sheet(workbook, ws3, "责任主体");

      let wbout = XLSX.write(workbook, {
        bookType: "xlsx",
        bookSST: true,
        type: "array",
      });
      try {
        FileSaver.saveAs(
          new Blob([wbout], {
            type: 'application/octet-stream;charset=utf-8"',
          }),
          "表格.xlsx"
        );
      } catch (e) {
        if (typeof console !== "undefined") console.log(e, wbout);
      }
      return wbout;

-------------------------------------------------------------------------------
element UI table组件 导出多个表格 
      //方式一:XLSX.utils.table_to_sheet接受一个表格 DOM 元素并返回一个类似于输入表格的工作表
      //1.创建空工作簿
      var workbook = XLSX.utils.book_new();
      let tableDom1 = document.getElementById("tableJz").cloneNode(true);
      let tableDom2 = document.getElementById("tableJncs").cloneNode(true);
      let tableDom3 = document.getElementById("tableZrzt").cloneNode(true);
      //当element ui表格使用fixed属性时,会多出一个表格,导致导出的表格内容重复,删掉就可以了
      tableDom1.removeChild(tableDom1.querySelector(".el-table__fixed"));
      tableDom2.removeChild(tableDom2.querySelector(".el-table__fixed"));
      tableDom3.removeChild(tableDom3.querySelector(".el-table__fixed"));
      //  将 DOM TABLE 元素转换为工作表
      let ws1 = XLSX.utils.table_to_sheet(tableDom1);
      let ws2 = XLSX.utils.table_to_sheet(tableDom2);
      let ws3 = XLSX.utils.table_to_sheet(tableDom3);
      //3.将工作表附加到工作薄
      XLSX.utils.book_append_sheet(workbook, ws1, "街镇");
      XLSX.utils.book_append_sheet(workbook, ws2, "局内处室");
      XLSX.utils.book_append_sheet(workbook, ws3, "责任主体");

      let wbout = XLSX.write(workbook, {
        bookType: "xlsx",
        bookSST: true,
        type: "array",
      });
      try {
        FileSaver.saveAs(
          new Blob([wbout], {
            type: 'application/octet-stream;charset=utf-8"',
          }),
          "表格.xlsx"
        );
      } catch (e) {
        if (typeof console !== "undefined") console.log(e, wbout);
      }
      return wbout;
----------------------------------------------------------------------------------
element UI table组件 导出单个表格 
      let ws1;
      //  .table要导出的是哪一个表格
      let table1 = document.querySelector("#tableJz").cloneNode(true);
      // 因为element-ui的表格的fixed属性导致多出一个table,会下载重复内容,这里删除掉
      table1.removeChild(table1.querySelector(".el-table__fixed"));
      ws1 = XLSX.utils.table_to_book(table1, { raw: true }); //mytable为表格的id名
      /* get binary string as output */
      var wbout = XLSX.write(ws1, {
        bookType: "xlsx",
        bookSST: true,
        type: "array",
      });
      try {
        FileSaver.saveAs(
          new Blob([wbout], { type: "application/octet-stream" }),
          "表格.xlsx"
        );
      } catch (e) {
        if (typeof console !== "undefined") console.log(e, wbout);
      }
      return wbout;
}

解决路由跳转的时候两次push的path地址相同 报错

//解决路由跳转的时候两次push的path地址相同 报错
const originalPush = VueRouter.prototype.push
//修改原型对象中的push方法
VueRouter.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err)
}

leaflet.js地图库,别人使用通过瓦片

1665817296227

图层选项-->选择要展示的图层

1665817319289


element 日期组件-bug

当选择日期后,点击取消,会有一个报错,解决方案

1665817478157

在日期组件的回调事件中判断他的value值,为 null 就赋值当前时间戳

1665817548758


父子组件-element-dialog 弹窗--bug

解决方案一:(很麻烦,不推荐)

父组件使用了 .sync 传值给子组件,子组件 dialog弹窗 点击右向角取消,会报错。可以在子组件声明变量等于父组件传过来的值,子组件绑定这个变量,watch 监听父组件传过来的值,没发生变化,子组件的变量就等于这个值

1665817695512

解决方案二:(好用)

使用 组件中的 before-close 回调事件处理即可,在事件处理函数中通过子传父来完成

this.$emit('update:父组件传过来的值',false)

1665817877725


element table表格-传递数据到 dialog弹窗 进行数据回显 --> bug

  • 子组件声明方法,在方法的处理函数中,对父组件传递的数据进行处理,以及赋值到子组件的变量中进行双向绑定数据回显

  • 父组件给子组件绑定 ref 通过 this.$refs 获取子组件的方法,进行传递数据

根据传递的数据进行回显,直接使用变量等于传递过来的值,会是浅拷贝,子组件dialog弹窗点击取消,表格中会缓存上一次的数据,虽然能调接口重新渲染,但是还是会一闪而过上一次数据,体验不好。

在子组件的方法中,可以执行深拷贝,这样两个变量的指向地址就会不一样,当子组件dialog弹窗点击取消,表格的数据就不会受到影响

1665819277780