这是我参与8月更文挑战的第2天,活动详情查看:8月更文挑战javascript
此文为前端进阶篇前边已经出了基础篇php
基础篇连接点击跳转css
JSONP:ajax 请求受同源策略影响,不容许进行跨域请求,而script 标签src 属性中的链 接却能够访问跨域的js 脚本,利用这个特性,服务端再也不返回JSON 格式的数据,而是 返回一段调用某个函数的js 代码,在src 中进行了调用,这样实现了跨域。html
AJAX 建立异步对象XMLHttpRequest操做XMLHttpRequest 对象前端
var xhr = new XMLHttpRequest();
xhr.open('get', 'aabb.php', true);
xhr.send(null);
xhr.onreadystatechange = function() {
if(xhr.readyState==4) {
if(xhr.status==200) {
console.log(xhr.responseText);
}
}
}
复制代码
PWA 全称Progressive Web App,即渐进式WEB 应用。一个PWA 应用首先是一个网页,能够经过Web 技术编写出一个网页应用. 随后添加上App Manifest 和Service Worker来实现PWA 的安装和离线等功能vue
直接给你们一个连接吧超详细。 juejin.im/post/599970…java
rem 单位如何转换为像素值 当使用rem 单位的时候,页面转换为像素大小取决于叶根元素的字体大小,即HTML 元素的字体大小。根元素字体大小乘rem 的值。例如,根元素的字体大小为16px,那么 10rem 就等同于10*16=160px。node
em 是如何转换成px 的 当使用em 单位的时候,像素值是将em 值乘以使用em 单位的元素的字体大小。例如一 个div 的字体为18px,设置它的宽高为10em,那么此时宽高就是18px*10em=180px。react
.test{
width: 10em;
height: 10em;
background-color: #ff7d42;
font-size: 18px;
}
/** 必定要记住的是,em 是根据使用它的元素的font-size 的大小来变化的,而不是根据父 元素字体大小。有些元素大小是父元素的多少倍那是由于继承了父元素中font-size 的设 定,因此才起到的做用。 */
复制代码
em 单位的继承效果 使用em 单位存在继承的时候,每一个元素将自动继承其父元素的字体大小,继承的效果 只能被明确的字体单位覆盖,好比px 和vw。只要父级元素上面一直有fontsize 为em 单 位,则会一直继承,但假如本身设置了font-size 的单位为px 的时候,则会直接使用自 己的px 单位的值。jquery
根html 的元素将会继承浏览器中设置的字体大小 除非显式的设置固定值去覆盖。因此html 元素的字体大小虽然是直接肯定rem 的值, 但这个字体大小首先是来源于浏览器的设置。(因此必定要设置html 的值的大小,因 为有可能用户的浏览器字体大小是不一致的。)
当em 单位设置在html 元素上时 它将转换为em 值乘以浏览器字体大小的设置。
html{
font-size: 1.5em;
}
/** 能够看到,由于浏览器默认字体大小为16px,因此当设置HTML 的fontsize 的值为1.5em 的售后,其对应的px 的值为16*1.5=24px 因此此时,再设置其余元素的rem 的值的时候,其对应的像素值为n*24px。 例如,test 的rem 的值为10, */
.test{
width: 10rem;
height: 10rem;
background-color: #ff7d42;
}
/** 总结: 1. rem 单位翻译为像素值的时候是由html 元素的字体大小决定的。此字体大小会 被浏览器中字体大小的设置影响,除非显式的在html 为font-size 重写一个单位。 2. em 单位转换为像素值的时候,取决于使用它们的元素的font-size 的大小,可是有 由于有继承关系,因此比较复杂。 优缺点 em 可让咱们的页面更灵活,更健壮,比起处处写死的px 值,em 彷佛更有张力,改 动父元素的字体大小,子元素会等比例变化,这一变化彷佛预示了无限可能, em 作弹性布局的缺点还在于牵一发而动全身,一旦某个节点的字体大小发生变化,那 么其后代元素都得从新计算 */
复制代码
// IOS8 下已经支持带小数的px 值, media query 对应devicePixelRatio 有个查询值
// -webkit-min-device-pixel-ratio, css 能够写成这样
// 经过-webkit-min-device-pixel-ratio 设置。
.border { border: 1px solid #999 }
@media screen and (-webkit-min-device-pixel-ratio: 2) {
.border { border: 0.5px solid #999 }
}
@media screen and (-webkit-min-device-pixel-ratio: 3) {
.border { border: 0.333333px solid #999 }
}
// 若是使用less/sass 的话只是加了1 句mixin
// 缺点: 安卓与低版本IOS 不适用, 这个或许是将来的标准写法, 如今不作期望
复制代码
这是淘宝移动端采起的方案, github 的地址:https://github.com/amfe/lib-flexible. 前面已经 说过1px 变粗的缘由就在于一刀切的设置viewport 宽度, 若是能把viewport 宽度设置 为实际的设备物理宽度, css 里的1px 不就等于实际1px 长了么. flexible.js 就是这样 干的. <meta name=”viewport”>
里面的scale 值指的是对ideal viewport 的缩放, flexible.js 检 测到IOS 机型, 会算出scale = 1/devicePixelRatio
, 而后设置viewport
/** 对于解决1px 边框问题,我我的以为最完美的解决办法仍是伪类+transform 比较好。 原理:是把原先元素的border 去掉,而后利用:before 或者:after 重作border ,并 transform 的scale 缩小一半,原先的元素相对定位,新作的border 绝对定位。 media query 经过媒体查询,能够经过给不一样分辨率的设备编写不一样的样式来实现响应式的布局,比 如咱们为不一样分辨率的屏幕,设置不一样的背景图片。好比给小屏幕手机设置@2x 图,为 大屏幕手机设置@3x 图,经过媒体查询就能很方便的实现。 可是媒体查询的缺点也很明显,若是在浏览器大小改变时,须要改变的样式太多,那么 多套样式代码会很繁琐。*/
@media screen and (min-width: 320px) {
html {
font-size: 50px;
}
}
@media
/** 方便应用普遍适用于pc 端手机页面,一般作自适应布局时咱们比较经常使用。
缺点:相对于代码要重复不少,得知道设备的宽度,手机的分辨率不少因此麻烦了点,
不过性能方面确定最高; 可能存在闪屏的问题
@media 处理手机和pc 端界面兼容的问题,在IE 上的访问出现问题,百度方法,找找
两种,一种是respond.js,另外一种是
css3-mediaquerieshttp://blog.csdn.net/small_tu/article/details/47317453
*/
复制代码
给你们一个参考不一一列举了移动端性能优化的方法
其余参考连接:https://zhuanlan.zhihu.com/p/28206065
手势事件 | 事件详解 |
---|---|
touchstart | 当手指接触屏幕时触发 来代替 click 事件 来触发移动端的点击事件 |
touchmove | 当手指接触屏幕时触发 代替 scroll 事件 |
touchend | 当手指离开屏幕时触发 来代替 click 事件 来触发移动端的点击事件 |
实际程序开发当中,咱们代码中用的值是指逻辑分辨率pt,而不是像素分辨率px, 好比咱们定义一个按钮的高度为45,这个45 指的是45pt 而不是45px。在非Retina 屏下1pt = 1px,4 和4.7 寸Retina 屏下1pt = 2px,5.5 和x 下1pt = 3px.咱们制做不一样尺寸的图片, 好比@1x 为22px,则@2x 为44px,@3x 为66px,命名分别为image.png,在项目的 Assets.xcassets 中新建New Image Set,修更名字为image,并把相应尺寸的图片拖放至相应位置。
/* 根据dpr 显示2x 图/3x 图*/
.bg-image(@url){
background-image:~"url('@{url}@2x.png')";
@media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3){
background-image:~"url('@{url}@3x.png')";
}
}
.bg-color(@color) {
background-color: @color;
}
复制代码
这个问题是 devicePixelRatio 的不一样致使的,由于手机分辨率过小了,若是按照分辨率显示网页,字会很是小,全部苹果系统当初就把 iphone 4 的960x640像素的分辨率在网页里更改成480x320像素。这样是 devicePixelRatio = 2. 而 Android 的 devicePixelRatio 比较乱,值有1.五、2和3,为了在手机里更为清晰地显示图片, 必须使用2倍宽高的背景图来代替 img 标签(通常状况下都使用2倍) 例如:一个 div 的宽高是 100x100 背景图必须是200x200,而后设置 background-size:contain 样式,显示出来就比较清晰。
<meta name="viewport" content="user-scalable=no">
<meta name="viewport" content="initial-scale=1,maximum-scale=1">
复制代码
//设置内联的元素在3D 空间如何呈现:保留
3D-webkit-transform-style:preserve-3D;
//设置进行转换的元素的背面在面对用户时是否可见:隐藏
-webkit-backface-visibility:hidden;
复制代码
body {
-webkit-overflow-scrolling: touch;
overflow-scrolling:touch;
}
复制代码
element{
-webkit-touch-callout: none;
}
复制代码
babel 的转译过程也分为三个阶段,这三步具体是:
Babel 解析成AST,而后插件更改AST,最后由Babel 输出代码那么Babel 的插件模块须要你暴露一个function,function 内返回visitor
module.export = function(babel){
return {
visitor:{
}
}
}
复制代码
visitor 是对各种型的AST 节点作处理的地方,那么咱们怎么知道Babel 生成了的 AST 有哪些节点呢?很简单,你能够把Babel 转换的结果打印出来, 或者这里有传送门:AST explorer
/** 这里咱们看到const result = 1 + 2 中的1 + 1 是一个BinaryExpression 节点,那么在 visitor 中,咱们就处理这个节点 */
var babel = require('babel-core');
var t = require('babel-types');
const visitor = {
BinaryExpression(path) {
const node = path.node;
let result;
// 判断表达式两边,是否都是数字
if (t.isNumericLiteral(node.left) && t.isNumericLiteral(node.right)) {
// 根据不一样的操做符做运算
switch (node.operator) {
case "+":
result = node.left.value + node.right.value;
break
case "-":
result = node.left.value - node.right.value;
break;
case "*":
result = node.left.value * node.right.value;
break;
case "/":
result = node.left.value / node.right.value;
break;
case "**":
let i = node.right.value;
while (--i) {
result = result || node.left.value;
result = result * node.left.value;
}
break;
default:
}
}
// 若是上面的运算有结果的话
if (result !== undefined) {
// 把表达式节点替换成number 字面量
path.replaceWith(t.numericLiteral(result));
}
}
};
module.exports = function (babel) {
return {
visitor
};
}
// 插件写好了,咱们运行下插件试试
const babel = require("babel-core");
const result = babel.transform("const result = 1 + 2;",{
plugins:[
require("./index")
]
});
console.log(result.code); // const result = 3;
/** 与预期一致,那么转换const result = 1 + 2 + 3 + 4 + 5;呢? 结果是: const result = 3 + 3 + 4 + 5; 这就奇怪了,为何只计算了1 + 2 以后,就没有继续往下运算了? 咱们看一下这个表达式的AST 树 你会发现Babel 解析成表达式里面再嵌套表达式。 表达式( 表达式( 表达式( 表达式(1 + 2) + 3) + 4) + 5) 而咱们的判断条件并不符合全部的,只符合1 + 2 */
// 判断表达式两边,是否都是数字
if (t.isNumericLiteral(node.left) && t.isNumericLiteral(node.right)) {}
/** 那么咱们得改一改 第一次计算1 + 2 以后,咱们会获得这样的表达式 表达式( 表达式( 表达式(3 + 3) + 4) + 5) 其中3 + 3 又符合了咱们的条件, 咱们经过向上递归的方式遍历父级节点 又转换成这样: 表达式( 表达式(6 + 4) + 5) 表达式(10 + 5) 15 */
// 若是上面的运算有结果的话
if (result !== undefined) {
// 把表达式节点替换成number 字面量
path.replaceWith(t.numericLiteral(result));
let parentPath = path.parentPath;
// 向上遍历父级节点
parentPath && visitor.BinaryExpression.call(this, parentPath);
}
/** 到这里,咱们就得出告终果const result = 15; 那么其余运算呢: */
const result = 100 + 10 - 50>>>const result = 60;
const result = (100 / 2) + 50>>>const result = 100;
const result = (((100 / 2) + 50 * 2) / 50) ** 2>>>const result = 9;
复制代码
参考回答: 给本身引流一下能够参考我转载的政采云的一篇文章很详细 点此此处跳转
Vue 是一个构建数据驱动的渐进性框架,它的目标是经过API 实现响应数据绑定和视图更新。 优势:
缺点:
虚拟dom 是相对于浏览器所渲染出来的真实dom 的,在react,vue 等技术出现以前, 咱们要改变页面展现的内容只能经过遍历查询dom 树的方式找到须要修改的dom 然 后修改样式行为或者结构,来达到更新ui 的目的。 这种方式至关消耗计算资源,由于每次查询dom 几乎都须要遍历整颗dom 树,若是 创建一个与dom 树对应的虚拟dom 对象( js 对象),以对象嵌套的方式来表示dom 树,那么每次dom 的更改就变成了js 对象的属性的更改,这样一来就能查找js 对象 的属性变化要比查询dom 树的性能开销小。
// @keyup. 方法
<template>
<input ref="myInput" type="text" value="hello world" autofocus @keyup.enter="handleKey"> </template>
<script> export default { methods: { handleKey(e) { console.log(e) } } } </script>
// addEventListener
<script> export default { mounted() { document.addEventListener('keyup', this.handleKey) }, beforeDestroy() { document.removeEventListener('keyup', this.handleKey) }, methods: { handleKey(e) { console.log(e) } } } </script>
<script> export default { mounted() { document.addEventListener('keyup', this.handleKey) }, beforeDestroy() { document.removeEventListener('keyup', this.handleKey) }, methods: { handleKey(e) { console.log(e) } } } </script>
复制代码
deep 设置为true 就能够监听到对象的变化
let vm=new Vue({
el:"#first",
data:{msg:{name:'北京'}},
watch:{
msg:{
handler (newMsg,oldMsg){
console.log(newMsg);
},
immediate:true,
deep:true
}
}
})
复制代码
通俗来说,既能用computed 实现又能够用watch 监听来实现的功能,推荐用computed, 重点在于computed 的缓存功能
computed 计算属性是用来声明式的描述一个值依赖了其它的值,当所依赖的值或者变量 改变时,计算属性也会跟着改变;
watch 监听的是已经在data 中定义的变量,当该变量变化时,会触发watch 中的方法。
Vue 数据双向绑定是经过数据劫持结合发布者-订阅者模式的方式来实现的。利用了 Object.defineProperty() 这个方法从新定义了对象获取属性值(get)和设置属性值(set)。
Vue3.0采用了 new Proxy() 能够参考https://juejin.cn/post/6950826293923414047 掘金签约的大神所写。
axios 的是一种异步请求,用法和ajax 相似,安装npm install axios --save 便可使用,请 求中包括get,post,put, patch ,delete 等五种请求方式,解决跨域能够在请求头中添加 Access-Control-Allow-Origin,也能够在index.js 文件中更改proxyTable 配置等解决跨域 问题。
// 一、绝对路径直接引入
// 在index.html 中用script 引入
<script src="./static/jquery-1.12.4.js"></script>
// 而后在webpack 中配置external
externals: { 'jquery': 'jQuery' }
// 在组件中使用时import
import $ from 'jquery'
// 2 、在webpack 中配置alias
resolve: { extensions: ['.js', '.vue', '.json'], alias: { '@': resolve('src'), 'jquery':
resolve('static/jquery-1.12.4.js') } }
// 而后在组件中import
// 三、在webpack 中配置plugins
plugins: [ new webpack.ProvidePlugin({ $: 'jquery' }) ]
// 全局使用,但在使用eslint 状况下会报错,须要在使用了$ 的代码前添加/*eslint-disable*/ 来去掉ESLint 的检查。
复制代码
响应式优化。
基础用法:
let datas = {
num:0
}
let proxy = new Proxy(datas,{
get(target,property){
return target[property]
},
set(target,property,value){
target[property] += value
}
})
复制代码
Vue.js 2.x 的数据更新并触发从新渲染的粒度是组件级的,单个组件内部须要遍历该组 件的整个vnode 树。在2.0 里,渲染效率的快慢与组件大小成正相关:组件越大,渲染 效率越慢。而且,对于一些静态节点,又无数据更新,这些遍历都是性能浪费。 Vue.js 3.0 作到了经过编译阶段对静态模板的分析,编译生成了Block tree。Block tree 是一个将模版基于动态节点指令切割的嵌套区块,每一个区块内部的节点结构是固定的, 每一个区块只须要追踪自身包含的动态节点。因此,在3.0 里,渲染效率再也不与模板大小 成正相关,而是与模板中动态节点的数量成正相关。
Vue.js 2.x 中,若是有一个组件传入了slot,那么每次父组件更新的时候,会强制使子组 件update,形成性能的浪费。
Vue.js 3.0 优化了slot 的生成,使得非动态slot 中属性的更新只会触发子组件的更新。 动态slot 指的是在slot 上面使用v-if,v-for,动态slot 名字等会致使slot 产生运行时动 态变化可是又没法被子组件track 的操做。
3.diff 算法优化
Vue2.x 中的虚拟dom 是进行全量的对比。 Vue3.0 中新增了静态标记(PatchFlag):在与上次虚拟结点进行对比的时候,值对比 带有patch flag 的节点,而且能够经过flag 的信息得知当前节点要对比的具体内容化。
Vue2.x : 不管元素是否参与更新,每次都会从新建立。 Vue3.0 : 对不参与更新的元素,只会被建立一次,以后会在每次渲染时候被不停的复用。
默认状况下onClick 会被视为动态绑定,因此每次都会去追踪它的变化可是由于是同一个函数,因此没有追踪变化,直接缓存起来复用便可。
vue 的数据劫持有两个缺点:
因此vue2.x 中才会有$set 属性的存在 proxy 是es6 中推出的新api,能够弥补以上两个缺点,因此vue3.x 版本用proxy 替换 object.defineproperty。
中间件提供第三方插件的模式,自定义拦截action -> reducer 的过程。变为action -> middlewares -> reducer 。这种机制可让咱们改变数据流,实现如异步action ,action 过 滤,日志输出,异常报告等功能。
常见的中间件:redux-logger:提供日志输出;redux-thunk:处理异步操做;redux-promise: 处理异步操做;actionCreator 的返回值是promise
根据组件的职责一般把组件分为UI 组件和容器组件。UI 组件负责UI 的呈现,容器组件负责管理数据和逻辑。二者经过React-Redux 提供connect 方法联系起来。
// 1. 初始化阶段
getDefaultProps:获取实例的默认属性
getInitialState:获取每一个实例的初始化状态
componentWillMount:组件即将被装载、渲染到页面上
render:组件在这里生成虚拟的DOM 节点
componentDidMount:组件真正在被装载以后
// 2. 运行中状态
componentWillReceiveProps:组件将要接收到属性的时候调用
shouldComponentUpdate:组件接受到新属性或者新状态的时候(能够返回false,接收数据
后不更新,阻止render 调用,后面的函数不会被继续执行了)
componentWillUpdate:组件即将更新不能修改属性和状态
render:组件从新描绘
componentDidUpdate:组件已经更新
// 3. 销毁阶段:
componentWillUnmount:组件即将销毁
复制代码
shouldComponentUpdate 这个方法用来判断是否须要调用render 方法从新描绘dom。因 为dom 的描绘很是消耗性能,若是咱们能在shouldComponentUpdate 方法中可以写出更 优化的dom diff 算法,能够极大的提升性能。
Flux 的最大特色,就是数据的"单向流动"。
React 虚拟dom 技术要求不断的将dom 和虚拟dom 进行diff 比较,若是dom 树比价大, 这种比较操做会比较耗时,所以React 提供了shouldComponentUpdate 这种补丁函数,如 果对于一些变化,若是咱们不但愿某个组件刷新,或者刷新后跟原来其实同样,就能够 使用这个函数直接告诉React,省去diff 操做,进一步的提升了效率。
React 会建立一个虚拟DOM(virtual DOM)。当一个组件中的状态改变时,React 首先会 经过"diffing" 算法来标记虚拟DOM 中的改变,第二步是调节(reconciliation),会用diff 的结果来更新DOM。
在React 组件中,应该在componentDidMount 中发起网络请求。这个方法会在组件第 一次“挂载”(被添加到DOM)时执行,在组件的生命周期中仅会执行一次。更重要的是, 你不能保证在组件挂载以前Ajax 请求已经完成,若是是这样,也就意味着你将尝试在 一个未挂载的组件上调用setState,这将不起做用。在componentDidMount 中发起网络 请求将保证这有一个组件能够更新了。
Refs 能够用于获取一个DOM 节点或者React 组件的引用。什么时候使用refs 的好的示例 有管理焦点/文本选择,触发命令动画,或者和第三方DOM 库集成。你应该避免使用 String 类型的Refs 和内联的ref 回调。Refs 回调是React 所推荐的。
高阶组件是一个以组件为参数并返回一个新组件的函数。HOC 运行你重用代码、逻辑 和引导抽象。最多见的多是Redux 的connect 函数。除了简单分享工具库和简单的 组合,HOC 最好的方式是共享React 组件之间的行为。若是你发现你在不一样的地方写 了大量代码来作同一件事时,就应该考虑将代码重构为可重用的HOC。
由于this.props 和this.state 的更新多是异步的,不能依赖它们的值去计算下一个state。
在组件的render 方法中返回null 并不会影响触发组件的生命周期方法
Keys 会有助于React 识别哪些items 改变了,被添加了或者被移除了。Keys 应该被赋 予数组内的元素以赋予(DOM)元素一个稳定的标识,选择一个key 的最佳方法是使用一 个字符串,该字符串能唯一地标识一个列表项。不少时候你会使用数据中的IDs 做为 keys,当你没有稳定的IDs 用于被渲染的items 时,可使用项目索引做为渲染项的 key,但这种方式并不推荐,若是items 能够从新排序,就会致使re-render 变慢
在super() 被调用以前,子类是不能使用this 的,在ES2015 中,子类必须在constructor 中调用super()。传递props 给super() 的缘由则是便于(在子类中)能在constructor 访问 this.props。
JSX 是JavaScript 语法的一种语法扩展,并拥有JavaScript 的所有功能。JSX 生产 React "元素",你能够将任何的JavaScript 表达式封装在花括号里,而后将其嵌入到JSX 中。在编译完成以后,JSX 表达式就变成了常规的JavaScript 对象,这意味着你能够在 if 语句和for 循环内部使用JSX,将它赋值给变量,接受它做为参数,并从函数中返回 它。
Props down
Events up
model 是Angular 开发中的基本单位,是一个容器,能够包含组件、指令、管道等
Components 是可被反复使用的带有特定功能的视图
Templates 是通过指令和管道、组件等加强过的html
Bindings 结合着事件绑定属性绑定双向数据绑定等扩展html 的功能
Directives 分为结构性和属性型指令还有其余模块中好比路由模块中的指令等,
主要是加强html.
Pipes 能够对数据作一个筛选、过滤、格式化从而获得目的数据
Service 将组件、应用中的可共用的部分,好比数据或者方法等封装成服务以方便服用
DependencyInjection 依赖注入
复制代码
ngOnChanges:当Angular 设置其接收当前和上一个对象值的数据绑定属性时响应。
ngOnInit:在第一个ngOnChange 触发器以后,初始化组件/指令。这是最经常使用的方法,
用于从后端服务检索模板的数据。
ngDoCheck:检测并在Angular 上下文发生变化时执行。
每次更改检测运行时,会被调用。
ngOnDestroy:在Angular 销毁指令/组件以前消除。取消订阅可观察的对象并脱离
事件处理程序,以免内存泄漏。
组件特定的hooks:
ngAfterContentInit:组件内容已初始化完成
ngAfterContentChecked:在Angular 检查投影到其视图中的绑定的外部内容以后。
ngAfterViewInit:Angular 建立组件的视图后。
ngAfterViewChecked:在Angular 检查组件视图的绑定以后
复制代码
Angular 应用程序具备路由器服务的单个实例,而且每当URL 改变时,相应的路由就与路 由配置数组 进行匹配。在成功匹配时,它会应用重定向,此时路由器会构建ActivatedRoute 对象的树, 同时包含路由器的当前状态。在重定向以前,路由器将经过运行保护(CanActivate) 来检查是否容许新的状态。Route Guard 只是路由器运行来检查路由受权的接口方法。 保护运行后,它将解析路由数据并经过将所需的组件实例化到 <router-outlet></router-outlet>
来激活路由器状态。
Rxjs 是在微软所提供的一种的异步处理数据的方式,在Angular 中处理网络通讯时用到了。
建立一个Observable 并subsribe
好比:this.http.get('').subscribe((data)=>{ })
复制代码
到这里基本完成了还有哪里没有讲述到的欢迎各位大佬指正批评。建议点赞+收藏