吃掉那只青蛙读后感
序言
在每天都有做不完的重复性的工作,我们如果一只保持这种状态下去的话,我们将不能很好地将所有的事情都在既定的时间内处理,我们就得要根据时间的优先级进行排序,通过这种方式,我们将那些复杂又耗时的事情进行集中处理,然后保证工作、家庭生活互不冲突,更好地来管理我们地时间,腾出更多的时间出来陪同家人、加强自身的学习、进行体育锻炼,而不是将有限的生命风险给无限的时间。
因此,我们提议,吃掉那只青蛙!我们为什么要吃掉一只🐸呢?不可以是其他的吗?这里的🐸其实是用比喻的方式,指的是那些又难啃又复杂的任务,按照一定的规则,来将这些任务进行合理的分配,然后集中时间精力,来吃掉一只又一只的青蛙。
🤔️那么我们应当怎样做,才能够吃掉那只🐸呢??这里需要以下几个方面的一个流程,如果能够将其固化成为我们的一个长期习惯,那么,我们每天将能够腾出更多的时间精力,分配到其他的事情上。
如何吃掉一只🐸?答案很简单,就是一口一口地来吃,那么又如何一口一口地来吃掉这只🐸呢?
这么大的🐸,可以是将任务(🐸)拆分为不同的子任务,比如我们原本是一个年度的一个计划,那么我们可以拆分为季度计划,再拆分为月度计划,再拆 ...
高效学习
前言
社会不断前进发展,我们会很明显的发现,如果自己和5年前的自己相比,没有任何增长,包括技能、价值、积累资金等,那么可以认为在者5年的时间内,自己没有半点增长,没有进步,自己还是和5年前的自己一样没有成长,那么最后就只有被社会所淘汰,社会不断往前发展,以前用的诺基亚称霸手机市场,现在都是苹果、华为、小米等平台的天下了,所以,如果不进步,就只有被社会所淘汰。现在信息量如此爆棚的时代,谁能够快速掌握更多的知识,谁就能够获取足够多的竞争力,就能够在企业/事业单位中夺得头筹。那么信息变化这么快,比如vue/react从刚出来,到现在到处都使用,前后不到两年的时间,而且现在市面上招的前端都需要足够多的vue/react运用技巧,甚至于源码的精通,好像就是还没入门就已经被淘汰了。那么我们如何快速吸收更多的知识,高速学习掌握吃透更多的知识,就需要高效的学习。
如何高效学习?举个🌰 –> 我们平时熟悉一些知识点,主要靠的是死记硬背,通过这种方式可以在短时间内,应付考试,但有可能造成信息的错乱,可能会记错知识点,而且在后面,可能时间久了,就忘了这个了。那么,我们如何来记住这些知识点呢??这 ...
前端技术架构
技术架构
根据上述的蜘点大平台架构图,我们对应划分为以下几大块进行详细描述
1. 协同工作
开发规范
为了低成本高效率的提高代码质量,基于公司实际情况,定制化开发了一个 webpack 脚手架,解决了以下问题:
避免了无限制引入第三方库:无限制引入第三方库,是一种常被忽略,但却很容易带来问题的行为(例如 vue+jquery 等)。因为开发人员通常并不会阅读第三方库的源代码,不能保证其是安全可靠的。而定制脚手架,提供了所有开发中需要的依赖,并严控新依赖的引入,则确保整个工程是安全的。约束开发人员代码规范:开发最常见问题是代码规范混乱,各写各的,导致维护成本高企。而通过引入 eslint,强行规定代码风格,自动对不符合规范的代码报错,解决了这些问题。并且由于 IDE 支持通过应用 eslint 规则,自动格式化代码。也降低了对开发人员的约束成本,降低推行代码规范的难度。方便提供给其他开发使用标准的脚手架,并提供技术支持(比如可以统一大前端的技术栈)。
git分支管理、code review创建项目时,一般会针对不同的环境,来创建三个常设分支:
develop:开发环境的稳定分支,公开 ...
jquery源码解读
前言现在的童鞋估计一上手项目,就不是以前直接用jquery来撸项目,而是使用的vue,react等快速开发框架,虽然jquery已经渐渐地淡出现阶段的项目,但它霸屏了长达好几年的浏览器,很值得我们具体来学习其中的缘由。
框架预览首先我们先看下jquery的总体架构,如下图:
首先它通过类工厂模式,创建了一个jquery对象,通过立即执行函数IIFE包裹,提供requirejs的方式引入jquery,可以在nodejs中包含document对象属性的环境中运行,最终也就是执行的factory(window, noGlobal)方法,来将window作为参数进行传递!
其次,为兼容amd环境使用jquery,同样地在框架中支持amd方式调用jquery
框架源码问题一一解读这里有一个点,就是为毛我们能够在引入了jquery库的环境中,可以使用window.$呢?原因就是它在全局环境中用$来指向了new出来的jquery对象,具体如下
从👆 我们可以看出这里将定义出来的jquery对象由window中的$来指向,因此,我们使用$()方法其实就是使用的jquery()方法
jquery ...
jenkins+gradle+pgyer+email => 安卓持续集成打包apk流程
前言以前开发的时候,一般流程是开发调试,提测的时候,给测试甩安装包或者是安装的二维码,各测试同时自行下载安装验证,但提供安装包的过程又臭又长,如果对于频繁需要修改bug并进行快速回归的话,单单通过android studio开发工具来提供的话,不仅效率低,而且打包时间大大占据了开发者的bug调试时间,因此,需要jenkins等持续集成平台来提供,也就是app的开发者,不再提供apk安装包,由测试同事自行到jenkins上索取安装包进行安装
jenkins环境的安装首先,先安装jenkins环境,访问jenkins网址 https://www.jenkins.io/zh/,选择适合自己的版本进行下载并安装,这边选用的是mac环境下的jenkins
通过brew命令来安装jenkins:
安装最新的jenkins LTS 版本:brew install jenkins-lts
或者安装指定版本的LTS:brew install jenkins-lts@VERSION
启动jenkins服务:brew services start jenkins-lts
重启jenkins服务:brew ...
在你的项目代码层面中加入git提交代码的规范
前言大家在日常的coding生活中,不免需要提交代码,然后每次代码commit的message,是否有认真地描述过呢?
我想不少童鞋应该是直接随便编写点简单的描述内容就直接提交上去了,但是,要是遇到下图这个情况:
作为项目管理员,在做这个代码的code reviewing的时候,要看每次提交的代码具体都是做了什么事情的时候,估计心里会有一顿F开头的话语。
那么作为一个项目的负责人,有必要对开发人员每次提交的message进行维护,不同的开发人员对每次commit的描述都有不同的格式。
根据业界开发人员整理了关于这个commit的规范,且在相关的IDE开发工具中提供的相关的插件
供我们方便的使用。
防范于未然,我们总不能在每个项目的各个阶段来跟进到代码提交的规范,更应该让每个开发人员在提交代码的时候都有这个意识。
针对👆这个情况,对于web前端项目,我们可以提供一简单的工具,在每个开发人员在提交代码的时候,自动拦截不符合规范的git commit message。
validate-commit-message 插件工具的使用validate-commit-message的安装sc ...
vue组件的生命周期与options属性一览
前言
每个Vue应用都是通过Vue函数创建一个新的Vue实例开始的:var vm = new Vue({});一个 Vue 应用由一个通过 new Vue 创建的根 Vue 实例,以及可选的嵌套的、可复用的组件树组成
像上述中的Todo根实例中,我们的子孙组件,都是以*.vue文件,包含template、script、style标签组成的,这里的所有的*.vue组件都是Vue实例子,并且接受相同的选项对象(除了一些特有的实例之外)
![new Vue()中的参数选项](new Vue()中的参数选项.png)
一、组件的生命周期这边在原本组件的生命周期上,加入了各个属性以及值的赋值操作,进行了一个补充,如下图:
从👆图我们可以看出,在Vue组件中的这些关于界面、数据等属性操作,都是在什么情况下可以访问的,从而可以帮助我们更好的编写代码
1.1、beforeUpdate与updatedVue实例中定义的data函数所返回的对象中属性,只有在对应的html中使用时,这个property改变时,才会调用beforeUpdate以及updated函数,比如有以下的代码:
对应的执行结 ...
深入浅出Vue.extend
前言
Vue.extend作为一全局api,作为我们去实现编程式组件的重要途径,所以我们通过源码学习的方式,来加深对Vue.extend函数的理解,通过以下几个问题的解读,来对Vue.extend深入学习
Vue.extend在Vue中的用途?
讲解下Vue.extend的内部实现?
实现一个编程式组件,具体的思路应该式怎样?
Vue.extend的深入基本用法参数:[Object] options
用法:使用基础Vue构造器,创建一个”子类”,参数式一个包含组件选项的对象,data选项是特例,需要注意⚠️下【Vue.extend()中data必须是函数。】
12345678910111213// 创建构造器 var Profile = Vue.extend({ template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>', data: function () { return { firstName: 'Walter', lastName: 'Wh ...
vue插件开发
前言插件的功能:
vue插件通常用来为Vue添加全局功能,插件的功能防伪没有严格的限制,一般有一下几种:
添加全局方法或者property。
添加全局资源:指令/过滤器/过渡等
通过全局混入来添加一些组件选项
添加Vue实例方法,通过把它们添加到Vue.prototype上实现
一个库,提供自己的API,同时提供上面的一个或多个功能
插件的使用通过全局方法Vue.use()使用插件,它需要在调用new Vue()启动应用之前完成:
123// 调用`MyPlugin.install(Vue)`Vue.use(MyPlugin);new Vue({});
也可以传入一个可选的选项对象:
1Vue.use(MyPlugin, { someOption: true });
⚠️ Vue.use会自动组织多次注册相同插件
插件的开发
Vue.js的插件应该暴露一个install方法,这个方法的第一个参数是Vue构造器,第二个参数是一个可选的选项对象:
123456789101112 MyPlugin.install = (Vue, options){// 1. 添加全局方法或者pro ...
slice、splice傻傻分不清
前言平时在日常开发过程中,总是间歇性的分不清数组的slice和splice方法,几乎每次需要用到的时候,都怀疑自己会记错了,都要去度娘一下。
slice
slice() 方法可以从已有的数组中返回选定的元素语法
1arrayObject.slice(start, end)
参数
描述
start
必填,规定从何处开始选取,如果是负数,则从数组尾部开始算起的位置,也就是说,-1指的是最后一个元素,-2是倒数第二个元素,以此类推。
end
可选,规定从何处结束选取,该参数是数组断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从start到数组结束的所有元素。如果这个参数是负数,那么同上。
返回值:返回一个新的数组,包含从start到end(不包含该元素)的arrayObject中的元素。
说明:⚠️,该方法并不会修改数组,二是返回一个子数组。如果想删除数组中的一段元素,应该使用方法Array.splice()
splice
splice() 方法 向/从 数组中 添加/删除 项目,然后返回被删除的项目。⚠️:该方法会改变到原始数组语法:
1arrayO ...
vue中8个有用的自定义指令
前言
Vue除了核心功能默认内置的指令(v-model和v-show)之外,Vue也允许注册自定义指令。
⚠️在Vue2.0中,代码复用和抽象的主要形式是组件,然而,有的情况下,我们仍然需要对普通的DOM元素进行底层操作,这个时候就会用到自定义指令
举个官方的🌰,我们需要在input输入框一创建的时候,然后在任何我们需要的情况下,只要设置了该指令,就在一加载页面的时候,获取到焦点,这种比如是需要连接扫码枪的业务,比较适合。
1234567891011121314// 注册一个全局自定义指令'v-focus'Vue.directive('focus', { inserted: function(el){ el.focus(); }});// 当然我们也可以注册局部指令,组件中接收一个`directive`的选项:directives: { focus: { inserted: function(el){ el.focus(); } }}
钩子函数一个指令定义对象可以提供如下几个钩子函数(均为可选):
bind:只调用一次,指令第一次绑定到元素时调 ...
js日常coding小技巧二
编写JavaScript的5个小技巧自从知道了这几个JavaScript技巧,下班都变早了!
1、加号操作符+这里说的不是数字的简单相加,而是将表达式转成数字的操作符。
12345678910console.log(+new Date()); //1620288834588console.log(+true); // 1console.log(+false); // 0const random = { // 重载对象的valueOf方法 valueOf: () => Math.floor(Math.random() * 100)};console.log(+random); // 4console.log(+random); //23console.log(+random); //30
刚接触JavaScript的新手可能觉得这种写法有点即乖,数字类型转换会倾向于用Number()函数。结果是一样的,但是用+就简洁多了。如果某个对象重载了valueOf方法,+操作符会返回这个方法的结果
2、debugger语句在浏览器 DevTools 上打断点调试,基本上人人都会。但是你知 ...
你不知道的Chrome DevTools的骚操作(-)
引言前端设备参差不齐、环境复杂,因此给前端的研发童鞋制造了许多的BUG,为了快速解决BUG,灵活运营调试工具就显得特别的重要了,因此这边整理了关于Chrome浏览器的调试方法,在Mac下,使用F12或者右键”检查”即可打开浏览器的调试工具。
1、动态修改元素样式类名增删类名在条件逻辑中比较常见,通过devtools可以直接动态修改/激活/禁用类名
在DOM树中选中元素
点击激活.cls
可通过选择框动态修改是否使用该类名
可通过Add new class输入框动态添加已定义类名
👆除了给元素修改类名,还可以动态的添加css规则:
2、强制激活伪类网页中的一些动效是基于例如:active、:hover等,当鼠标移动到控制台的时候,这些伪类就不生效,在控制台中也无法调试css样式,此时可以使用强制激活伪类
选中具有伪类效果的元素
点击:hov
根据代码情况,勾选相应伪类
在styles面板可动态调试伪类样式
3、计算样式定位到CSS规则【直接浏览最终生效的样式定义位置】一个工程项目的DOM层级是比较复杂的,如果font-size这一样式属性,就可能存在多层覆盖,我们必须定位 ...
JavaScript数组reduce总是不会用?看看这5个例子就懂了
前言相信不少初学者都曾经被JavaScript数组的reduce方法困扰过,一直搞不明白到底应该怎么来用。
reduce方法是按照顺序对数组每个元素执行某个函数,这个函数接收上一次执行结果作为参数,并将结果传递给下一次调用。reduce方法用的好的话可以简化复杂的逻辑,提高代码可读性。通过👇几个例子可以帮助快速理解reduce的用法。
1、数字数组求和这是reduce最常见的入门级例子。
12345678910111213141516 // 传统的for循环写法如下 function sum(arr){let sum = 0;for(const val of arr){ sum += val;}return sum; } // ➡️ 使用了reduce的方式 function sum(arr) { const reducer = (sum, val) => sum + val; const initialValue = 0; return arr.reduce(reducer, initialValue); } sum([1,3,5,7]); //16
re ...
js日常coding小技巧一
编写JavaScript的10个小技巧
简介的代码不但方便阅读,还能减少复杂逻辑和出错的可能性。本文就介绍一些常用的JavaScript简化技巧,日常开发都用得上。
1、简化条件表达式经常碰到这种情况,要判断某个变脸是否为指定的某些值,用常规的逻辑表达式会很长,我们可以将它们都放到数组中来进行判断
12345678// 太长的逻辑表达式if('abc' === xxx || 'def' === xxx || 'sdf' === xxx || 'oop' === xxx){ //执行其他逻辑}//➡️ 简写后的版本if(['abc', 'def', 'sdf', 'oop'].includes(xxx)){ // 执行其他逻辑}
2、简化if…else…if...else...太常用了,以至于很多人都忘记了其实还有更好的方式来进行的条件判断,比如一些简单的赋值操作,就没有必要进行冗长的语句,一行表达式就可以搞定了:
1234567891011// 冗长的写法let test = true;if(x > 100){ test = true;}else{ test = fa ...
this的指向
前言在ES5中,关于this的指向,始终坚持一个原理:** this永远指向最后调用他的那个对象, **
➡️ 为毛要使用this,这里引入一段话:
12345从前有座山,山里有座庙叫做神庙,神庙里面有好多和尚,和尚们都很喜欢神庙,于是和尚们都经常跳水到神庙。
读上面的一段话,现实中显然比较拗口,我们一般会使用”这”或者其他替代词,调整后如下:
12345从前有座山,山里有座庙叫做神庙,这里面有好多和尚,和尚们都很喜欢这,于是和尚们都经常跳水到这。
首先我们来看一个最简单的例子:
例1:1234567 var name = 'windowsName'; function fun(){console.log(this.name); // --> windowsName console.log('inner: ' + this); // inner: Window } a(); console.log('outer:' + this); // --> outer: Window
👆大家应该都知道为什么log的都是windowsName,因为格局刚刚的那句话th ...
this, call, apply, bind 知多少
前言:关于this关键词的指向✨* this永远指向最后调用它的那个对象 *
一、call、apply、bind的用途二、手写call、apply、bind
节流与防抖
问题引入问题1: 如果要实现dom节点的拖拽功能,但是在绑定拖拽事件的时候发现每当元素稍微移动一点点就会触发大量的回调函数,导致浏览器直接卡死,这个时候,我们应咋整呢?
问题2: 如果给一个按钮绑定了表单提交的post事件,但用户有时候在网络比较差的情况下多次点击按钮造成表单重复提交,如果防止多次提交事件的发生?
为了应对上述场景,变出现了函数防抖和函数节流两个概念,总的来说,这两个方法是在时间轴上控制函数的执行次数。
函数防抖(debounce)概念: 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
生活中的实例: 如果有人进电梯(触发事件),那电梯在10秒钟后触发(执行事件监听器),这时如果又有人进电梯了(在10秒钟内再次触发该事件),则我们又得等待10秒再出发(重新计时)
举个🌰:
123456789 // 模拟一段ajax请求 function ajax(content){console.log('ajax requst ' + content); } let inputA = document.getElementById('unDebounce') ...
回流与重绘
写在前面
在讨论回流与重绘之前,我们需要知道浏览器的渲染过程
从上面这个图我们可以看出,浏览器的渲染过程如下:
解析HTML,生成DOM树,解析CSS,生成CSSOM树;
将DOM树与CSSOM树结合,生成渲染树(Render Tree);
Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小);
Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素;
Display:将像素发送给GPU,展示到页面上(这一步其实还有很多的流程在其中,比如会在GPU将多个层合并为同一个层,并展示在页面中,而css3硬件加速的原理是新建合成层)。
渲染过程看起来很简单,让我们来了解一下每一步都具体做了什么。
生成渲染树
为了构建渲染树,浏览器主要完成了以下工作:
从DOM树的根节点开始便利每个可见节点;【渲染树只包含可见的节点】
对于每个可见的节点,找到CSSOM树中对应的规则,并应用它们;
根据每个可见节点以及其对应的样式,组合生成渲染树。
👆有了渲染树,我们就知道了所有可见节点的样式,然后计算它们在页面上的大小和位置,最 ...