此次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},'来段静态文件')
虽然用处真的不大, 可是开阔了思路对将来的变成之路也是有好处的。
本次的分享就是这样,我深入的感觉到‘好的解决方法’不少, 最缺乏的是好的问题,欢迎交流, 祝天天进步