第四期:前端九條bug分享

本期

最近工做以及我的的事情都比較忙而且抽時間在學java,致使拖到如今才攢夠9條合格的‘bug’, 最近一直在用服務端渲染nuxt.js還有echarts, 因此會有多處涉及這方面技術, 此次最後會分享兩個最近感悟出的觀點還挺有意思的。html

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照樣被排序, 而帶漢字的放到最後vue

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

我把0換個位置java

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

bug現象3:node

那我加上漢語

使用下面的代碼順序就不會有問題啦,nginx

let obj = {
       '1漢字':"數字1",
       '3漢字':"數字3",
       '2漢字':"數字2"
     };

bug理解:
數組也是對象, 那麼對象對這種數組的形式是有一些特殊操做的,這個坑點必定要後端同窗明白, 否則後期出現奇怪的bug還要轉換數據形式就太苦惱了。git

2:echarts的圖表如何顯示「無數據」, 描述了一個思惟過程。

事情是這樣的
我要畫一張折線圖, 但這個折線圖有兩個狀態顯示, 無數據的時候顯示「暫無數據」, 有數據的時候正常顯示數據,因此有了以下的代碼。編程

其中list就是折線圖數據的數組, 就是這個樣子的[{},{},{}];

你能夠分析一下下面的代碼bugelement-ui

<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元素, 這樣固然會報錯啦,因此有了下面這段代碼。json

使用一個變量來控制是否顯示暫無數據
<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:
看起來好像沒有大問題, 可是測試提出了一個詭異的問題, 在數據從有數據到無數據不斷切換的時候, 「暫無數據」與圖表居然一塊兒顯示了出來,如圖所示。
image

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序列化, 會不會是序列化的時候致使了變異?
想到了就趕快試一試

image

不難看出原本是18:41:19, 可是轉換完畢變成了10:41:19, 前面的小時數出現了變化。
但調用toString方法就不會使其變化
這麼好玩的事情必定要追查下去啊, 這個10究竟是什麼, 他的轉換規則究竟是什麼, 當時沒有這方面的只是儲備, 那麼就把date對象身上的屬性一個一個的試我就不行找不到

果真被找到了,如圖
image

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:

但願文章可以對你有收穫! 本次的分享就是這樣,歡迎交流, 祝天天進步

相關文章
相關標籤/搜索