知识点目录基于 http://www.javashuo.com/article/p-bwnrhidz-gx.html
根据我的理解对每一个知识点附上的答案,有错误欢迎你们指出。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>标题</title> </head> <body> 内容 </body> </html>
header、footer、nav、section文档中的一节、article页面的独立内容区域、aside页面侧边栏内容、detailes文档某个细节部分、summary包含details元素的标题、dialog对话框
提供input更多输入类型,如color、date、email、number、range、tel、week、url、search等;新的表单元素datalist(其id属性与input的list属性绑定,实现选项列表输入);新表单元素keygen、output等;新增placehoder、required、pattern、min、max、step、height、width、autofocus、multiple属性。
<script> var c=document.getElementById("myCanvas"); var ctx=c.getContext("2d"); ctx.fillStyle="#FF0000"; ctx.fillRect(0,0,150,75); </script> 还有moveTo(x,y)线条开始坐标、lineTo(x,y)线条结束坐标; fillText(text,x,y)实心文本、strokeText(text,x,y)心文本; createLinearGradient(x,y,x1,y1) - 建立线条渐变 createRadialGradient(x,y,r,x1,y1,r1) - 建立一个径向/圆渐变 drawImage(image,x,y) - 将图片放在画布上等
网络: 检测网络状态: window.navigator.onLine 事件监听:online和offline 监听连上网络和断开网络 地理定位: 获取当前地理信息: window.navigator.geolocation.getCurrentPosition( successCallback, errorCallback, options ) 重复获取当前地理信息: window.navigator.geolocation.watchPosition( successCallback, errorCallback, options ) 成功的回调参数: position.coords.latitude 纬度 position.coords.longitude经度 web存储: sessionStorage(生命周期为关闭浏览器) 5M localStorage(永久生效,除非手动删除) 20M 全屏: 容许用户自定义网上任一元素全屏显示: requestFullScreen() 开启全屏 cancelFullScreen() 关闭全屏 文件读取: FileList对象,input上传文件后返回该对象 FileReader对象: 读取:readAsDataURL(file.files[0]) 监听: onload 拖拽: 给元素设置draggable="true",其中img和a标签默承认拖拽 事件监听: 拖拽元素: drag: 拖拽过程当中一直调用 dragstart: 拖拽开始调用 dragleave: 鼠标离开拖拽元素调用 dragend: 拖拽结束调用 目标元素: dragenter:拖拽元素进入时调用 dragover:停留在目标元素上时调用,注意阻止浏览器默认行为(event.preventDefault()) drop:当在目标元素上松开鼠标时调用 dragleave:当鼠标离开目标元素时调用 能够经过dataTransfer拿到当前的拖拽进来的文件列表 多媒体: load()、play()、pause()
css3新增的属性和选择器: 属性选择器、伪类选择器、反选伪类(:not()) box-shadow、border-image、 text-overflow(clip|ellipsis|string)、word-wrap、border-radius、opacity、 box-sizing、resize、 background-size、background-origin、background-clip transform、trasition、animation
格式化上下文,指一个独立的渲染区域或者说是一个隔离的独立容器
将元素类比为一个盒子,有外边距、边框、内边距、宽度、高度五个元素决定齐所占的元素空间大小
常见问题:javascript
可经过box-sizing:border-box锁定元素宽高;
content-box 元素的宽高 = 边框 + 内边距 + 内容宽高 border-box 元素的宽高 = width/height的宽高
将其中一个元素放入一个BFC模式的元素内(不推荐,会改变文档结构);通常会给其中一个元素设置margin-bottom直接给够距离
利用BFC机制,好比父盒子设置overflow:hidden;
内容宽高 = width/height 元素宽高 = 边框+内边距+width/height;设置box-sizing:border-box后值为:width/height 元素空间的宽高:外边距+边框+内边距+width/height
css预处理器方便开发,无需考虑浏览器兼容问题,代码模块化、清晰简洁scss 是 sass3 引入新的语法,其语法彻底兼容 css3,而且继承了 sass 的强大功能。sass 和 scss 实际上是同一种东西,咱们平时都称之为 sass,二者之间不一样之处有如下两点:1.文件扩展名不一样(.sass/.scss);2.语法书写方式不一样,sass 是以严格的缩进式语法规则来书写,不带大括号({})和分号(;),而 scss 的语法书写和咱们的 css 语法书写方式很是相似。css
<meta name="viewport" content="width=device-width,initial-scale=1" />
@media screen and (min-width: 768px) and (max-width: 1024px) ...
基本:String、Number、Boolean、Undefined、Null 引用:Object(Array、Function...) 检测: typeof(用于基本类型;typeof null返回object;typeof []返回object) 变量 === null ? 'null' : typeof 变量 instanceof(用于引用类型;不适用undefined和null) (变量).constructor(不适用undefined和null) Object.prototype.toString.call(),能够解决判断全部类型
+运算符的一个值若是是字符串,它会把另外一个值转为字符串拼接 一元+,会将值试图转为数字,如 +"5" 一元!,会将值试图转为boolean,再取反 在作比较运算时,也会发生不少隐示转换: 对象转字符串再转数字 布尔转数字 字符串转数字
函数定义: function example(param){} const example = function(param){} (function (param){})() const example = new Function('param', '') (param) => {} 箭头函数内的this与外层的this同样,箭头函数不能提高 函数调用: 函数名调用 example(param)至关于window.example(param) 做为方法调用,好比某个对象中的行为 obj.example(param) 构造函数调用 const exampleObj = new example(param); exampleObj.属性/行为 做为函数方法调用函数call()、apply(): obj = example.call(obj, param1, param2) obj = example.apply(obj, paramArray)
call和apply详解: 在javascript中,call和apply都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部this的指向。 function fruits() {} fruits.prototype = { color: "red", say: function() { console.log("My color is " + this.color); } } var apple = new fruits; apple.say(); //My color is red banana = { color: "yellow" } apple.say.call(banana); //My color is yellow apple.say.apply(banana); //My color is yellow 因此,能够看出call和apply是为了动态改变this而出现的,当一个object没有某个方法(本例子中banana没有say方法), 可是其余的有(本例子中apple有say方法),咱们能够借助call或apply用其它对象的方法来操做。 两者区别: func.call(this, arg1, arg2); 若干个参数 func.apply(this, [arg1, arg2]); 数组参数 经常使用实例: 数组追加: var array1 = [12 , "foo" , {name:"Joe"} , -2458]; var array2 = ["Doe" , 555 , 100]; Array.prototype.push.apply(array1, array2); // array1 值为 [12 , "foo" , {name:"Joe"} , -2458 , "Doe" , 555 , 100] 获取数组中的最大值和最小值: var numbers = [5, 458 , 120 , -215 ]; var maxInNumbers = Math.max.apply(Math, numbers), //458 maxInNumbers = Math.max.call(Math, 5, 458, 120, -215); //458 // number 自己没有 max 方法,可是 Math 有,咱们就能够借助 call 或者 apply 使用其方法。 验证是不是数组(前提是toString()方法没有被重写过): functionisArray(obj){ return Object.prototype.toString.call(obj) === '[object Array]' ; } 真伪数组转换: 真转伪:[].push.apply(obj, arr); 伪转真:[].slice.call(obj); bind 是返回对应函数,便于稍后调用;apply 、call 则是当即调用
基本类型,按值传递(函数内部修改形参值,不会影响外部实参值) 引用类型,按对象共享传递 var obj = {}; function f(o) { o.name = 'li'; } f(obj); console.log(obj.name); //li 被修改了 var obj = {}; function f(o) { o = []; } f(obj); console.log(obj); //{} 没有修改 调用函数传参时,函数接受对象实参引用的副本(既不是按值传递的对象副本,也不是按引用传递的隐式引用)。 它和按引用传递的不一样在于:在共享传递中对函数形参的赋值,不会影响实参的值。以下面例子中,不能够经过修改形参o的值,来修改obj的值。 也就是说不能够改变引用类型的指针,只能够改变这个对象的属性
concat()拼接数组,参数是任意个值或者数组,返回新数组,不影响原数组 join()将数组的值用指定分隔符转成字符串,不传参默认为逗号,返回新值,不影响原值 pop()删除并返回数组最后一个元素 push()向数组末尾添加一个或多个元素,返回数组新长度 shift()删除并返回数组第一个元素 unshift()想数组开头添加一个或多个元素,返回数组新长度 slice(start,end)包含头不包含尾,返回新值对原值没有影响 splice(index,howmany,item1...,itemX) 可用于替换,删除,添加; howmany表示要删除的个数,返回被删除的值组成的数组,原数组被修改 sort()对数组元素排序,修改原值 reverse()点到数组中元素的顺序,修改原值 every()是对数组中的每一项运行给定函数,若是每一项都返回true,则返回true some()是对数组中的每一项运行给定函数,若是对任一项返回true,则返回true filter()是对数组中的每一项运行给定函数,返回该函数返回true的项组成数组 map()是对数组中的每一项运行给定函数,返回每次函数调用的结果组成数组 reduce()从数组元素中计算出一个值 arr.indexOf('')查找数组,判断数组中是否含有某一项
三个字符方法: charAt()返回给定位置的字符 charCodeAt()返回给定位置的字符编码 str[index]直接用方括号加索引也能返回指定位置的字符,IE7及更早版本不支持 操做字符串方法: concat()用于拼接字符串,可传任意个参数 slice(start,end)包含头不包含尾,返回新值对原值没有影响 substring(start,end)包含头不包含尾,返回新值对原值没有影响 substr(start,num)第二个参数为个数,返回新值对原值没有影响 字符串位置方法: indexOf()从前日后找、lastIndexOf()从后往前找 大小写: toLowerCase()、toLocaleLowerCase()、toUpperCase()、toLocaleUpperCase() 都是返回新值对原值没有影响 字符串的模式匹配方法: match()参数为正则表达式或者RegExp对象,返回匹配的数组 search()返回字符串中第一个匹配项的索引,若是没找到就返回-1 replace(egexp/substr, replacement/function),返回新值对原值没有影响 split()基于分隔符分割字符串,返回新数组对原值没有影响 trim()删除字符串先后全部空格,返回新值对原值没有影响
格式:/正则表达式主体/修饰符(可选) \d: 0-9任意一个数字 \w: 数字、字母、下划线 0-9 a-z A-Z _ \s: 空格或者空白 (): 分组 [a-z]: 区间内任意一个 *: 0到多个 +: 1到多个 {n}: 正好n次 {n,m}: n-m次 好比手机:/1[34578]\d{9}/
全局做用域、函数做用域 ES6引入let和const关键字,随即带来块级做用域的概念
对象有一个内部属性[[Scope]],该属性包含了函数被建立的做用域中对象的集合,这个集合被称为函数的做用域链。 js解析某个变量时,会从代码嵌套的最内层开始,若是没找到,会顺着做用域链向上查找。
函数内部返回一个函数 对外部暴露指定行为,但仍是能用到本身做用域内的变量 function greet(){ name = 'Alan'; return function() { console.log('Hi ' + name); } } greet()(); 私有做用域 (function () { // private scope )() 模块模式 var Module = (function () { function _privateMethod() {} return { publicMethod: function() { // can call privateMethod(); } } })()
构造函数的prototype指向一个原型对象, 原型对象的constructor指回构造函数, 实例的内部指针__proto__指向原型对象。 经过调用构造函数产生的实例,都有一个内部属性,指向了原型对象。因此实例可以访问原型对象上的全部属性和方法 例子: function Dog (name) { this.name = name; } Dog.prototype.speak = function () { alert('wang'); } var doggie = new Dog('jiwawa'); doggie.speak(); //wang Dog.prototype.constructor == Dog //true
graph LR C[实例] --> B A[构造函数Dog] --> B[Dog的原型对象] B --> A
//定义一个 Animal 构造函数,做为 Dog 的父类 function Animal () { this.superType = 'Animal'; } Animal.prototype.superSpeak = function () { alert(this.superType); } function Dog (name) { this.name = name; } //改变Dog的prototype指针,指向一个 Animal 实例 Dog.prototype = new Animal(); Dog.prototype.speak = function () { alert(this.type); } var doggie = new Dog('jiwawa'); doggie.superSpeak(); //Animal 若是将Dog的prototype指针指向另外一个Animal的实例,那么Dog的实例就能调用Animal的属性和方法。
规律一:函数名加圆括号直接调用,函数上下文是 window 对象。 规律二:函数若是做为一个对象的方法,对象使用点方法进行调用,那么函数的上下文就是这个对象。 规律三:函数是事件处理函数,那么函数的上下文就是触发这个事件的对象。 规律四:函数被定时器调用时,上下文是 window 对象。 规律五:数组中存放的函数,被数组索引调用,函数上下文就是这个数组。
JS单线程(主线程) ↓ 单线程致使任务须要排队,若是前一个任务耗时很长,后面的就一直等着。 若是排队是由于计算了大,CPU忙不过来,倒也算了。 不少时候没事由于IO设备慢(好比Ajax操做从网络读取数据) ↓ 同步任务和异步任务 同步:在主线程上排队执行的任务,前一个完成,才执行后一个。 异步:不进入主线程,而进入“任务队列”,只有“任务队列”通知主线程,某个异步任务能够执行了,该任务才会进入主线程执行。 只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。这个过程会不断重复 ↓ "任务队列"是一个事件(消息)的队列,IO设备完成一项任务,就在"任务队列"中添加一个事件,表示相关的异步任务能够进入"执行栈"了。主线程读取"任务队列",就是读取里面有哪些事件。 "任务队列"中的事件,除了IO设备的事件之外,还包括一些用户产生的事件(好比鼠标点击、页面滚动等等)。只要指定过回调函数,这些事件发生时就会进入"任务队列",等待主线程读取。 所谓"回调函数"(callback),就是那些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。 主线程的读取过程基本上是自动的,只要执行栈一清空,"任务队列"上第一位的事件就自动进入主线程。可是,因为"定时器"功能,主线程首先要检查一下执行时间,某些事件只有到了规定的时间,才能返回主线程。 ↓ 主线程从"任务队列"中读取事件,这个过程是循环不断的,因此整个的这种运行机制又称为Event Loop(事件循环)。 执行栈中的代码(同步任务),老是在读取"任务队列"(异步任务)以前执行。
Ajax 是一种在无需从新加载整个网页的状况下,可以更新部分网页的技术。 var xmlHttp; if (window.XMLHttpRequest) {// IE7及以上 xmlHttp = new XMLHttpRequest(); } else { xmlHttp = new ActiveXObject('Microsoft.XMLHTTP'); } xmlHttp.open('GET/POST', url, true/false); // 若是是post,须要设置请求头 xmlHttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xmlHttp.send(); // 若是是post,须要传参数,参数为空就传null; xmlHttp.onreadystatechagne = function() { if (xmlHttp.readyState == 4) { if (xmlHttp.status >= 200 && xmlHttp.status < 300 || xmlHttp.status == 304) { // 成功回调函数... } else { // 失败回调函数... } } }; 相关知识点: GET 更简单更快,没法发送大数据,没法缓存 POST 更大更稳定,可发大数据,可缓存 readyState(0: 请求未初始化 1: 服务器链接已创建 2: 请求已接收 3: 请求处理中 4: 请求已完成,且响应已就绪) status(1字头:消息,表明请求已被接受,须要继续处理; 2字头:成功; 3字头:重定向; 4字头:请求错误; 五、6字头:服务器错误) 常见:200成功、304缓存、404未找到页面、500服务器错误
普通使用: import axios from 'axios' axios.get/post(url, params).then(function(){}).catch(function(){}) 自定义axios常见使用方式: let myAxios = axios.create({ baseURL: '', timeout: 30000, headers: {}, ... }) // 请求拦截器 myAxios.interceptors.request.use( function (config) { // 发送请求以前作些什么,好比token if (store.state.Token) { config.headers.Authorization = '前缀' + store.state.Token } reutrn config }, function (error) { // 对请求错误,作些什么 return Promise.reject(error) } ) // 响应拦截器 myAxios.interceptors.response.use( function (response) { // 对响应数据作点什么 return response.data }, function (error) { // 对响应错误作点什么, 好比后台返回token失效的状态码,就须要跳转login if (error && error.response) { switch (error.response.status) { case 400: error.message = '请求出错' break case 401: alert('token失效,从新登陆') store.commit('loginOut') setTimeout(() => { window.location.reload() }, 1000) return } } else { error.message = '链接服务器失败' } alert(error.message) return Promise.reject(error.response) } )
Trident(IE)、Gecko9(火狐)、Blink(Chrome、Opera)、Webkit(Safari)html
HTML解释器 CSS解释器 图层布局计算模块:布局计算每一个对象的精确位置和大小 视图绘制模块:进行具体节点的图像绘制,将像素渲染到屏幕上 JavaScript引擎:编译执行JS代码
运行机制: 浏览器使用http/https向服务的请求页面 ↓ 解析HTML,构建DOM树 ↓ 计算DOM树上的CSS ↓ (排版)根据CSS属性渲染元素,获得内存中的位图 ↓ (可选步骤)对位图进行合成,提高后续绘制速度 ↓ 绘制到界面上
解析HTML,生成DOM树(DOM) 解析CSS,生成CSSOM树(CSSOM) 将DOM和CSSOM合并,生成渲染树(Render-Tree) 计算渲染树的布局(Layout) 将布局渲染到屏幕上(Paint)
JavaScript分三个部分: ECMAScript标准 --- 基本语法 DOM --- 文档对象模型,操做页面元素的 BOM --- 浏览器对象模型,操做浏览器的 浏览器顶级对象: window 页面顶级对象: document 页面中全部内容都属于浏览器
BOM是独立于内容的、能够与浏览器窗口进行互动的对象结构,其由多个对象组成,其中表明浏览器窗口的Window对象是其顶层对象。 可刷新浏览器、后退、前进、在浏览器中输入URL等。 alert()、prompt()、confirm() onload()、onunload() setTimeout()、clearTimeout()、setInterval()、clearInterval() loaction、history、navigator
document. getElementById() getElementsByTagName() getElementsByName() getElementsByClassName() querySelector() createElement() appendChild()
addEventListener("事件名","事件处理函数","布尔值false冒泡,true捕获") removeEventListener("事件名","事件处理函数","布尔值") preventDefault()阻止默认事件 stopPropagation()阻止事件冒泡 其余经常使用事件: onclick、ondbclick、 onmousedown、onmouseup、onmouseout、onmousemove、onmouseover
原理:利用事件冒泡,只指定一个事件处理程序,就能够管理某一类型的全部事件 window.onload = function(){ var oUl = document.getElementById("ul1"); oUl.onclick = function(ev){ var ev = ev || window.event; var target = ev.target || ev.srcElement; if(target.nodeName.toLowerCase() == 'li'){ alert(target.innerHTML); } } }
强缓存:用户发送的请求,直接从客户端缓存中获取,不发送请求到服务器,不与服务器发生交互行为。 协商缓存:用户发送的请求,发送到服务器后,由服务器断定是否从缓存中获取资源。 二者共同点:客户端得到的数据最后都是从客户端缓存中得到。 二者的区别:从名字就能够看出,强缓存不与服务器交互,而协商缓存则须要与服务器交互。
为何会跨域:浏览器的同源策略(阻止不一样协议或者域名或者端口的请求) 解决方法: JSONP(只能发GET请求) 空iframe加form CORS(跨域资源共享):响应头设置Access-Control-Allow-Origin等... 代理 ...
HTTP(Hyper Text Transfer Protocol)超文本传输协议: 基于TCP/IP通讯协议传递数据,用于从万维网服务器传输超文本到本地浏览器的传送协议 主要特色: 简单快速、灵活、无链接(完成请求就断开连接)、无状态、支持B/S C/S
HTTP使用统一资源标识符URI来传输数据和创建链接,统一资源定位符URL是URI的一种特殊类型 URL:协议+域名+端口+虚拟目录+文件名+锚(#)+参数(?)
请求行(请求方法 URL 协议版本) 请求头(头部字段名 值...) 空行(必定有一个空行)请求数据 请求数据
状态行(协议版本 状态码 状态消息) 消息报头 空行 响应正文(服务器返回给客户端的文本信息)
1xx:指示信息--表示请求已接收,继续处理 2xx:成功--表示请求已被成功接收、理解、接受 3xx:重定向--要完成请求必须进行更进一步的操做 4xx:客户端错误--请求有语法错误或请求没法实现 5xx:服务器端错误--服务器未能实现合法的请求 常见: 200 OK:客户端请求成功 400 Bad Request:客户端请求有语法错误,不能被服务器所理解 401 Unauthorized:请求未经受权,这个状态代码必须和WWW-Authenticate报头域一块儿使用 403 Forbidden:服务器收到请求,可是拒绝提供服务 404 Not Found:请求资源不存在,eg:输入了错误的URL 500 Internal Server Error:服务器发生不可预期的错误 503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常
GET、HEAD、POST、PUT、DELETE、CONNECT、OPTIONS、TRACE
创建TCP链接(三次握手),客户端链接服务器 ↓ 发送HTTP请求 ↓ 服务器接受请求,返回HTTP响应 ↓ 释放TCP链接 ↓ 浏览器解析HTML内容
GET: 请求数据附在URL后,地址栏可见 POST: 请求数据包在请求体中 GET: 长度有限(2083字节) POST: 理论上不限制大小,服务器常会对POST数据大小进行限制 GET: 数据明文,不安全 POST: 安全
客户端缓存技术 浏览器的一种数据存储功能,由服务器生成,发送给浏览器,以键值方式存储,下次请求,会把cookie发送给服务器,过时时长由expire决定
会话缓存技术 相似客户端的身份标识,由服务器生成,保存在服务器端,以键值方式存储,默认30分钟过时 客户端每次像服务器发送请求,都带上身份标识,服务器就知道请求来自谁。客户端经常使用cookie方式保存标识
用户登陆成功,服务器生成Token返回给客户端 客户端保存Token 客户端每次请求携带Token 服务器校验Token
生命周期永久,除非手动清楚,存放大小通常5MB,存在客户端
当前会话有效,关闭浏览器清楚,存放大小5MBD,存在客户端
变量名不自动提示,提供块级做用域
() => {} 箭头函数中没有this,若是在箭头函数内使用this,该this是外层的this
使用``将字符串包裹,在其中可使用${}来包裹一个变量或表达式
数组以序列号对应,对象根据属性名对应 eg: // es5 var loading = props.loading; var clicked = props.clicked; // es6 const { loading, clicked } = props; // es6 const arr = [1, 2, 3]; const [a, b, c] = arr; // es5 var arr = [1, 2, 3]; var a = arr[0]; var b = arr[1]; var c = arr[2];
// es5 function add(x, y) { var x = x || 20; var y = y || 30; return x + y; } console.log(add()); // es6 function add(x = 20, y = 30) { return x + y; } console.log(add());
使用...能够将数组或者对象进行展开 const arr1 = [1, 2, 3]; const arr2 = [...arr1, 10, 20, 30]; // 这样,arr2 就变成了[1, 2, 3, 10, 20, 30]; const obj1 = { a: 1, b: 2, c: 3 } const obj2 = { ...obj1, d: 4, e: 5, f: 6 } // 结果相似于 const obj2 = Object.assign({}, obj1, {d: 4})
当属性与值同名时,可简写 const person = { name, age } // ES5 // 构造函数 function Person(name, age) { this.name = name; this.age = age; } // 原型方法 Person.prototype.getName = function() { return this.name } // ES6 class Person { constructor(name, age) { // 构造函数 this.name = name; this.age = age; } getName() { // 原型方法 return this.name } } extends继承关键字、super()
解决异步回调地狱问题 promise.then(function(value) { // success 成功回调 }, function(error) { // failure 失败回调 }); then方法返回一个新的Promise实例,所以支持链式写法,后面的then会等待前面then返回的Promise对象状态发生变化,而后决定调用resolve仍是reject。 .catch() .finally() ES2018引入, 无论promise最后状态,都会执行 .all()将多个Promise实例包装成一个新的Promise实例,只有子实例状态都变为fulfilled,包装实例才变为fulfilled,若是其中一个是rejected,那么包装也是rejected。 .race()同all()方法,至关于或操做,只要有一个实例状态改变,包装实例就会跟着改变 .resolve()将现有对象转为Promise对象 .reject()返回一个状态为rejected的Promise实例
Set相似于数组,但其成员的值都是惟一的,没有重复的值 const s = new Set() const s1 = new Set([1,2,3,2,3]) [...s] add(value):添加某个值,返回 Set 结构自己。 delete(value):删除某个值,返回一个布尔值,表示删除是否成功。 has(value):返回一个布尔值,表示该值是否为Set的成员。 clear():清除全部成员,没有返回值。
相似于对象,也是键值对的集合,可是键不限于字符串,各类类型均可以看成键。 const map = new Map() map.set(键,值) map.get(键) map.has(键) map.delete(键) map.clear() map.size 遍历Set和Map: keys():返回键名的遍历器。 values():返回键值的遍历器。 entries():返回全部成员的遍历器。 forEach():遍历 Map 的全部成员 因为 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),因此keys方法和values方法的行为彻底一致
在目标对象以前架设一层“拦截”,外界访问该对象,都必须先经过这层拦截 var proxy = new Proxy(target, handler) eg: var obj = new Proxy({}, { get: function (target, key, receiver) { console.log(`getting ${key}!`); return Reflect.get(target, key, receiver); }, set: function (target, key, value, receiver) { console.log(`setting ${key}!`); return Reflect.set(target, key, value, receiver); } }); get(target, propKey, receiver): 拦截对象属性的读取,好比proxy.foo和proxy['foo']。 set(target, propKey, value, receiver): 拦截对象属性的设置,好比proxy.foo =v或proxy['foo']=v,返回一个布尔值。 has(target, propKey): 拦截propKey in proxy的操做,返回一个布尔值 ...
Iterator做用: 1. 为各类数据结构,提供一个统一的访问接口 2. 使数据结构的成员可以按某种次序排列 3. 创造了一种新的遍历命令for...of 遍历器原理:建立一个指针指向数据结构(Array/Set/Map/String/TypedArry/arguments/NodeList)的初始位置, 第一次调用指针对象的next方法,将指针指向第一个成员,第二次next指向第二个,以此类推,直到结束位置。 for(let val of 数据结构){}
export与export default都可用于导出常量、函数、文件、模块等 在一个文件或模块中,export、import能够有多个,export default仅有一个 经过export方式导出,在导入时要加{ },export default则不须要 export能直接导出变量表达式,export default不行
v-text:绑定元素的文本内容 <span v-text="txt"></span> v-html:绑定元素的innerHTML <div v-html="html"></div> v-show:显示与隐藏,切换元素的display CSS属性 v-if:Dom元素的销毁和重建 v-for v-on:绑定事件监听器,缩写@;使用:v-on:click="handleClick()" 修饰符: .stop - 调用 event.stopPropagation()。 .prevent - 调用 event.preventDefault()。 .capture - 添加事件侦听器时使用 capture 模式。 .self - 只当事件是从侦听器绑定的元素自己触发时才触发回调。 .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。好比 @click.enter="handleEnter" .native - 监听组件根元素的原生事件。 .once - 只触发一次回调。 .left - (2.2.0) 只当点击鼠标左键时触发。 .right - (2.2.0) 只当点击鼠标右键时触发。 .middle - (2.2.0) 只当点击鼠标中键时触发。 .passive - (2.3.0) 以 { passive: true } 模式添加侦听器 v-bind:动态绑定一个或多个特性或组件prop到表达式,缩写":"; 好比 :class="{}" 修饰符: .prop - 被用于绑定 DOM 属性 (property)。(差异在哪里?) .camel - (2.1.0+) 将 kebab-case 特性名转换为 camelCase. (从 2.1.0 开始支持) .sync (2.3.0+) 语法糖,会扩展成一个更新父组件绑定值的 v-on 侦听器。 v-model:数据双向绑定 修饰符: .lazy - 取代 input 监听 change 事件 .number - 输入字符串转为有效的数字 .trim - 输入首尾空格过滤 v-slot:用于<template>,缩写# v-pre:跳过这个元素和其子元素的编译过程 v-cloak:与CSS规则[v-cloak]{display:none}一块儿使用 v-once:只渲染元素和组件一次。<span v-once>This will never change: {{msg}}</span>
经常使用: vm.$refs:返回Object,获取注册过ref特性的全部DOM元素和组件实例 其余: vm.$data:Object,访问Vue实例的data属性 vm.$props:Object,访问Vue实例的props属性 vm.$el:Element,当前组件的根DOM元素 vm.$options:Object,访问Vue的初始化选项 vm.$parent:获取父实例 vm.$root:当前组件树的根实例 vm.$children vm.$slots:访问具名插槽的内容 vm.$scopedSlots:访问做用域插槽的内容 vm.$isServer vm.$attrs vm.$listeners
经常使用: vm.$emit(eventName,[...args]):触发当前实例上的事件,经常使用于父子组件通讯 vm.$watch:观察 Vue 实例变化的一个表达式或计算属性函数 vm.$watch('a.b.c', function (newVal, oldVal) { // 作点什么 }) vm.$set(target,key,value) 其余: vm.$delete(target,key) vm.$on(event,callback):监听当前实例上的自定义事件 vm.$once(event,callback):监听自定义事件,只触发一次,触发后自动移除监听器 vm.$off([event,callback]):移除自定义事件 vm.$mount([elementOrSelector]):可用于给vue实例手动挂载dom元素 vm.$forceUpdate():迫使vue实例从新渲染 vm.$nextTick([callback]):将回调延迟到下次DOM更新循环以后执行。在修改数据以后当即使用它,而后等待 DOM 更新 vm.$destory():彻底销毁一个实例。清理它与其它实例的链接,解绑它的所有指令及事件监听器
beforeCreate 实例初始化以后调用 created 实例建立完成后被当即调用 beforeMount 挂载开始以前被调用 mounted 挂载到实例上去以后调用该钩子 beforeUpdate 数据更新时调用,发生在虚拟 DOM 打补丁以前 updated 因为数据更改致使的虚拟DOM从新渲染和打补丁,在这以后会调用该钩子 activated keep-alive组件激活时调用 deactivated keep-alive组件停用时调用 beforeDestory 实例销毁以前调用 destoryed 实例销毁后调用 errorCaptured 当捕获一个来自子孙组件的错误时被调用
全局注册: Vue.component('name', { data () { return { ... } }, template: `<button>BTN</button>` ... }) 局部注册: var componentA = {} var componentB = {} var componentC = {} new Vue({ el: '#app', components: { componentA, componentB } })
父给子传值: 直接以属性的方式,若是是动态值能够用v-bind,子组件经过props接受值 子给父传值: 经过自定义事件。 子组件经过$emit('faterEvent', ...params)触发父组件的自定义事件,父组件自定义事件触发一个自定义方法,其参数就是子组件传过来的值。
可借助同一个父组件通讯
vuex
定义: <slot name="header"></slot> 调用: <template v-slot:header> <h1>Here might be a page title</h1> </template>
让插槽内容可以访问子组件中才有的数据 定义: <span> <slot v-bind:user="user"> {{ user.lastName }} </slot> </span> 调用: <current-user> <template v-slot:default="slotProps"> {{ slotProps.user.firstName }} </template> </current-user>
HTML: 入口(声明式): <router-link to="/index"></router-link> 出口: <router-view></router-view> JavaScript: import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) // 定义路由 const routes=[ {path: '/index', component: ()=>require('../index')} ] // 建立router实例并配置路由 const router = new Router({ routes }) // 根实例配置router const app = new Vue({ router })
能够在任何组件内经过this.$router访问路由器,经过this.$route访问当前路由。
eg: 将不一样id的用户都指向User组件 const router = new Router({ routes: [ // 动态路径参数,以冒号开头 {path: '/user/:id', component: User} ] }) 屡次路由若是渲染同个组件,组件会被复用,因此生命周期钩子不会再调用,可使用watch监听$route对象。 watch: { '$route': (to, from) {} }
通配符(*): path: '*' path: 'user-*' 若是使用通配符,$route.params会自动添加一个名为pathMatch参数 // 给出一个路由 { path: '/user-*' } this.$router.push('/user-admin') this.$route.params.pathMatch // 'admin' // 给出一个路由 { path: '*' } this.$router.push('/non-existing') this.$route.params.pathMatch // '/non-existing'
Vue实例内部使用this.$router访问 router.push(location, onComplete?, onAbort?) eg: // 字符串 router.push('home') // 对象 router.push({ path: 'home' }) // 命名的路由,若是提供了path,params会被忽略 router.push({ name: 'user', params: { userId: '123' }}) // 带查询参数,变成 /register?plan=private router.push({ path: 'register', query: { plan: 'private' }}) router.replace(location, onComplete?, onAbort?) router.go(n): 向前或后退多少步
全局前置守卫: const router = new Router({ ... }) router.beforeEach((to, from, next) => { // 确保调用next方法,不然钩子不会被resolved // next() 进行下一个钩子 // next(false) 中断当前的导航 // next('/')或者next({path: '/'}) 中断当前导航,跳转到新导航 // next(error) 终止导航,并触发router.onError()的回调 }) 全局解析守卫: router.beforeResolve与上面的前置守卫相似 区别是在导航被确认以前,同时在全部组件内守卫和异步路由组件被解析以后,解析守卫就被调用 全局后置钩子: router.afterEach((to, from) => {}) 路由独享的守卫: const router = new Router({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => {} } ] }) 组件内的守卫: export default { name: 'Foo', beforeRouteEnter(to, from, next) { // 在渲染该组件的对应路由被 confirm 前调用 // 不!能!获取组件实例 `this` // 由于当守卫执行前,组件实例还没被建立 // 能够经过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,而且把组件实例做为回调方法的参数 next(vm => { // 经过 `vm` 访问组件实例 }) }, beforeRouteUpdate (to, from, next) { // 在当前路由改变,可是该组件被复用时调用 // 举例来讲,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候, // 因为会渲染一样的 Foo 组件,所以组件实例会被复用。而这个钩子就会在这个状况下被调用。 // 能够访问组件实例 `this` }, beforeRouteLeave (to, from, next) { // 导航离开该组件的对应路由时调用 // 能够访问组件实例 `this` } }
meta: { requiresAuth: true } 访问元信息: 路由是能够嵌套的,所以一个路由匹配成功后,可能匹配多个路由记录 $route.matched数组 router.beforeEach((to, from, next) => { if (to.matched.some(record => record.meta.requiresAuth)) { if (!auth.loggedIn()) { next({ path: '/login', query: { redirect: to.fullPath } }) } else { next() } } else { next() // 确保必定要调用 next() } })
const router = new Router({ routes: [...], scrollBehavior (to, from, savedPosition) { // return 指望滚动到哪一个的位置 return { x: 0, y: 0 } } })
const Home = () => import('@/pages/home/Home') (resolve) => require(['pages/marketing-center/mission-medal/mission-rules/mission-rules'], resolve)
State、Getter、Mutation、Action、Modulevue
为何要用vuex: 当多个组件共享状态时(多个视图依赖同一状态,不一样视图的行为须要变动同一状态) vuex和单纯的全局对象有两点不一样: 1.vuex的存储是响应式的,当vue组件从store中读取状态时,若store中的状态发生变化,那么相应的组件也会获得高效更新。 2.不能直接改变store中的状态。改变状态的惟一途径就是显示提交mutation。 const store = new Vuex.Store({ state: { count: 0 }, mutation: { increment(state) { state.count++ } } }) const app = new Vue({ el: '#app', store }) this.$store.state.count this.$store.commit('increment')
import { mapState } from 'vuex' export default { computed: { ...mapState(['count']) } }
就像计算属性同样,getter的返回值会根据它的依赖被缓存起来,且只有当依赖值发生了改变才会被从新计算。 const store = new Vuex.Store({ state: { todos: [ { id: 1, text: '...', done: true }, { id: 2, text: '...', done: false } ] }, getters: { doneTodos: state => { return state.todos.filter(todo => todo.done) } } }) 经过属性访问: this.$store.getters.doneTodos 经过方法访问: 定义时返回一个函数: getters: { getTodoById: (state) => (id) => { return state.todos.find(todo => todo.id === id) } } 访问时能够传参数查询: this.$store.getters.getTodoById(2)
更改vuex的store中状态的惟一方法是提交mutation mutation必须是同步函数 const store = new Vuex.Store({ state: { count: 1 }, mutations: { increment (state) { state.count++ } } }) this.$store.commit('increment') 或者 methods: { ...mapMutations([ // 将 `this.increment()` 映射为 `this.$store.commit('increment')` 'increment' ]) }
Action相似于mutation,不一样在于: Action提交的是mutation,而不是直接变动状态 Action能够包含任意异步操做 const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } }, actions: { increment (context) { // 能够异步操做 setTimeout(() => { context.commit('increment') }, 1000) } } }) 分发Action: this.$store.dispatch('increment') 或者 methods: { ...mapActions(['increment']) }
因为使用单一状态树,当应用变得复杂时,store对象会很是臃肿。 所以,vuex容许咱们将store分割成模块(module),每一个模块拥有本身的state、mutation、action、getter、以及嵌套子模块。 const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } } const moduleB = { state: { ... }, mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) this.$store.state.a // -> moduleA 的状态 this.$store.state.b // -> moduleB 的状态
var fs = require('fs') fs.readFile('文件名', 'utf-8', function(err, data){}) fs.readFileSync('文件名', 'utf-8') fs.writeFile('输出文件名', data, function(err){}) fs.writeFile('输出文件名', data) fs.stat('文件名', function(err, stat){ if (err) { } else { // 是不是文件: console.log('isFile: ' + stat.isFile()); // 是不是目录: console.log('isDirectory: ' + stat.isDirectory()); if (stat.isFile()) { // 文件大小: console.log('size: ' + stat.size); // 建立时间, Date对象: console.log('birth time: ' + stat.birthtime); // 修改时间, Date对象: console.log('modified time: ' + stat.mtime); } } })
var fs = require('fs') // 打开一个流 var rs = fs.createReadStream('文件名', 'uft-8') rs.on('data', function(chunk){}) // data可能有屡次,每次传递的chunk是流的一部分 rs.on('end', function(){}) rs.on('error', function(err){}) // 用流写入文件 var ws = fs.createWriteStream('输出文件名', 'utf-8') ws.write('文本数据。。。') ws.write(newBuffer('用流写二进制数据', 'utf-8') ws.end() // 用流复制 var rs = fs.createReadStream('sample.txt'); var ws = fs.createWriteStream('copied.txt'); rs.pipe(ws);
var http = require('http'); // 建立http server,并传入回调函数: var server = http.createServer(function (request, response) { // 回调函数接收request和response对象, // 得到HTTP请求的method和url: console.log(request.method + ': ' + request.url); // 将HTTP响应200写入response, 同时设置Content-Type: text/html: response.writeHead(200, {'Content-Type': 'text/html'}); // 将HTTP响应的HTML内容写入response: response.end('<h1>Hello world!</h1>'); }); // 让服务器监听8080端口: server.listen(8080);
对http有封装,使用Promise并配合async来实现异步。 // 导入koa,和koa 1.x不一样,在koa2中,咱们导入的是一个class,所以用大写的Koa表示: const Koa = require('koa'); // 建立一个Koa对象表示web app自己: const app = new Koa() // 对于任何请求,app将调用该异步函数处理请求: app.use(async (ctx, next) => { await next(); ctx.response.type = 'text/html'; ctx.response.body = '<h1>Hello, koa2!</h1>'; }); // 在端口3000监听: app.listen(3000);
const Koa = require('koa'); // 注意require('koa-router')返回的是函数: const router = require('koa-router')(); const app = new Koa(); // log request URL: app.use(async (ctx, next) => { console.log(`Process ${ctx.request.method} ${ctx.request.url}...`); await next(); }); // add url-route: router.get('/hello/:name', async (ctx, next) => { var name = ctx.params.name; ctx.response.body = `<h1>Hello, ${name}!</h1>`; }); router.get('/', async (ctx, next) => { ctx.response.body = '<h1>Index</h1>'; }); // add router middleware: app.use(router.routes()); app.listen(3000); console.log('app started at port 3000...');
const Koa = require('koa'); const app = new Koa(); const bodyParser = require('koa-bodyparser'); app.use(bodyParser());
//引入数据库 var mysql=require('mysql'); //实现本地连接 var connection = mysql.createConnection({ host: 'localhost', user: 'user', password: '123456', database: 'test' }) connection.query('SELECT * FROM users WHERE id = ?', ['123'], function(err, rows) {}); connection.query("INSERT INTO demo SET ?", post, function (error, results, fields) {}) ...
const Sequelize = require('sequelize'); // 链接数据库 let sequelize = new Sequelize(config.database, config.username, config.password, { host: config.host, dialect: config.dialect, pool: config.pool }); sequelize.define(tableName, attrs, { tableName, timestamps: false, freezeTableName: true, // 钩子函数,统一设置id、createdAt等这些基础字段的值 hooks: { beforeValidate: function (obj) { let now = Date.now(); if (obj.isNewRecord) { if (!obj.id) { obj.id = generateId(); } obj.createdAt = now; obj.updatedAt = now; obj.version = 0; obj.isDelete = false; } else { obj.updatedAt = Date.now(); obj.version++; } } } });