Generator 是一个生成函数,返回值是一个迭代器,可用于异步调用。
比如某个事物只有三种状态(状态 A,状态 B,状态 C),而这三种状态的变化是状态 A =>状态 B =>状态 C =>状态 A ,这就是状态机。Generator 特别适用于处理这种状态机
1、在循环对象属性的时候,使用 for…in,在遍历数组的时候的时候使用for…of。
2、for…in 循环出的是 key,for…of 循环出的是 value
3、注意,for…of 是 ES6 新引入的特性。修复了 ES5 引入的 for…in 的不足
4、for…of 不能循环普通的对象,需要通过和 Object.keys()搭配使用
解构赋值语法是一种 Javascript 表达式。通过解构赋值, 可以将属性/值从对象/数组中取出,赋值给其他变量。
应用场景:默认值,交换变量,将剩余数组赋给一个变量
阻止冒泡:.stop、
阻止默认事件:.prevent、
事件捕获 :.capture、
事件在元素本身触发回调:.self 、
事件只触发一次:.once,
只会在自己范围内触发的事件 .self
不阻止默认行为: .passive
Object.defineProperty方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性,并返回这个对象
Object.defineProperty 有三个参数(object , propName , descriptor)
第一个参数:定义属性的对象。
第二个参数:要定义或修改的属性的名称。
第三个参数:将被定义或修改的属性描述符。
性能提升 更小巧,更快速,支持摇树优化支持自定义渲染器
API变动 除渲染函数API和scoped-slot语法外,其余均保持不变或者通过另外构建一个兼容包来兼容2.x
重写虚拟DOM 重写将包括更有效的代码来创建虚拟节点
methods在重新渲染的时候每次都会被重新的调用;
computed监听属性,监听依赖发生变化就会调用 。
watch 影响数据变化当绑定的数据方法发生变化就会重新调用
MVC:
Model(模型)
View(视图)
Controller(控制器)
简单的理解:视图请求数据,将请求发送至控制器,控制器再将请求发送给模型,模型去查找数据,找到之后传给控制器,控制器再传给视图进行渲染。
MVVM
Model 代表数据模型
View 代表UI视图
ViewModel 负责监听 Model 中数据的改变并且控制视图的更新(桥梁,可以理解成mvc中的控制器)
简单理解:视图请求数据,将请求发送至控制器,在控制器的两端具有监听机制,直接调用模型的数据,一端改变全部改变,利用数据劫持,结合订阅者和发布者模式,实现数据的双向绑定
闭包:
定义 当一个函数的返回值是另外一个函数,而返回的函数如果调用了父函数的内部变量,且返回的那个函数在外部被执行,就产生了闭包.
闭包的三个特性
1:函数套函数
2:内部函数可以直接访问外部函数的内部变量或参数
3:变量或参数不会被垃圾回收机制回收
闭包的优点:
1:变量长期驻扎在内存中
2:避免全局变量的污染
3:私有成员的存在
闭包的缺点
常驻内存 增大内存的使用量 使用不当会造成内存的泄露.
调用方式:
//1:直接调用
a()()//内部函数的执行
//2:通过赋值在调用var f = a(); f()
作用域分为全局作用域和局部作用域
全局作用域:变量在函数或者代码块{ }外定义,即为全局作用域。
局部作用域:在函数内部定义的变量,就是局部作用域。局部作用域内,对外是封闭的,从外层的作用域无法直接访问函数内部的作用域
作用域链:自由变量的向上级作用域一层一层查找,直到找到为止,最高找到全局作用域,就形成了作用域链。
class继承:
class 相当于es5中构造函数
class中定义方法时,前后不能加function
class中只能定义方法,不能定义对象,变量等
class和方法内默认都是严格模式
ES5中继承:原形链继承+构造函数继承
原型链继承:父类的实例作为子类的原型
缺点: 引用类型值的属性会被所有实例共享。
借用构造函数继承:在子类,使用call()调用父类方法,并将父类的this修改为子类的this.就是把父类的实例属性复制了一份放到子类的函数内
优点:
1 可以传递参数
2 解决了原型中所有实例共享的问题
组合继承:既能调用父类实例属性,又能调用父类原型属性
原形链:
每个函数都有一个prototype,叫做显示原型
每个实例都有一个_proto_,叫做隐式原型
实例的隐式原型指向构造的显示原型
获取对象属性时,如果对象本身没有这个属性,那就会去他的原型__proto__
上去找,如果还查不到,就去找原型的原型,一直找到最顶层(Object.prototype
)为止。Object.prototype对象也有__proto__属性值为null。
promise是一个容器,里面保存异步操作的结果
promise是一个对象,可以获取异步操作的最终状态(成功/失败)
promise是一个构造函数,对外提供统一的API自身上有all,reject,resolve等方法,原型上有then,catch方法
promise两大特点
promise对象状态不受外界影响
promise的状态一旦改变,不会在变,任何时候都可以得到这个结果,状态不可逆
三种状态:pending初始状态 fulflled成功状态 rejected失败状态
async 是“异步”的简写, async 用于声明一个异步的 function
await 可以认为是 async wait 的简写,await 用于等待一个异步方法执行完成。
特点:
asayc的用法,它作为一个关键字放到函数前面,这样普通函数就变为了异步函数
异步async函数调用,跟普通函数的使用方式一样
异步async函数返回一个promise对象
async函数配合await关键字使用是异步方法,但是阻塞式的
vue的双向数据绑定只要是采用数据劫持结合开发者和订阅者方式 通过Object.defineProperty()来劫持各个属性的setter,getter, 在数据变动时发布消息给订阅者,触发相应监听回调
vue的数据双向绑定 将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者。 通过Observer来监听自己的model的数据变化,通过Compile来解析模板指令。
virtual-dom(简称vdom)的概念得益于react的出现react这个框架的非常重要的特性之一。
在vue的整个应用生命周期当中,每次需要更新视图的时候便会使用vdom
vdom算法是基于snabbdom算法所做的修改。
实现
①用js对象构造一个虚拟的dom树,插入到文档中;
②状态变更时,记录新树和旧树的差异;
③把上面的差异构建到真正的dom中
Vuex 是适用于 Vue.js 应用的状态管理库,为应用中的所有组件提供集中式状态存储与操作,保证了所有状态以可预测的方式进行修改。
优点 当state中定义一个数据后,可以在所在项目的任何组件中进行获取,修改,修改可以得到全局的变更
运行机制:vue提供数据来驱动试图,通过dispath派发actions,通过commit调用mutations的方法,修改state的数据
state是存储数据的一个对象
mutaitions 是可以直接操作state的数据
actions是可以调用mutaitions中的方法
getters 类似计算属性 可以对state里面的数据进行一些逻辑性的操作
modules 将仓库分模块化
标签:是Vue的内置组件,在组件切换过程中将状态保留在内存中,取消组件的销毁函数,防止重复渲染DOM
当用它包裹
时,会缓存不活动的组件实例,而不是销毁它们。
和
相似,它自身不会渲染一个 DOM 元素。
使用
组件后即可使用 activated() 和 deactivated() 这两个生命周期函数
父组件传到子组件 通过props属性给子组件通信的
子组件向父组件传值 父组件通过自定义事件,接受子组件传递来的参数,子组件通过$emit触发父组件上的自定义事件发送参数
兄弟通信:bus事件
在子组件中创建模板,在props中接受父组件传递的数据,在父组件中引入子组件,然后在components中创建子组件,挂载到父组件的template中
props 父传子使用 $emit(参1,参2)子传父时使用 参1是自定义的事件名,参2是要传递的数据,在父组件的子组件中绑定自定义事件名,调用一个函数,函数的形参就是传递的数据
自定义指令分为:全局自定义指令,局部自定义指令。
钩子函数
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
inserted:被绑定元素插入父节点时调用。
bind:只调用一次,指令第一次绑定到元素时调用。
update:所在组件的 VNode 更新时调用
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
**指令钩子函数会被传入以下参数:
**
el:指令所绑定的元素,可以用来直接操作 DOM 。
binding:一个对象,包含以下属性:
name:指令名,不包括 v- 前缀。
value:指令的绑定值,例如:v-my-directive=“1 + 1” 中,绑定值为 2。
oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression:字符串形式的指令表达式
arg:传给指令的参数
modifiers:一个包含修饰符的对象
vnode: Vue编译生成的虚拟节点
oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
全局路由守卫有个两个:一个是全局前置守卫,一个是全局后置守卫
① 全局导航钩子:一般用来判断权限,以及页面丢失时需要执行的操作;
beforeEach()每次路由进入之前执行的函数。
afterEach()每次路由进入之后执行的函数。
beforeResolve()2.5新增
② 单个路由(实例钩子):某个指定路由跳转时需要执行的逻辑。
beforeEnter() beforeLeave()
③ 组件路由钩子:
beforeRouteEnter()
beforeRouteLeave()
beforeRouteUpdate()
**路由独享守卫:**路由独享守卫是在路由配置页面单独给路由配置的一个守卫
beforeCreate() 在实例创建之间执行,数据未加载状态
created() 在实例创建、数据加载后,能初始化数据,dom渲染之前执行
beforeMount() 虚拟dom已创建完成,在数据渲染前最后一次更改数据
mounted() 页面、数据渲染完成,真实dom挂载完成
beforeUpadate() 重新渲染之前触发
updated() 数据已经更改完成,dom 也重新 render 完成,更改数据会陷入死循环
beforeDestory() 和 destoryed() 前者是销毁前执行(实例仍然完全可用),后者则是销毁后执行
activated(keep-alive组件激活调用)
deactivated(keep-alive组件停用调用)
errorcapture(捕获来自子孙组件错误是调用)
理解跨域的概念:协议、域名、端口都相同才同域,否则都是跨域
jsonp 实现原理:主要是利用动态创建 script 标签请求后端接口地址,然后传递 callback 参数,后端接收 callback,后端经过数据处理,返回 callback 函数调用的形式,callback 中的参数就是 json
优点:浏览器兼容性好,
缺点:只支持 get 请求方式
vue跨域: 在vue.config.js的空文件中,配置文件
target:要访问的接口的基础地址
changeOrigin:是否可以跨域
secure:是否进行 https 验证
pathRewrite:将 api 替换成 ’ ’ 中的值
200 OK //客户端请求成功
400 //客户端请求有语法错误,不能被服务器所理解
401 //请求未经授权
403 //服务器收到请求,但是拒绝提供服务
404 //请求资源不存在,输入了错误的 URL
500 //服务器发生不可预期的错误
503 //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
创建脚手架下载element -ui 配置路由 创建登入页面 在element-ui复制表单 和表单验证 把账号密码进行绑定 根据接口判断登入状态是否 !=200登入失败,==200登入成功 this.$router.push 跳转到后台首页,存入token值 登入完成进行后台首页基本布局 分为头部区域 主题区域 侧边栏 进行相对应的css布局 然后配置axios拦截器 进行token验证 在main.js中添加代码,在将axios挂载到vue原型 请求侧边栏数据 通过v-for双重循环渲染左侧菜单 根据左侧菜单的路由制作相应的用户管理,权限管理,商品管理,订单管理,数据统计根据项目文档完成里面对应的功能.
深拷贝复制变量值,对于非基本类型的变量,则递归至基本类型变量后,再复制。 深拷贝后的对象与原来的对象是完全隔离的,互不影响, 对一个对象的修改并不会影响另一个对象。
为什么要使用深拷贝: 我们希望在改变新的数组(对象)的时候,不改变原数组(对象)
可 以 使 用 for in 、 Object.assign 、 扩 展 运 算 符 … 、Array.prototype.slice()、Array.prototype.concat() 、递归等递归函数实现深拷贝
大致过程是这样的:
1.DNS 解析
2.TCP 连接
3.发送 HTTP 请求
4.服务器处理请求并返回需要的数据
5.浏览器解析渲染页面
6.连接结束
常见的 3 字开头的状态码有:
301(永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应时,会自动将请求者转到新位置。
302(临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
304 (未修改) 自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。
4xx(请求错误) 这些状态代码表示请求可能出错,妨碍了服务器的处理。
常见的 4 字开头的状态有:404 – 请求的网页不存在5xx(服务器错误)
这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。
常见的以 5 开头的状态码有:
500 (服务器内部错误) 服务器遇到错误,无法完成请求。
503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态
虚拟dom就是用对象的方式区代真实的dom操作。
当页面打开时浏览器解析HTML元素,构建一个dom树,将状态保存起来,在内存中模拟dom操作,又会生成一个dom树,两个进行比较,根据diff算法找出不同的地方,之渲染一次不同的地方
diff算法就是进行虚拟节点对比,并返回一个patch对象,用来存储两个节点不同的地方,最后用patch记录的消息去局部更新Dom
data是一个函数时,每个组件实例都有自己的作用域,每个实例相互独立,不会相互影响。
Object是引用数据类型,如果不用function返回,每个组件的data都是内存的同一个地址,一个数据改变了其他也改变了
一、修改请求静态资源的路径
打开config下的index.js文件,修改assetsPublicPath的值,从‘/’改为‘./’。即从根路径改为相对路径。
二、修改本地图片的路径
打开build下的utils.js文件,增加 publicPath:’…/…/’
三、在终端运行npm run build。
防抖: 触发高频事件后 定时器内函数只会执行一次,如果定时器内高频事件再次被触发,则重新计算时间
场景:
按钮提交场景:防止多次提交按钮,只执行最后提交的一次。
节流 :高频事件触发,在定时器内只会执行一次,所以节流会稀释函数的执行效率。
1.拖拽场景:固定时间内只执行一次,防止超高频次触发位置变动
2.缩放场景:监控浏览器 resize
3.动画场景:避免短时间内多次触发动画引起性能问题
indexOf
function newArr(array){
//一个新的数组
var arrs = [];
//遍历当前数组
for(var i = 0; i < array.length; i++){
//如果临时数组里没有当前数组的当前值,则把当前值push到新数组里面
if (arrs.indexOf(array[i]) == -1){
arrs.push(array[i])
};
}
return arrs;
}
var arr = [1,1,2,5,5,6,8,9,8];
console.log(newArr(arr))
Set
function newArr(arr){
return Array.from(new Set(arr))
}
var arr = [1,1,2,9,6,9,6,3,1,4,5];
console.log(newArr(arr))
利用递归去重
24.Git指令
git init 初始化git仓库
git status 查看文件状态
git add 文件列表 追踪文件
git commit -m 提交信息 向仓库中提交代码
git log 查看提交记录
覆盖工作目录中的文件: git checkout --文件名
将文件从暂存区中删除: git r m --cached 文件名
git branch 查看分支
git branch 分支名称 创建分支
git checkout 分支名称 切换分支
git merge 来源分支 合并分支 (必须在master分支上才能合并d)
git branch -d 分支名称 删除分支(分支被合并后才允许删除)(-D 强制删除)
将本地仓库推送到远程仓库: git push 项目链接
Git 添加远程仓库origin (origin是仓库别名): git remote add 仓库名 项目链接
git push origin master
git push -u origin master
-u 将推送地址和分支保存,下次推送输入git push即可
在我们HTML页面中,每一个元素都可以被看作一个盒子,而这个盒子由:内容区(content)、填充区(padding)、边框区(border)、外边界区(margin)四部分组成。
标准模式下: 一个块的总宽度(页面中占的宽度)= width + margin(左右) + padding(左右) + border(左右)
怪异模式下: 一个块的总宽度= width + margin(左右)(即width已经包含了padding和border值)(IE浏览器)
常用: 标记清除 (因为常用,所以先介绍)
变量进入环境时在函数中声明一个变量,就将这个变量标记为“进入环境”。因为只要执行流进入相应的环境,就可能会用到它们。而当变量离开环境时,则将其标记为“离开环境”。
引用计数
引用计数的含义是跟踪记录每个值被引用的次数
内存泄漏:
对于持续运行的服务进程,必须及时释放不再用到的内存。否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃。
1.创建xhr 核心对象
2.调用open 准备发送
3.如果是post请求,必须设置请求头。
4.调用send 发送请求 (如果不需要参数,就写null)
5.监听异步回调
备注:如果是post请求,想要传json格式数据。
事件冒泡:事件冒泡会从当前触发的事件目标一级一级往上传递,依次触发,直到document为止。
事件捕获:事件捕获会从document开始触发,一级一级往下传递,依次触发,直到真正事件目标为止。
事件流: DOM结构是一个树型结构,当一个HTML元素产生一个事件时,该事件会在元素结点与根结点之间的路径传播,路径所经过的结点都会收到该事件,这个传播过程可称为DOM事件流。
1.event.stopPropagation();
事件处理过程中,阻止了事件冒泡,但不会阻击默认行为
2.return false;
事件处理过程中,阻止了事件冒泡,也阻止了默认行为
还有一种有冒泡有关的:
3.event.preventDefault();
它的作用是:事件处理过程中,不阻击事件冒泡,但阻击默认行为
箭头函数是匿名函数不能作为构造函数不能使用new
箭头函数不绑定arguments,需要用运算符解决…解决
箭头函数的 this 永远指向其上下文的 this ,任何方法都改变不了其指向
箭头函数通过call()或apply()调用一个函数,只传入了一个参数,对this并没有影响.
箭头函数没有原型属性
var声明的变量存在变量提升,变量可以声明之前调用
let和const不存在变量提升
let和const存在暂时性死区
var允许重复声明变量, let和const在同一作用域不允许重复声明变量
var不存在块级作用域,let和const存在块级作用域.
var和let可以修改声明变量
const声明的变量不能改变一但改变立即初始化,不能留到以后赋值
1.Vue 在不同组件间强制使用单向数据流,父组件可以向子组件传递数据,但是子组件不能直接修改父组件的状态。
2.数据的双向绑定
主要由MVVM框架实现,主要由三部分组成View、ViewModel和Model组成,其中view和model不能直接进行通信,他们通过中间件ViewModel来进行通信。
对页面加载速度影响最大的就是图片,一张普通的图片可以达到几M的大小。当页面图片很多时,页面的加载速度缓慢,几S钟内页面没有加载完成,也许会失去很多的用户。
所以,对于图片过多的页面,为了提高加载速度, 我们需要将页面内未出现在可视区域内的图片先不做加载, 等到访问到可视区域后再去加载。这样子对于页面加载性能会有很大的提升,也提高了用户体验。
使用nextTick的原因:Vue是异步修改DOM的,并且不鼓励开发者直接接触DOM,但是有时候需要必须对数据更改后的DOM元素做相应的处理,但是获取到的DOM数据并不是更改后的数据,这时候就需要this.$nextTick();
原理:Vue通过异步队列控制DOM更新和nextTick回调函数先后执行的方式。
for of 遍历数组
用于对数组或者对象的属性进行循环操作。
for in 遍历对象
for…of循环可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象,以及字符串
瀑布流的实现原理就是通过比较每一列的高度,如果这一列高度低的话就在这一列进行添加,如果可视区距离和滚动距离想加的话比你当前页面的高度还要高的时候,页面就开再次加载多个,这个主要也是页面布局,如果你的布局实现的不好的话!也会出现问题,首先每一列的高度,都是需要自适应的,不能设置高通过每一块内容将每一列撑起来,还有一个问题就是,滑动底部,根据每个电脑的不同,所以他每个人,获取的高度是不同而且有的时候,页面的整体高度和页面可视区高度加上滚动高度差 1px 这个时候就需要我们提前加载,不然滑动到底部也加载不出来!
在JavaScript中,null 和 undefined 几乎相等
null和undefined区别:
null表示没有对象,可能将来要赋值一个对象,即该处不应该有值
undefined表示缺少值,即此处应该有值,但没有定义
在浏览器里,在全局范围内this 指向window对象;
在函数中,this永远指向最后调用他的那个对象;
构造函数中,this指向new出来的那个新的对象;
call、apply、bind中的this被强绑定在指定的那个对象上;
箭头函数中this比较特殊,箭头函数this为父作用域的this,不是调用时的this.
apply、call、bind都是js给函数内置的一些API,调用他们可以为函数指定this的执行,同时也可以传参。
有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。子组件想修改时,只能通过 $emit 派发一个自定义事件,父组件接收到后,由父组件修改。