此次9個並不都是bug, 其中有幾個小優化, 雖然一個月的時間遇到不少bug, 但並非每一個都有參考價值, 讓咱們看看此次我遇到的有趣問題吧.css
bug現象:
一個平凡的清晨, 放下書包喝了口白開水, 習慣性的git pull了一下, 這個不速之客就出如今了命令行裏面, 腦殼中居然第一反應是但願這個bug有趣一點, 這樣就能夠寫文章了, 這個bug是忽然出現的自己確定與個人操做無關, 當時問了下其餘同事也遇到了這個問題, 可是我須要查一下如何解決它,以及它的危害與預防.前端
bug追查:
WARNING: POSSIBLE DNS SPOOFING DETECTED! 翻譯成中文 警告:檢測到可能的DNS欺騙!哦哦原來是"信任"方面的問題, 那我能想到的就是"身份驗證方面", 有關身份我只作過全局的gitlab的帳號郵箱設置, 權限設置, 還有就是ssh的設置, 那麼怎麼看都是ssh嫌疑最大, 最後仍是去網上查到的解決方法.vue
bug解決方案:
刪除 known_hosts 文件
一臺主機上有多個Linux系統,會常常切換,那麼這些系統使用同一ip,登陸過一次後就會把ssh信息記錄在本地的~/.ssh/known_hsots文件中,
切換該系統後再用ssh訪問這臺主機就會出現衝突警告,須要手動刪除修改known_hsots裏面的內容。
有如下兩個解決方案:node
優缺點:webpack
需求:
項目內須要使用地圖展現資產在全球的分佈, 須要繪製'全球地圖',有閃爍提示有懸停展現詳情, 本功能只是一個小模塊, 因此不準有明顯的加載感, 後端會返回給我每一個點對應的經緯度.ios
分析與準備:nginx
<template> <div id="main" style="position: relative; width: 100%; height: 100%; padding: 0px; margin: 0px; border-width: 0px; cursor: default;" /> </template> <script> import echarts from 'echarts'; import geoJson from '../assets/geojson/countries.geo.json'; export default { props: { mapData: Array, // 裏面只有三個值, 經度, 緯度, 數量 用於打點 }, data() { return { sanData: [], myChart: null, tooltip: { // 提示框 trigger: 'item', formatter: (arg) => { if (arg.value) { return `${arg.name}: ${arg.value[2]}`; } return ''; }, }, geo: { // 地圖的底色樣式 map: 'all', zoom: 1, top: 30, left: 30, right: 30, bottom: 30, show: true, roam: false, label: { normal: { show: false, }, emphasis: { show: false, }, }, itemStyle: { normal: { areaColor: '#47D1FF', // 板塊顏色 borderColor: '#3B5077', // 邊線 shadowColor: 'rgba(0, 0, 0, 0.2)', shadowBlur: 10, }, emphasis: { areaColor: '#2B91B7', // 懸停 }, }, }, effect: { // 閃點樣式 name: '數量', type: 'effectScatter', showEffectOn: 'render', // render emphasis coordinateSystem: 'geo', hoverAnimation: true, legendHoverLink: true, symbolSize: () => 20, rippleEffect: { brushType: 'stroke', }, itemStyle: { normal: { color: '#ff8003', }, }, label: { normal: { formatter(arg) { return arg.value[2]; }, position: 'inside', show: true, }, emphasis: { show: false, }, }, }, map: { // 地圖的繪製數據 type: 'map', name: '工程數', mapType: 'world', // 自定義擴展圖表類型 geoIndex: 0, itemStyle: { normal: { label: { show: true } }, emphasis: { label: { show: true } }, }, }, }; }, methods: { initMap() { this.myChart = echarts.init(document.getElementById('main')); const { myChart, sanData, effect, tooltip, geo, map, } = this; echarts.registerMap('all', geoJson, {}); effect.data = sanData; const option = { geo, tooltip, series: [effect, map], }; myChart.setOption(option); }, // 組裝成地圖須要的打點數據 initDian() { this.mapData.forEach((item) => { this.sanData.push({ name: item.country, value: [ item.lng, item.lat, item.value, ], }); }); }, }, mounted() { this.initDian(); this.initMap(); }, }; </script>
背景:
一個展轉了三個團隊, 維護了快三年的老vue項目, 代碼簡直亂到使人髮指的程度, 好比請求報錯了 /api/home/list/ip這樣的地址報401, 那麼我去查找這個地址在哪裏發出的請求, 全局也沒搜索到這個地址, 一個小時後我才知道 這個地址被分紅了相似這種-> , const a = 'api', const b = 'home', const c = 'list', 請求的時候 axios.get(/${a}/${b}/${c}/ip
), 不只如此, 這個請求還被放在的vuex裏面展轉反側三個配置頁面而後被各類從新命名以後不知所蹤, 關鍵是連個文檔也沒有, 這個項目在我來到公司以前就已是一我的人不肯碰的存在了.git
須要解決的問題:程序員
解決方案:web
404問題:
若是監測到new字段就跳轉到新項目, 檢測到home路徑就跳到老項目, 這個會有bug, 好比我亂打一個xxx/jjj那麼這個就會留在原地, 咱們就須要在'新老'兩個項目裏面都寫一個'404頁面', 這一點想到了那麼若是是這樣 xxx/new/jjj這又是一個'404頁面'可是他帶new字段, 那麼它跳到新項目又變成了bug, 我想到的解決方案是 new這個新項目只要檢測到不是本身路由表裏的地址, 就把這個鏈接指向老項目, 老鄉維護一套新項目的路由地址list, 只有在list內纔會進行跳轉新項目的操做, 這樣bug就解決了, 可能你會有更好的方法哦能夠一塊兒交流.
401與303 前端 測試 後端:
好比說: 你在老項目裏面不報303那麼登陸頁面就把你轉到'來時的'路徑, 可是這個路徑若是指向新項目, 可是新型項目裏面報了401, 致使新項目又跳回登陸頁面, 日復一年年復一年的循環跳轉.
只要出現循環的跳轉, 測試就會來找到咱們, 由於這看起來絕壁是前端問題啊, 你死循環管後端什麼事, bug提給我無論是否是個人問題, 有時間的話我都會幫着排查與修復, 我把這個緣由搞清楚後去跟後端同窗溝通, 這個過程挺慢的, 畢竟誰也不但願bug是本身的..., 但是這個問題到第一次上線他們也沒有去解決, 線上又報循環跳轉測試仍讓我緊急修復, 這個雖然可以理解但也挺無語, 後來用的技巧就是把問題在羣裏拋出來, 用簡短的話把問題說清楚, 不能"看着像前端問題就前端改", 固然了我跟後臺同窗瞭解下303餘與401的判斷標準, 在前端側也增長了一層登陸判斷, 雖然沒啥大用可是也能幫後端同窗解決95%的差別了, 但是剩下5%的問題我已經幫他們分析出解決方案, 但是也放在下個版本作了.
故事是這樣的
做者接到了一個離職者的遺留工程的新增需求,需求很簡單:在一個表單中根據某一項的選擇狀況來決定顯示與隱藏一個input,好比'類型下拉框'選擇‘我的’就隱藏‘訂單號’反之則顯示而且爲'必填', 這個需求簡直簡單到爆。
bug描述
當先不選擇'我的', 而後再選擇'我的'選項時,‘訂單號的input’消失了可是報錯提示信息'訂單號爲必填'仍是存在。
bug初步分析
element-ui自己是否有缺陷, 我用v-if控制輸入框的隱藏它沒有檢測到。
bug初步解決
在我隱藏這個輸入框後, 100毫秒的時候調用一次表單的驗證方法,雖然你可以解決但這個方法給人的感受就是臨時方案。
bug深刻分析
建一個vue工程把這個bug狀況在純淨的新工程裏面還原一次,結果並未復現, 這就說明這bug跟人家element沒有關係,定位在代碼自己有問題就行了,問題的元兇就在@change這個事件裏面, 上一位同窗是在行間這樣寫的。 @change="() => { updateDesc(); updateYtsUserType(); updateMonitoring() }"
而在updateMonitoring方法裏面有一個對錶單的校驗,這個updateMonitoring方法還有5處地方在調用,因此並不建議修改這裏, 致使這一bug的緣由是@change事件與vue的數據更新機制未銜接好, vue更新一個值是要通過diff算法的, 更新數據採用三種方案,1:事件的訂閱發佈 2: promise 3:settimeout 逐級兼容, change事件剛好在這以前就調用了表單的驗證,因此把這個檢驗放在下一個宏任務就不會出現這個bug了, 也不會出現錯誤信息一閃而逝的狀況。
想起了聚焦與失焦的問題(某些移動端有bug)
以前作移動端項目有三個input, 我須要監控當前用戶從某個input框裏面填完再跳到某個input框的操做路徑, 並作一些相應的處理,具體的業務場景我記不清了, 可是當時我發現,好比我再inputa裏面輸入內容後跳到inputb裏面,有時候是先執行的inputb的聚焦 而後 纔是inputa的失焦 而且這個時間不是固定的, 由於當時我搞了個0秒延時器並非100%奏效, 這個點你們能夠注意一下。
正常因該是 a聚焦-> a失焦-> b->聚焦 pc端還挺好
這種事情我也認爲屬於小bug, 畢竟程序員是追求高效的, 並且減小操做步驟能夠減小出錯的機率。
以前上傳代碼
1: 打包yarn build
2:壓縮
把打包好的dist文件壓縮爲zip格式
3:scp上傳dist.zip文件
4:ssh鏈接服務器
5: 進入指定目錄, unzip解壓dist
如今傳代碼
1: 打包yarn build
2:scp上傳代碼scp -r dist/* root@1.1.1.1:/home/xxx/xxxt
反思
若是包並非特別大的話或者網絡很很差, 建議使用第二種, 不以優化小而不爲,不以危害小而爲之。
bug描述
拉新項目-> 切分支-> yarn 一切正常,打開地址就報這個錯.
中文意思就是這個項目裏面混合使用了common的規範與es的規範, 須要我統一規範, 就比好比使用了 module.exports
也使用了 import
bug初步解決
使用插件讓二者兼容就解決了npm install babel-plugin-transform-es2015-modules-commonjs
babelrc配置{ "plugins": ["transform-es2015-modules-commonjs"] }
思考
這個問題應該不會是個須要下載插件或者修改代碼才能解決的問題, 畢竟開發了好久, 若是啓動都有bug那怎麼上線的, 因此問題應該就存在於流程上, 或者外部的環境上, 好比它使用了我本地的全局webpack的話那就有多是我webpack版本問題, 但查了一下package.json文件並沒有這種狀況,那問題就在操做流程上。
bug解決
緣由很簡單, 這個是個老工程使用npm管理版本, 而我習慣性的用了yarn, 致使yarn命令並不能讀取package-lock.json文件,那麼我下載的版本與以前同窗使用的版本可能出現了不一樣, 刪掉node_modules文件夾npm i
, 解決問題
反思:npm與yarn的鎖文件能否用插件兼容
npm: package-lock.json
yarn:yarn.lock
能否作一個小插件把這兩種文件類型與數據相互的轉換, 我分別看了下這兩個文件的格式以下
文件類型各不相同, 還有一個問題就是這兩個工具的源也有差別, 可能會出現某個插件某個版本yarn能夠安裝, npm裏面沒有等等問題, 這就致使相似的兼容插件沒有大的意義了。
總結
你們仍是暫時老老實實使用過同一種包管理工具把。
hover思惟的侷限
剛入門的時候一個老師給我講,標籤的:hover只能修改這個元素自己與這個元素內部的元素, 因此當時寫一個彈出菜單的話須要把這個'標題''彈出框'寫在一個div裏面, hover這個div的時候彈出框block, 可是其實hover能夠選擇兄弟元素, 能夠選擇遠方的兄弟元素, 能夠給兄弟元素增長條件
舉例子
<div class="home"> <div class="main">被hover的元素</div> <div class="content">相鄰的元素</div> <div class="content"> <span>遠處的元素</span> <p>我不變色</p> </div> </div>
.main:hover +.content +.content >span { color: red; }
需求描述
好比我如今有6種數據類型, 每種類型前面要有一個‘彩色的點’來快速代表他是什麼類型以下圖:
要解決的問題
解決問題
上才藝,咳咳不是,是上代碼
<div data-color="red" data-title="1">動漫</div> <div data-color="green" data-title="2">小說</div> <div data-color="blue" data-title="3">狗狗</div>
*[data-color]::after { content: attr(data-title); color: white; align-items: center; display: inline-flex; justify-content: center; width: 20px; height: 20px; font-size: 12px; margin-left: 10px; border-radius: 50%; } @each $color in red, green, yellow, blue { *[data-color="#{$color}"]::after { background-color: $color; } }
注意
attr只能在content
中生效。
若是attr不是隻能在content
裏生效就行了,咱們就能夠完美解決這一問題,這方面如今也在提案中, 可是暫時沒有瀏覽器支持。
受限於css的本性, 這裏並不完美, 顏色方面仍是要傳,若是你們有好的方法能夠私信討論一下。
問題描述
咱們前端工程師無時無刻都在與json打交道(或是一個大對象),好比咱們生成了一個很長的json或者是ajax獲取到了一段很長的json, 咱們想要把這個json拿出來單獨做爲一個文件本地引入, 或者是在控制檯看着累要拿到某些工具中進行解析,爲了提高性能會出現不少..., 除此以外還會出現對象類型須要手動打開等狀況, 說實話複製出來不是太方便
用鼠標複製仍是處於網民階段, 成須要確定是利用方法
使用window.copy方法把數據複製到剪切板裏面就能夠拿到了, 對於開發環節來講又不用在意兼容性, 這個方法我試了一下也並無長度限制挺好用的。
使用js直接把json數據生成在一個文件裏面豈不是更方便, 聽到這個的時候就是感受js不是不能夠操縱用戶的文件系統麼。。。 有點打破個人固有認知, 可是試了一下他提供的方法, 還真不錯,下面我就介紹一下這個方法與原理:上才藝
(function(console){ console.save = function(data, filename){ if(!data) { console.error('Console.save: No data') return; } if(!filename) filename = 'console.json' if(typeof data === 'object'){ data = JSON.stringify(data, undefined, 4) } var blob = new Blob([data], {type: 'text/json'}), e = document.createEvent('MouseEvents'), a = document.createElement('a') a.download = filename a.href = window.URL.createObjectURL(blob) a.dataset.downloadurl = ['text/json', a.download, a.href].join(':') e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null) a.dispatchEvent(e) } })(console) console.save({a:1})
// 這裏是解釋版, 每一個語句的意思都詳細的解釋
(function(console){ console.save = function(data, filename){ if(!data) { // 1:沒東西沒有意義, 大部分多是複製錯了 console.error('Console.save: No data') return; } // 2:名字確定要有個 if(!filename) filename = 'console.json' if(typeof data === 'object'){ // 3:轉成字符串 // 4: JSON.stringify // 第一個參數:就是數據了 // 第二個參數:指定哪些key須要處理, undefined就是都處理 // 第三個參數: 層級之間的空格縮進數 data = JSON.stringify(data, undefined, 4) } // 這個構造函數厲害了: Blob // Blob類型的對象表示不可變的相似文件對象的原始數據。 // Blob對象是二進制數據,但它是相似文件對象的二進制數據,所以能夠像操做File對象同樣操做Blob對象 // Blob 表示的不必定是JavaScript原生格式的數據(這句最關鍵)。File 接口基於Blob // 第一個參數是數組, 就是個拼接,這個本身拼也行 // 第二個參數是配置, 這裏咱們指定爲json文件 var blob = new Blob([data,data], {type: 'text/json'}), // 自定義一個事件 e = document.createEvent('MouseEvents'), // a標籤沒什麼好說的 a = document.createElement('a') // 必須定義, 不然變成了跳轉 a.download = filename // URL就是定義本地路徑的api, 咱們作一個上傳組件 或是裁剪組件的時候, 會用這種方式展現本地的圖片 a.href = window.URL.createObjectURL(blob) // dataset就是獲取屬性的意思 // 格式->> text/json:文件名:blob數據 a.dataset.downloadurl = ['text/json', a.download, a.href].join(':') // 咱們的自定義事件配置 e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null) // 觸發咱們的自定義事件 a.dispatchEvent(e) } })(console) console.save({a:21},'來段靜態文件')
雖然用處真的不大, 可是開闊了思路對將來的變成之路也是有好處的。
本次的分享就是這樣,我深入的感覺到‘好的解決方法’不少, 最缺乏的是好的問題,歡迎交流, 祝天天進步