乐趣区

关于javascript:第四期前端九条bug分享

本期

最近工作以及集体的事件都比较忙并且抽时间在学 java,导致拖到当初才攒够 9 条合格的‘bug’,最近始终在用服务端渲染 nuxt.js 还有 echarts,所以会有多处波及这方面技术,这次最初会分享两个最近感悟出的观点还挺有意思的。

1: 为什么列表的数据不要让后端同学返回对象,而应该返回数组?

返回对象咱们前端间接遍历有没问题啊,能够失常显示,那是因为你没有遇到上面形容的状况
bug 景象 1:

我明明把 3 这个 key 定义在了第二个地位,然而每次打印进去他都跑到了第三个地位,那么我是不是循环出的列表就有问题了
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Document</title>
</head>
<body>
 <script>
    let obj = {
      '1':"数字 1",
      '3':"数字 3",
      '2':"数字 2"
    };

   // 这三个都阵亡啦
    console.log(Object.keys(obj)) //  ["1", "2", "3"]
    console.log(Object.values(obj)) // ["数字 1", "数字 2", "数字 3"]
    console.log(Object.entries(obj)) 
    /*
    (3) [Array(2), Array(2), Array(2)]
       0: (2) ["1", "数字 1"]
       1: (2) ["2", "数字 2"]
       2: (2) ["3", "数字 3"]
    */

    // 老办法也有这个问题
    for(let item in obj){console.log(item) // 1 2 3
    }

    console.log(JSON.stringify(obj)) // {"1":"数字 1","2":"数字 2","3":"数字 3"}

    console.log(obj) // {1: "数字 1", 2: "数字 2", 3: "数字 3"}
 </script>
</body>
</html>

bug 景象 2:
123 照样被排序,而带汉字的放到最初

     let obj = {
       '1':"数字 1",
       '3':"数字 3",
       '2':"数字 2",
       '0 汉字':'数字 0'
     };
     console.log(Object.keys(obj)) //  ["1", "2", "3", "0 汉字"]

我把 0 换个地位

     let obj = {
       '0 汉字':'数字 0','1':"数字 1",
       '3':"数字 3",
       '2':"数字 2",
     };
     console.log(Object.keys(obj)) //  ["1", "2", "3", "0 汉字"]

bug 景象 3:

那我加上汉语

应用上面的代码程序就不会有问题啦,

 let obj = {
       '1 汉字':"数字 1",
       '3 汉字':"数字 3",
       '2 汉字':"数字 2"
     };

bug 了解:
数组也是对象,那么对象对这种数组的模式是有一些非凡操作的,这个坑点肯定要后端同学明确,不然前期呈现奇怪的 bug 还要转换数据模式就太苦恼了。

2:echarts 的图表如何显示“无数据”, 形容了一个思维过程。

事件是这样的
我要画一张折线图,但这个折线图有两个状态显示,无数据的时候显示“暂无数据”,有数据的时候失常显示数据,所以有了如下的代码。

其中 list 就是折线图数据的数组,就是这个样子的[{},{},{}];

你能够剖析一下上面的代码 bug

<template>
  <div v-if="list.length === 0" class="nodata"> 暂无数据 </div>
  <div v-else ref="main" class="line"></div>
</template>
...
 mounted() {this.initLine(); // 初始化折线图
 }
 initLine() {this.myChart = echarts.init(this.$refs.main);
      //...
}

bug 景象 1:
很显著第一次 this.initLine(); 会报错,因为 list 的初始值必定是空数组导致没有 ref 等于 main 的 dom 元素,这样当然会报错啦,所以有了上面这段代码。

应用一个变量来管制是否显示暂无数据
<template>
  <div v-if="showNodata" class="nodata"> 暂无数据 </div>
  <div v-else ref="main" class="line"></div>
</template>
data(){
  return {showNodata:false}
}
...
 mounted() {this.initLine(); // 初始化折线图
 }
 initLine() {
     //... 比方申请拿到返回值
     this.list = res.list;
     this.showNodata = res.list.length === 0; // 这里要谨严一点的话,要解决申请出错的状况,提前把 this.showNodata 赋值为 false,这里我就只是举例子啦。}

bug 景象 2:
看起来如同没有大问题,然而测试提出了一个诡异的问题,在数据从有数据到无数据一直切换的时候,“暂无数据”与图表居然一起显示了进去,如图所示。

bug 景象 3:
明明是 v-if 管制的 dom 元素,怎么会同时呈现两个。。。
这类问题第一反馈必定是元素的复用问题啦,加个 key 就有了如下的代码

<template>
  <div v-if="showNodata" key="1" class="nodata"> 暂无数据 </div>
  <div v-else ref="main" key="2" class="line"></div>
</template>

问题真的就解决了,然而明明俩个 class 不同,一个有 ref 一个没有,那么这个元素为啥还要反复啊?
bug 景象 4:
带着疑难去掉了 class,同时去掉 key,居然也能够打消 bug

<template>
  <div v-if="showNodata"> 暂无数据 </div>
  <div v-else ref="main"></div>
</template>

bug 总结:
如果都有 class 的话,就会复用上面的 dom,把这个 dom 的 class 换成nodata,然而这个 dom 被 echarts 解决过所以就导致折线图还在,所以如果想防止这个 bug 那就须要其中一个 dom 不加 class 或者乖乖加个 key 啦。

3:commit 了不想提交的内容,然而又 commit 其余的数据

bug 景象:
周末加班不小心把一个 .zip 文件 commit 了下来,push 时报的错误信息是内容过大,那好办我间接删除了这个文件再 push,还是包这个谬误,那我批改 .gitignore 文件,push 依然报这个谬误这就很恼火啦。
bug 追究:
通过 git log 查出每个 commit 的 hash 号码,而后 git show 打进去看看具体的 commit 信息,确实就是因为这个.zip 文件出的问题,那么我当初就是须要勾销那一次 commit,然而那次提交之后我又进行了屡次提交,这可怎么办。
bug 解决:
git reset 出错 commit 的前一个 hash,运行 git status 你就会发现曾经把.zip 文件‘吐出来了’,当然这种回退并不会把咱们的文件删除,或者是把文件批改的内容回退,所以大家能够放心使用,要记住的是对于曾经 commit 的文件,配置 .gitignore 文件是有效的。

4: 为什么每次工夫都会变动

bug 景象:
一个风和日丽的黄昏 … 我写了一个毫无花哨表单, 然而诡异的事件正在缓缓到来,背景是咱们那个我的项目应用了 nuxt.js, ui 选用了 Ant Design Vue, 这个表单外面应用了一个工夫控件,就是那种能够选小时与分钟的,不堪设想的是每次我提交的数据‘工夫这一项都是谬误’,比方我选的下午 2 点,然而提交的是上午 3 点,就是工夫永远提交的是错的。。。
bug 追究:

  1. 后盾要求工夫格局是‘23:03’这种字符串的格局
  2. 过后我没有用插件解决,而是间接把工夫串 slice 截断了一下,取出小时局部
  3. 为了不影响原数据,每次提交的时候我都会const form = JSON.parse(JSON.stringify(this.form))

由下面的内容分析了一下,我忽然想到 Date 对象不反对 json 序列化,会不会是序列化的时候导致了变异?
想到了就赶快试一试

不难看出原本是 18:41:19,然而转换结束变成了 10:41:19,后面的小时数呈现了变动。
但调用 toString 办法就不会使其变动
这么好玩的事件肯定要追究上来啊,这个 10 到底是什么,他的转换规则到底是什么,过后没有这方面的只是储备,那么就把 date 对象身上的属性一个一个的试我就不行找不到

果然被找到了,如图

d.getUTCHours() 是什么?

getUTCHours() 办法可依据世界时 (UTC) 返回工夫的小时。也就是说他是世界工夫,而不是北京工夫的小时
对世界工夫有趣味的能够看看这篇文章写的挺分明的 https://www.cnblogs.com/you-jia/p/4465690.html

为啥只有小时不同,分钟和秒都一样

哈哈哈这个其实很好解释,就是联合国规定每个时区之间的差别只能以小时为维度,所以才有了这个 bug 的状况,真是无用的常识又减少了感觉本人棒棒的。
如果当前大家遇到了这种 bug 能够大胆的吹它一顿 nb 啦。

5:Failed to execute ‘appendChild’ on ‘Node’: This node type does not support this method

前因后果:
在应用 nuxt.js 框架编写我的项目的时候,遇到了一些理论的问题。

  1. 部署老本的减少,服务端可能要装置 pm2,node,yarn。
  2. 每次更新代码太慢了,尤其切实联调阶段,每次更新代码要花费我 5 分钟左右(你能够设想遇到一个只在线上才会呈现的 bug 我有多心累)。
  3. 莫名其妙的谬误减少了学习老本,并且这些谬误可能对咱们没啥进步。
  4. 每次编译速度极慢极慢,并且编译后有谬误(在这里热更新就是个笑话),开发了一个月我甚至都曾经习惯用鼠标点浏览器的刷新按钮,甚至甚至!!!!刷新一遍可能还是谬误的我要手动刷新第二遍才会正确(桌子都掀了,再摆回去)。
  5. 报错很夸大,可能我一个代码谬误它报 500…. 我一个取值谬误它就白屏。
  6. 本身代理须要在每个环境外面批改,比方测试环境服务启在 3000,开发环境启在 8080,上线又要变。

吐槽还有很多很多,然而我就不吐苦水了,大家想分明如果真的真的须要服务端渲染再抉择应用它,咱们我的项目一个后盾管理系统应用它收益真的有点小。

bug 景象:
在咱们不堪其扰的时候,团队终于决定应用动态包来部署,"generate":"nuxt generate",也就是这句神奇的命令,他会生成多个 html 文件来达到区别于 spa 技术的目标,而咱们部署起来不便多了,然而开发还是很很不难受,就在这个时候呈现了这个问题,我在开发服务器上启动的服务跑的没问题,然而在测试服务下面的 generate 动态包呈现了题目上的谬误,难道这个谬误与打包形式还无关???

bug 解决:
解决办法说来也简略,我应用了一个 <iframe> 标签,这在他生成时候就乱了套了哎,所以我要用 <no-ssr></no-ssr> 标签 dom 构造包裹起来,让他不要走服务端渲染程序,这样就能够防止这个问题啦,归根结底还是这个技术自身有问题。

6: 在 nuxt 的动态打包时,前端 path 被占用

bug 景象:
做好的我的项目放在新的测试服务器上,其中动静大屏的页面拜访包 nginx 报 403,这时候测试与后端同学就来找我了,质问我做了什么导致 nginx 出了问题 …. 我给他们的是动态包基本没有操作服务器的代码,那么问题曾经就处在服务器环境或者后端同学代码身上啦,尽管不是前端的工作,但正好是个学习的机会就来帮他们查一查吧。
在我的项目内用 $router.push 的形式跳过去没问题,点击刷新页面就会 404.

bug 追究:
nginx 报错那么肯定出在门路上,查看 nginx 配置文件外面是如何代理这个门路的,内部间接拜访这个门路查找走到了那个代理,最初果然发现了这个门路被一个空的资源占据啦。

bug 解决:

  1. 加上门路前缀也就是 publicPath
  2. 前端给这个页面改名

最初为了最快工夫解决,并且也是后端同学切实忙不过来了只能斗争这个版本应用第二种形式。

7:echarts 的几个不常见的问题列举

知识点列举:

  1. 让折线图重叠与不重叠
    在应用折线图的时候,有时候会波及到多折线,这个时候就可能须要这 n 条折线各自之间互补干预,也可能让给他们成为重叠的状态,如图所示:

    通过设置每条线的 stack 属性雷同达到重叠成果,反之亦然

 series: [
 {
            name: '紧急',
            type: 'line',
            smooth: true,
            stack: '紧急', // 不一样就不重叠了
            data: [1,2,3],
          },
          {
            name: '高危',
            type: 'line',
            smooth: true,
            stack: '高危',
             data: [5,6,7],
          },
          {
            name: '中危',
            type: 'line',
            smooth: true,
            stack: '中危',
              data: [8,9,10],
          },
  ]
  1. 使横线变成虚线
    这个要求好诡异我找了半天才找到,不分享进去都感觉对不起本人,对比方图:

    代码如下
yAxis: {
          type: 'value',
          axisLabel: {
            color: 'white',
            fontSize: 14,
          },
          splitLine: { // 这个就是精华
            show: true,
            lineStyle: {
              color: '#d8d8d8',
              type: 'dotted',
            },
          },
        },
  1. 让地图能够依据评分变成相应的色彩

这个也是我找了半天,官网外面说的都是 inRange 属性,然而这个属性没法让咱们去设置范畴,起初我找到了 dataRange 这个属性如图:

如下的形式去应用就好啦
 dataRange: {
            right: "2%",
            bottom: "3%",
            icon: "circle",
            align: "left",
            splitList: [{
                    start: 0,
                    end: 0,
                    label: '提醒',
                    color: "#6ead51"
                },
                {
                    start: 0,
                    end: 250,
                    label: '高温',
                    color: "#92b733"
                },
                {
                    start: 250,
                    end: 500,
                    label: '中温',
                    color: "#c4aa29"
                },
                {
                    start: 500,
                    end: 750,
                    label: '低温',
                    color: "#ce6c2b"
                },
                {
                    start: 750,
                    label: '超高温',
                    color: "#c92626"
                }
            ]
        },
  1. 举荐论坛地址 echarts 论坛

8: 写一个官网的注意事项

bug 景象 1:

所有要害的 key 与词语必须让用户搜寻的到:

ui 组件库的官网每个实例上面,根本都有一个折叠代码的性能,然而当我想要 ctrl+f 搜寻的局部就在这个被遮挡住的代码块中的时候怎么办??那就很不不便找到了,所以说折叠代码的同时不要让这里的 dom 构造隐没会更难受,毕竟 ui 的官网应该以不便查问为主,而不是官网页面的性能。
这方面 element-ui 做的很棒。

bug 景象 2:

过于简短的介绍甚至无介绍:

很多官网对于一些用法都是一句话了事,举例子也就举其中的一段代码,导致咱们要付出更多的学习工夫能力把他钻研懂,官网你都做了为什么不能附上残缺的代码?与具体的介绍。
可能写这个的团队都是大神,怕写多了没有身份。
更有甚者,vue 的一个插件他在介绍外面引入了个 mixin 也不说 mixin 外面是啥代码。。。。

bug 景象 3:

不怕重点词的反复

其实某个知识点你尽管说过,然而有些时候如果解释的话术不是很多的话,我还是倡议间接在应用的地位的旁边附上解释,不要为了找一个 13 个字就能说分明的货色还要点三层连贯去到你们的英文文档外面自行查阅,我抵赖你写的很标准很秀,然而不太好用。

9: 面向人类编程(这里只是集体的观点)

代码不然而写给咱们本人的,也是写个所有人的
  1. 把本人写的代码当一个产品输入。
  2. 把共事当客户。
  3. 不要为了看着所谓的正规而丢失代码的可读性,有时候代码丑一些然而更实用。
适度封装

代码自身就是给人看给机器运行的,而咱们何不把写出的代码当成一个产品去设计,让用户用着难受用着爽。
我看过太多代码做到了所谓的“高标准”,比方把申请全副集中起来,当我发现一个 http 申请出错的时候我要搜寻这个 http 地址,而后再全局搜这个 http 地址对应的办法名,这样的两步走收益真的大么?这只是一个小例子吧。

本人明确就行?

做开发必定会遇到一起奇奇怪怪的需要与 bug,当咱们梳理好了逻辑或是解决了怪异的问题 可否间接在相干代码的旁边残缺的写上逻辑关系以及为什么这里写的比拟奇怪,干嘛每次他人梳理到这里还要来问你一次为啥这么写。

用着不爽硬保持?

某些技术可能是你总监提出来的或者 cto 亲推,然而理论应用起来就是不爽,那么咱们作为开发者也能够提出来,毕竟写代码是件开心的事。

当然工夫紧工作重的话酌情

毕竟大家都会有非常非常忙的时候,此时不用过分谋求这些,都了解的哈哈哈。

end:

心愿文章可能对你有播种! 本次的分享就是这样,欢送交换, 祝每天提高

退出移动版