笔记-前端基础01

前端开发
一、html、html5

1. src与href区别

  • src是source的缩写,表示对资源的引用,它指向的内容会嵌入到当前标签所在的位置。由于src的内容是页面必不可少的一部分,因此浏览器在解析src时会停下来对后续文档的处理,直到src的内容加载完毕。常用在script、img、iframe标签中
<img src="img/girl.jpg">
<frame src="top.html">
<iframe src="top.html">
<script src="show.js">

注释:建议js文件放在HTML文档的最后面。如果js文件放在了head标签中,可以使用window.onload实现js的最后加载。

  • href是Hypertext Reference的缩写,超文本引用,它指向一些网络资源,建立和当前元素或者说是本文档的链接关系。在加载它的时候,不会停止对当前文档的处理,浏览器会继续往下走。常用在a、link等标签。
<a href="http://www.baidu.com"></a>
<link type="text/css" rel="stylesheet" href="common.css">

注释:当浏览器加载到link标签时,会识别这是CSS文档,并行下载该CSS文档,但并不会停止对当前页面后续内容的加载。这也是不建议使用@import加载CSS的原因。

2.html5的文档类型和字符集

<!doctype html> DOCTYPE用来规范浏览器的行为(让浏览器按照他们应该的方式来解读运行)
<meta charset="UTF-8">

3.html5新元素和移除的元素

新增加:
 <canvas><audio><video><source><article><aside><footer><header><nav><section>等
移除:
 <big><frame><font><center><frameset>

4. html5的web 存储
一个比cookie更好的本地存储方式,提供相应API
localStorage - 用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去除。
sessionStorage - 用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。

不管是 localStorage,还是 sessionStorage,可使用的API都相同,常用的有如下几个(以localStorage为例
    保存数据:localStorage.setItem(key,value);
    读取数据:localStorage.getItem(key);
    删除单个数据:localStorage.removeItem(key);
    删除所有数据:localStorage.clear();
    得到某个索引的key:localStorage.key(index);

5.HTML5 标准提供了新的 API

媒体API、文本轨道API、应用程序缓存API、用户交互、数据传输API、命令API、约束验证API、历史API

6.HTML5 应用程序缓存和浏览器缓存区别

借助manifest 文件可以实现应用程序缓存,提供了离线使用的功能,让应用程序可以获取本地的网站内容,
例如 HTML、CSS、图片以及 JavaScript,可以在没有因特网连接时进行访问,

7.浏览器常见的兼容性问题

1)png24位的图片在IE6浏览器上出现背景;
解决方法:做成PNG8;
2)浏览器默认的 margin 和 padding 不同。
解决方法:加一个全局的*{margin:0;padding:0;}来统一。
3)IE6双边距bug:块属性标签float后,又有横向的 margin 情况下,在 IE6 显示 margin 比设置的大。浮动IE产生的双倍距离 
#box{float:left;width:10px;margin:0 0 0 100px;} 这种情况下IE6会产生200px的距离。
解决方法:加上_display:inline,使浮动忽略
4)IE下,可以使用获取常规属性的方法来获取自定义属性,也可以使用getAttribute()获取自定义属性; Firefox下,只能使用getAttribute()获取自定义属性。
解决方法:统一通过getAttribute()获取自定义属性。
5)IE下,even对象有x,y属性,但是没有pageX,pageY属性;
解决方法:(条件注释)缺点是在IE浏览器下可能会增加额外的HTTP请求数。
6)Chrome中文界面下默认会将小于 12px 的文本强制按照 12px 显示
解决方法:可通过加入 CSS 属性 -webkt-text-size-adjust:none;解决
7)超链接访问过后 hover 样式就不出现了,被点击访问过的超链接样式不在具有 hover 和 active ;
解决方法:改变CSS属性的排列顺序:L-V-H-A: a:link{ }  a:visited{ } a:hover{ } a:active{ } 

8.html语义化的理解
平时,我们都会采用DIV+CSS布局我们的页面。但是这样的布局方式不仅使我们的文档结构不够清晰,而且不利于浏览器对页面的读取。所以HTML5新增了很多新的语义化标签。并且,在我们未给页面添加css样式时,用户体验并不好。语义化标签也能让浏览器更好的读取页面结构。再就是便于团队开发和维护,语义化更具可读性,遵循W3C标准的团队都遵循这个标准,可以减少差异化。

常用的标签

<header></header>头部
<nav></nav>导航栏
<section></section>区块(有语义化的div)
<main></main>主要区域
<artical></artical>主要内容
<aside></aside>侧边栏
<footer></footer>底部

二、css、css3

1.盒子模型

IE: content, margin  IE 的 content 部分包含了 border 和 padding
盒模型: 内容(content)、填充(padding)、边界(margin)、边框(border)

统一兼容IE: box-sizing: border-box

2.选择器

1)id 选择器(#myid)
2)类选择器(.myclassname)
3)标签选择器(div,h1,p)
4)相邻选择器(h1 + p)//该选择器定位与元素h1具有相同父元素且在标记中紧邻h1的元兄弟素p
4)一般兄弟选择器(h1 ~ p) //该选择器定位与元素h1具有相同父元素且在标记中位于h1之后的所有元素p
5)子选择器(ul > li) //该选择器定位元素ul的直接子元素中的所有元素li,它将忽略任何进一步的嵌套:
6)后代选择器(li a)//该选择器定位元素的li后代中所有元素a:
7)通配符选择器(*8)属性选择器( a[rel = "external"]9)伪类选择器(a: hover, li: nth - child)
10)input[title^="title1"] // ^=指定属性的值以指定字符串开头 
11)input[title$="title1"] //$=指定属性的值以指定字符串结尾
12)input[title*="title1"] //*=指定属性的值包含指定字符串 1
13)input[title|="title1"] // |=指定属性的值等于title1或者以title1-开头 
14)E[attr~=val] // ~=指定属性的值有单个指定字符串

3.元素水平、垂直居中

 行内元素、行内块级元素 水平居中: 父元素:text-align:center 
 行内元素、行内块级元素 垂直居中:  父元素: line-hieght===height
 块级元素: 
 1) 已知盒子大小
    width:200px
    height: 200px
    positon:absolute
    left:50%
    top=50%
    margin-left=-width/2
    margin-top=-height/2
 2) 未知大小
    positon:absolute
    left:0;
    top=0;
    bottom:0;
    right: 0;
    transform:translateX(50%)
    transform:translateY(50%)

4.清除浮动
高度塌陷: 父元素未设置高度,子元素脱离标准文档流时
1)父盒子设置高度
2)在浮动最后元素加一个空div

<div style="clear: both;"></div>

3)添加伪类

<div class="clearfix">
	<div class="box1"></div>
	<div class="box2"></div>
</div>
<div class="footer"></div>

.box1{
	width: 120px;
	height: 120px;
	background-color: red;
	float: left;
}
.box2{
	width: 240px;
	height: 240px;
	background-color: yellow;
	float: left;
 }
.clearfix:after,.clearfix:before{
   content: "";
   display: table;
}
.clearfix:after{
   clear: both;
}
.clearfix{
   zoom: 1;
}
.footer{
	width: 900px;
	height: 100px;
	background-color: darkslateblue;
}

5.BFC
BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。
1.使 BFC 内部浮动元素不会到处乱跑;
2.和浮动元素产生边界。

一个BFC由以下之一创建

1float的值不是none。
2、position的值不是static或者relative。
3、display的值是inline-block、table-cell、flex、table-caption或者inline-flex
4、overflow的值不是visible

6.css样式三角形
border属性

<div class="box"></div>
.box{
	width: 0;
	height: 0;
	border-left: 20px solid red;
	border-bottom: 20px solid green;
	border-right: 20px solid transparent; // 透明
	border-top: 20px solid transparent;  // 透明
}

在这里插入图片描述
7.css样式

 font-family:Arial, Helvetical, sans-serif
 font-style:italic斜体, normal默认
 text-decoration:underline下划线, overline上划线,line-throgh中间线
 list-style:用于列表
 overflow:scroll滚动, auto自动, hidden隐藏
 box-sizing:border-box固定盒子大小, 向内伸缩,
 position:absolute, relative, fixed固定定位,相对于浏览器窗口定位,并且不会随滚动条滚动
             层级关系:定位元素>浮动元素>文档流元素
 background-size:cover铺满, content有留白
 background-attachement:scroll流动, fixed固定
 outline:none清除边框 

8.css3常用样式

border-radius // 圆角
box-shadow // 阴影
linear-gradient // 线性渐变
radial-gradient // 径向渐变
transform: // 变换
translate | rotate | scale | skew | matrix
元素位置移动 | 旋转角度 | 放大缩小 | 倾斜的角度 | 包含旋转,缩放,移动(平移)和倾斜功能  
transition // 过度
@keyframes // 自定义动画
 多列布局
 媒体查询

三、js
1.作用域

  • var 全局/局部作用域
for(var i = 1; i <= 3; i++){ 
	setTimeout(function(){
	console.log(i); 
	},0); 
	};
	//输出 4 4 4 
  • let 块级作用域
for(let i = 1; i <= 3; i++){ 
	setTimeout(function(){
	console.log(i); 
	},0); 
	};
	//输出 1 2 3

2.typeof返回的数据类型

Object(null, array)、Number、undefined、String、Boolean、function
 var a = [34,4,3,54],
     b = 34,
     c = 'adsfas',
     d = function(){console.log('我是函数')},
     e = true,
     f = null,
     g;
     console.log(typeof(a));//object
     console.log(typeof(b));//number
     console.log(typeof(c));//string
     console.log(typeof(d));//function
     console.log(typeof(e));//boolean
     console.log(typeof(f));//object
     console.log(typeof(g));//undefined

typeof在判断null、array、object以及函数实例(new + 函数)时,得到的都是object。这使得在判断这些数据类型的时候,得不到真是的数据类型。

  • instanceof属性 对象运算符
    instanceof运算符用于检验构造函数的prototype属性是否出现在对象的原型链中的任何位置,返回一个布尔值
let a = [];
a instanceof Array; //true
let b = {};
b instanceof Array; //false
  • constructor属性
    实例的构造函数属性constructor指向构造函数,那么通过constructor属性也可以判断是否为一个数组
let a = [1,3,4];
a.constructor === Array;//true

注释:prototype属性是可以修改的,所以并不是最初判断为true就一定永远为真,以上这两个属性都会存在多个全局环境的问题

  • Object.prototype.toString.call()
    可以获取到对象的不同类型,多个全局环境也适用
// 检验是否是数组
 let a = [1,2,3]
 Object.prototype.toString.call(a) === '[object Array]';//true
 //检验是否是函数
 let b = function () {};
 Object.prototype.toString.call(b) === '[object Function]';//true
 //检验是否是数字
 let c = 1;
 Object.prototype.toString.call(c) === '[object Number]';//true
 //检验是否是对象
 let d = {
   name: '袁冰妍'
 }
 Object.prototype.toString.call(c) === '[object Object]';//true
  • Array.isArray() ES5中提出
let a = [1,2,3]
Array.isArray(a);//true

判断数组最终方法

 function isArr(arr) {
	if (!Array.isArray) { // es5一下
	 Array.isArray = function(arr) {
	  return Object.prototype.toString.call(arr) === '[object Array]';
	 };
	} else { es5以上
	  return Array.isArray(arr)
	}
 }

3.常用数组方法

shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。
unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度
pop() 删除 arrayObject 的最后一个元素,把数组长度减 1,并且返回它删除的元素的值。如果数组已经为空,则 pop() 不改变数组,并返回 undefined 值。
push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度
splice(0, 1)删除替换
split("=")分割

4.CDN

   CDN的全称是Content Delivery Network,即内容分发网络。CDN是构建在现有网络基础之上的智能虚拟网络,
依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,
提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储和分发技术

5.SEO - 搜索引擎优化
网站搜索引擎优化任务主要是认识与了解其它搜索引擎怎样紧抓网页、怎样索引、怎样确定搜索关键词等相关技术后,以此优化本网页内容,确保其能够与用户浏览习惯相符合,并且在不影响网民体验前提下使其搜索引擎排名得以提升,进而使该网站访问量得以提升,最终提高本网站宣传能力或者销售能力的一种现代技术。基于搜索引擎优化处理,其实就是为让搜索引擎更易接受本网站,搜索引擎往往会比对不同网站的内容,再通过浏览器把内容以最完整、直接及最快的速度提供给网络用户

优化策略:

 - 主题要明确,内容要丰富
2.引出链接要人气化
3.关键词设定要突出
4.网站架构层次要清晰
5.页面容量要合理化
6.网站导航要清晰化
7.网站发布要更新

6.DOM事件原理

  • 事件监听
  var oBtn=document.getElementById('btn');
  if(oBtn.addEventListener){  
  	oBtn.addEventListener("click", function() {  //给元素添加监听事件
  		alert('赵丽颖');
  	});
  } else if(oBtn.attachEvent){
  	oBn.attachEvent('onclick', function() {
  		alert('安悦溪');
  	});
  }
  oBtn.removeEventListener //移除监听事件
  
 element.addEventListener(event, function, useCapture);
 event监听事件名 click/mouseover/mouseout/mousedown/mouseup/load/unload等事件
 function事件发生时需要调用的函数
 useCapture布尔值 ,默认false为冒泡传播, true为捕获传播
 
  • 事件触发的整个过程可分为三个阶段:
1.事件的第一个阶段是(捕获阶段)。事件从文档的根节点出发,随着DOM树的结构向事件的目标节点流去。途中经过各个层次的DOM节点,并在各节点上触发捕获事件,直到到达事件的目标节点。
2.当事件到达目标节点的,事件就进入了(目标阶段)。事件在目标节点上被触发,然后会逆向回流,直到传播至最外层的文档节点
3.最后再返回到文档的根节点(冒泡阶段)
  • 阻止事件传播
通过调用事件对象的stopPropagation方法,在任何阶段(捕获阶段或者冒泡阶段)中断事件的传播;
此后,事件不会在后面传播过程中的经过的节点上调用任何的监听函数
  • 阻止浏览器的默认行为
当特定事件发生的时候,浏览器会有一些默认的行为作为反应。
例如,使用a元素时会自动添加click事件,当a元素上click事件触发时,它会向上冒泡直到DOM结构的最外层document,
浏览器会解释href属性,并且在窗口中加载新地址的内容。
如果我们需要阻止浏览器针对点击事件的默认行为,可以调用event.preventDefault()
  • 代理事件监听(事件委托)
    所谓代理事件监听,指的是不直接在监听的目标节点上添加事件监听函数,而是通过其他的节点代为监听目标节点的事件;
如果有一个列表ul包含了10个子元素li,它们都需要对click事件做出相似的响应,那么我们可能需要查询这10个子元素,并分别为他们添加上事件监听器。这样的话,我们就会产生10个独立的事件监听器
代理事件监听可以让我们更简单的处理这种情况。我们不去监听所有的子元素的click事件,相反,我们监听他们的父元素ul。当一个li元素被点击的时候,这个事件会向上冒泡至ul,触发回调函数。我们可以通过检查事件的event.target属性来判断具体是哪一个li被点击了。
这样一来,仅仅使用了一个上层的事件监听器,并且我们不需要在为添加元素而考虑它的事件监听问题
往往使用jQuery提供的on()方法去实现事件代理

<ul>
	<li>赵丽颖</li>
	<li>袁冰妍</li>
	<li>王小儿</li>
</ul>
var lis = document.querySelectorAll('li')
var ulBtn = document.querySelector('ul')
ulBtn.addEventListener('click', function(ev){
	// console.log(ev)
	var ev = ev || window.event;
  var target = ev.target || ev.srcElement;
  if(target.nodeName.toLowerCase() == 'li'){
    console.log(target.innerHTML);
  }
})

$('ul').on('click','li',function(evt){
     var content = $(evt.target).text();
 })

7.图片懒加载
原理:先将img标签的src链接设为同一张图片(比如空白图片),然后给img标签设置自定义属性(比如 data-src),然后将真正的图片地址存储在data-src中,当JS监听到该图片元素进入可视窗口时,将自定义属性中的地址存储到src属性中。达到懒加载的效果
这样能防止页面一次性向服务器发送大量请求,导致服务器响应面,页面卡顿崩溃等

html:
<div class="container">
    <img src="https://img-blog.csdnimg.cn/2020060221453246.jpg#pic_right" alt="1" data-src="https://blog.csdn.net/qq_46346301/0.png">
    <img src="https://img-blog.csdnimg.cn/2020060221453246.jpg#pic_right" alt="1" data-src="https://blog.csdn.net/qq_46346301/1.png">
    <img src="https://img-blog.csdnimg.cn/2020060221453246.jpg#pic_right" alt="1" data-src="https://blog.csdn.net/qq_46346301/2.png">
    <img src="https://img-blog.csdnimg.cn/2020060221453246.jpg#pic_right" alt="1" data-src="https://blog.csdn.net/qq_46346301/3.png">
    <img src="https://img-blog.csdnimg.cn/2020060221453246.jpg#pic_right" alt="1" data-src="https://blog.csdn.net/qq_46346301/4.png">
    <img src="https://img-blog.csdnimg.cn/2020060221453246.jpg#pic_right" alt="1" data-src="https://blog.csdn.net/qq_46346301/5.png">
    <img src="https://img-blog.csdnimg.cn/2020060221453246.jpg#pic_right" alt="1" data-src="https://blog.csdn.net/qq_46346301/6.png">
    <img src="https://img-blog.csdnimg.cn/2020060221453246.jpg#pic_right" alt="1" data-src="https://blog.csdn.net/qq_46346301/7.png">
    <img src="https://img-blog.csdnimg.cn/2020060221453246.jpg#pic_right" alt="1" data-src="https://blog.csdn.net/qq_46346301/8.png">
</div>
js:
<script>

    // 一开始没有滚动的时候,出现在视窗中的图片也会加载
    showImg();
    // 当页面开始滚动的时候,遍历图片,如果图片出现在视窗中,就加载图片
    var clock; //函数节流
    $(window).on('scroll',function(){
        if(clock){
            clearTimeout(clock);
        }
        clock = setTimeout(function(){
            showImg()
        },200)
    })
    
    function showImg(){
      $('.container img').not('[data-isLoading]').each(function ()    {
          if (isShow($(this))) {
              loadImg($(this));
          }
      })
    }

    // 判断图片是否出现在视窗的函数
    function isShow($node){
       return $node.offset().top <= $(window).height()+$(window).scrollTop();
    }

    // 加载图片的函数,就是把自定义属性data-src 存储的真正的图片地址,赋值给src
    function loadImg($img){
       $img.attr('src', $img.attr('data-src'));
        // 已经加载的图片,我给它设置一个属性,值为1,作为标识,防止每次滚动的时候,所有的图片都会遍历一遍,这样有点浪费,所以做个标识,滚动的时候只遍历哪些还没有加载的图片
        $img.attr('data-isLoading',1);
    }
</script>

8.冒泡法
基本原理:依次比较两个相邻数据,如果前者比后者大,换位置

function str(arr) {
	for(let i = 0; i< arr.length-1; i++) {
		for( let j= 0; j < arr.length - i-1 ; j++) {
			if(arr[j] > arr[j + 1]) {
				let temp;
				temp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = temp;
			}
	    }
	}
	return arr;
}
let arr = [3,7,8,2,1,9,5]
console.log(str(arr))    // [1,2,3,5,7,8,9]

9.快速排序
1、找基准(一般是以中间项为基准)
2、遍历数组,小于基准的放在left,大于基准的放在right
3、递归

let arr = [3, 7,8,2,1,9,5];
function qrtsort(arr) {
	if(arr.length === 0) {
		return [];
	}
	let index = Math.floor(arr.length/2);
    console.log(index)
	let c = arr.splice(index , 1);
	console.log(c)
	let left = []
	let right = []
	for(let i= 0; i< arr.length; i++) {
		if(arr[i] < c) {
			left.push(arr[i])
		}else {
			right.push(arr[i])
		}
	}
	return qrtsort(left).concat(c, qrtsort(right))
} 

console.log(qrtsort(arr))  // [1,2,3,5,7,8,9]

10.二分法
1.定义3个用来记录索引值的变量,变量min记录当前范围最小索引值,初始值为0;变量max记录当前范围最大索引值,初始值为数组长度-1;变量mid记录当前当前范围最中间元素的索引值,初始值为(min+max) / 2

2.使用循环,判断当前范围下,最中间元素值与指定查找的数值是否相等,
若相等,结束循环; 若不相等,如果中间元素值 比 要查询的数值大,则更新查询范围:范围最大索引值 = 上一次中间索引位置 -1;中间元素值 比 要查询的数值小,说明要查询的数值在当前范围的最大索引位置与中间索引位置之间,此时,更新查询范围为: 范围最小索引值 = 上一次中间索引位置 +1;
3.每次查询范围缩小一半后,使用if语句判断,查询范围是否小于0个元素,若小于0个元素,则说明指定数值没有查询到,返回索引值-1。

 function halfSearch(arr, number){
     int min =0;  //最小下标
     int max =arr.length-1;   //最大下标
     int mid = 0;  //中间下标
     while (min<max){
        //没找到,更新范围继续找
         mid = (min+max)/2;
         if (arr[mid]>number){   // number在mid的左边
             max = mid-1;  // 改变最大下标
         }else if(arr[mid]<number){  // number在mid的右边
             min = mid+1;  // 改变最小下标
         }else{
             return  mid;
         }
     }
     return -1; // 没有找到
  }

11.闭包
闭包是指有权访问另一个函数作用域中的变量的函数,本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
(2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
运用

  • setTimeout
    原生的setTimeout传递的第一个函数不能带参数,通过闭包可以实现传。
function f1(a) {
  function f2() {
       console.log(a);
   }
   return f2;
}
let fun = f1('郭...');
setTimeout(fun,1000);//一秒之后打印出 郭...
  • 回调
function changeSize(size){
    return function(){
          document.body.style.fontSize = size + 'px';
      };
  }
  var size12 = changeSize(12);
  var size20 = changeSize(20);
  btn1.onclick = size12;
  btn2.onclick = size20;
  
 点击不能按钮获取不同字体大小
  • 函数防抖

在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
实现的关键就在于setTimeOut这个函数,由于还需要一个变量来保存计时,考虑维护全局纯净,可以借助闭包来实现。

fn  需要防抖的函数
number 毫秒,防抖期限值
function debounce(fn,number ){
    let timer = null
    //借助闭包
    return function() {
        if(timer){
            clearTimeout(timer) //进入该分支语句,说明当前正在一个计时过程中,并且又触发了相同事件。所以要取消当前的计时,重新开始计时
            timer = setTimeOut(fn,number) 
        }else{
            timer = setTimeOut(fn,number) // 进入该分支说明当前并没有在计时,那么就开始一个计时
        }
    }
}

12.面向对象构造函数

function person(name, age) {
	this.name = name
	this.age = age
	this.showName = function() {
		console.log('名字: ' + this.name)
	}
	this.showaAge = function() {
		console.log('年龄: ' + this.age)
	}
}
var obj = new person('赵丽颖', 27)
obj.showName() // 名字: 赵丽颖
obj.showaAge() // 年龄: 27

13.原型链

函数->构造函数原型->对象原型->null

在这里插入图片描述
14.浏览器输入地址到渲染的过程

1.DNS域名解析;
浏览器输入域名地址后,首先去看本地,浏览器,服务器端有没相应的缓存,检查在该文件中是否有相应的域名、IP对应关系,如果有,则向其IP地址发送请求,如果没有,再去找DNS服务器。解析成IP地址
2.建立TCP连接;
三次握手
3.发送HTTP请求;
4.服务器处理请求;
5.返回响应结果;
6.关闭TCP连接;
需要4次握手:
客户端:“兄弟,我这边没数据要传了,咱关闭连接吧。”
服务端:“收到,我看看我这边有木有数据了。”
服务端:“兄弟,我这边也没数据要传你了,咱可以关闭连接了。”
客户端:“好嘞。”
7.浏览器解析HTML;
8.浏览器布局渲染;

15.ajax
异步的 JavaScript 和 XML,最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容
优点:
异步与服务器通信
广泛支持
缺点:
破坏了浏览器机制,即干掉了bink和history功能
对搜索引擎支持弱
不能很好的支持移动端
安全问题
创建过程

 var xmlhttp; 
 if(window.XMLHttpRequest)
  {
  	xmlhttp =  new XMLHttpRequest();
  }else{
  	xmlhttp = new ActiveXObject(); // IE
  }
  xmlhttp.open("GET", '请求地址', true); //异步请求
  xmlhttp.send();
  xmlhttp.onreadystatechange=function() { // 状态
  	if(xmlhttp.readyState == 4 && xmlhttp.status == 200)
  	{
  		document.getElementById('').innerHTML = xmlhttp.responseText;
  	}
  }
		
  • get与post区别

get: 通过网址提交数据 容量小, 安全性差, 有缓存
post: 不通过网址提交 容量大(2G) 安全性相对高 无缓存

  GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
  GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
  GET请求在URL中传送的参数是有长度限制的,而POST么有。
  GET在浏览器回退时是无害的,而POST会再次提交请求。
  GET参数通过URL传递,POST放在Request body中。
  GET请求只能进行url编码,而POST支持多种编码方式。
  对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
  GET产生的URL地址可以被Bookmark,而POST不可以。
  GET请求会被浏览器主动cache,而POST不会,除非手动设置。
    
1.对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
2.而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。  

客户端与服务器之间数据的发送和返回的过程当中需要创建一个叫TCP

  • TCP三次握手
    连接必须是一方主动打开,另一方被动打开的
    以客户端向服务端发送连接为例:
1.首先客户端向服务器端发送一段TCP报文
 报文内容:请求建立新连接
2.服务器端接收到来自客户端的TCP报文之后,结束LISTEN阶段。并返回一段TCP报文
报文内容:确认客户端的报文Seq序号有效,服务器能正常接收客户端发送的数据,并同意创建新连接
3.客户端接收到来自服务器端的确认收到数据的TCP报文之后,明确了从客户端到服务器的数据传输是正常的,结束SYN-SENT阶段。并返回最后一段TCP报文
报文内容:确认收到服务器端同意连接的信号
  • http与https区别
1、https协议需要到CA申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl/tls加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是4434、http的连接很简单,是无状态的;HTTPS协议是由SSL/TLS+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

16.前端界面性能优化

 1.恰当放置css, 把css放入到文档头之内,确定正常渲染,不会长时间空白,使用link引入css, @import 会阻止浏览器并行下载
 2.正确放置js,将js置于底部,放头部会阻塞html、css元素加载过程,导致加载时间过程
 3.压缩js、css、html ,压缩技术可以去掉多余的字符,如:注释、缩进
 4.缓存方式, 浏览器缓存、服务器缓存
 5.预加载方式
 6.减少使用float、闭包、git图片等, 多使用CSS3样式

17.跨域处理
出于安全方面的考虑,页面中的JavaScript无法访问其他服务器上的数据,即“同源策略,而跨域就是通过某些手段来绕过同源策略限制,实现不同服务器之间通信的效果。

常用方法:
1.jsonp跨域
JSON 是一种轻量级的数据交换格式,而JSONP(JSON with Padding)则是JSON 的一种“使用模式”,通过这种模式可以实现数据的跨域获取。
当我们正常地请求一个JSON数据的时候,服务端返回的是一串JSON类型的数据,而我们使用JSONP模式来请求数据的时候,服务端返回的是一段可执行的JavaScript代码。
2.CORS,后端配置
跨域资源共享
3.nginx代理跨域
4.nodejs中间件代理跨域
proxy 

18.显式和隐式类型转换

显式转换:
parseInt()
parseFloat()
toString()
Number() 
Boolean()
隐式转换:
加法运算符+是双目运算符,只要其中一个是String类型,表达式的值便是一个String。
对于其他的四则运算,只有其中一个是Number类型,表达式的值便是一个Number。

19.js基础
js特点:单线程

 - var element = document.createElement("p");  //创建节点(元素)
   var text = document.createTextNode("袁冰妍小姐姐,真漂亮..."); //节点文本
  element.appendChild(text);  //元素中加入内容
  aDiv.appendChild(element); //将子节点加入到父元素中
  父元素.appendChild(子节点);
  父元素.insertBefore(子节点, 子节点2); //在子节点2 之前插入
  父元素.replaceChild(子节点, 被替换的节点);
2.var all = document.querySelectorAll('p');  //在文档中获取 节点列表NodeList  只能通过索引来获取。
  var span =document.querySelector('span');
3.arguments 不定参   参数数组  函数开始时使用
 function test() {
   let s = ""
   for(let i=0; i<arguments.length; i++){ 
         console.log(arguments[i])
     }
    return s;
 }
 test('aaa', 'bbb') // aaa  bbb
 4. 
  var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;//可视区顶部离整个文档顶部的距离
  var scrollLeft=document.documentElement.scrollLeft||document.body.scrollLeft;// 可视区左边离整个文档左边的距离  
  document.documentElement.clientHeight 可视区高度
  document.documentElement.scrollHeight 总高度
  documnet.documentElement.scrollTop 滚动的高

20.浅拷贝与深拷贝

  • 浅拷贝
    共享一块内存,修改其中一个对象,另一个也会跟着变
1.object.assign(目标,源1,源2....)
2.直接赋值
  • 深拷贝(递归)
    复制并创建一个一摸一样的对象,不共享内存,修改新对象,旧对象保持不变
 1.数组深拷贝可以用 for循环
 2.对象用for.. in..
 3.函数直接赋值 = 
 4.JSON.parse(JSON.stringify(Object/Array))

21.this的理解

1.总是指向函数的直接调用者,而非间接调用者
2.如果有new关键字,this指向new出来的那个对象
3.在事件中,this指向触发这个事件的对象,特殊时,IE中的attachEvent中的this指向全局变量window

22.XML与JSON区别

1.JSON相对于XML,数据体积小,传输速度大点
2.JSON与javascript交互更方便,更容易解析处理,更好的数据交互
3.JSON对吧数据的描述性比XML差些

23.web常见的安全问题及防范

  • XSS攻击
    原理:
    XSS是一种经常出现在web应用中的计算机安全漏洞,攻击者往web页面插入恶意的HTML代码和js代码。比如:攻击者用一个链接,骗取用户点击后,获取cookie中用户私密信息,或者攻击者加一个恶意表单,用户提交数据时,被提交到攻击者的服务器上,获取信息。
    表现:
    1、盗取各类用户帐号,如机器登录帐号、用户网银帐号、各类管理员帐号
    2、控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力
    3、盗窃企业重要的具有商业价值的资料
    4、非法转账
    5、强制发送电子邮件
    6、网站挂马
    7、控制受害者机器向其它网站发起攻击
    措施:
    目前来讲,最简单的办法防治办法,还是将前端输出数据都进行转义最为稳妥,虽然显示出来是有script标签的,但是实际上,script标签的左右尖括号(><),均被转义为html字符实体,所以,便不会被当做标签来解析的,但是实际显示的时候,这两个尖括号,还是可以正常展示的。
  • CSRF攻击
    原理:
    CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。其实就是网站中的一些提交行为,被黑客利用,你在访问黑客的网站的时候,进行的操作,会被操作到其他网站上(如:你所使用的网络银行的网站)。
    表现:
    在登入信任网站A时,并在本地生成Cookies,同时没有退出,直接登入危险网站B
    措施:
    增加随机数,登入时验证码
  • sql注入
    原理:
    通过把sql命令插入到web表单,最终执行恶意的sql语句
    措施
    不要使用动态拼接sql,可以使用参数化的sql
    不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接
    24.随机选取10-100之间的10个数,并排序
let arr = []
function getRandNum(start, end) {
  let dis = end - start + 1
  return Math.floor(Math.random() * dis ) + start 
}
for(let i=0; i< 10; i++) {
 arr.push(getRandNum(10, 100)) 
}
arr.sort()

25.数组去重常用方法

  • es6 Set方法
let arr = ['12', 12, 12, '12', true, true, false, false, undefined, null]
let mp = Array.from(new Set(arr))
console.log(mp) // ["12", 12, true, false, undefined, null]

或者[...new Set(arr)]简结写法
  • 利用for嵌套 然后splice去重 (es5常用)
let arr = ['12', 12, 12, '12', true, true, false, false, undefined, null]
function unique(arr) {
	for(let i=0; i< arr.length; i++) {
		for(let j=i+1; j< arr.length; j++) {
			if(arr[i] === arr[j]) {
				arr.splice(j, 1)
				j--
			}
		}
	}
	return arr
}
console.log(unique(arr)) //  ["12", 12, true, false, undefined, null]
  • 利用indexOf去重
let arr = ['12', 12, 12, '12', true, true, false, false, undefined, null]
function unique(arr) {
	if(!Array.isArray(arr)) {
		console.log('type error')
		return false
	}
	var array = []
	for(let i=0; i< arr.length; i++) {
		if(array.indexOf(arr[i]) === -1) {
			array.push(arr[i])
		}
	}
	return array
}
console.log(unique(arr)) //  ["12", 12, true, false, undefined, null]
  • 利用includes去重
let arr = ['12', 12, 12, '12', true, true, false, false, undefined, null]
function unique(arr) {
	if(!Array.isArray(arr)) {
		console.log('type error')
		return false
	}
	var array = []
	for(let i=0; i< arr.length; i++) {
		if(!array.includes(arr[i])) {
			array.push(arr[i])
		}
	}
	return array
}
console.log(unique(arr)) //  ["12", 12, true, false, undefined, null]

26.ajax用Promise封装

/*** ajax数据请求接口
  	@param {string} type 请求方式 {"get(默认)" | "GET" | "post" | "POST"}
 	@param {string} url 请求接口地址
  	@param {Object} data 请求时后台所需参数
  	@param {bool} async 是否异步(true)或同步(false)请求{true(默认) | false}	  	
  	@example: $ajax({
  					type: "post", 
  					url: "", 
  					data: {}
  				}).then(function(ret){
  				
  				}).catch(function(err){
  				
  				});
*/
var $ajax = function({type, url, data, async}){
	// 异步对象
	var ajax;		
	window.XMLHttpRequest ? ajax =new XMLHttpRequest() : ajax=new ActiveXObject("Microsoft.XMLHTTP");
	!type ? type = "get" : type = type;
	!data ? data = {} : data = data;
	async != false ? !async ? async = true : async = async : '';
	return new Promise(function(resolve,reject){
		// get 跟post  需要分别写不同的代码
		if (type.toUpperCase()=== "GET") 
		{// get请求
			if (data) {// 如果有值
				url += '?';										
				if( typeof data === 'object' )
				{ // 如果有值 从send发送
					var convertResult = "" ;
					for(var c in data){
						convertResult += c + "=" + data[c] + "&";
					}						
					url += convertResult.substring(0,convertResult.length-1);
				}
				else
				{
					url += data;
				}
			}
			ajax.open(type, url, async); // 设置 方法 以及 url
			ajax.send(null);// send即可
		}
		else if(type.toUpperCase()=== "POST")
		{// post请求
			ajax.open(type, url); // post请求 url 是不需要改变
			ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded"); // 需要设置请求报文
			if(data)
			{ // 判断data send发送数据
				if( typeof data === 'object' ){// 如果有值 从send发送
					var convertResult = "" ;
					for(var c in data){
					  convertResult += c + "=" + data[c] + "&";
					}
					convertResult = convertResult.substring(0,convertResult.length-1);
					ajax.send(convertResult);
				}else{
					ajax.send(data);
				}
			} else
			{
				ajax.send(); // 木有值 直接发送即可
			}
		}
		// 注册事件
		ajax.onreadystatechange = function () {
			// 在事件中 获取数据 并修改界面显示
			if (ajax.readyState == 4)
			{
				if(ajax.status===200)
				{ // 返回值: ajax.responseText;
					if(ajax.response && typeof ajax.response != 'object'){
						resolve(JSON.parse(ajax.response));							
					}
					else{
						resolve(ajax.response);
					}
				}
				else
				{
					reject(ajax.status);
				}
			}
		}
	});	
		
 引用自:https://blog.csdn.net/weixin_43838488/article/details/106721278

四、es6**

1.let、var、 const

  • 作用域:防止变量泄露污染
  • 在使用var关键词声明变量时,变量在函数外则是全局变量,有全局作用域,全局变量在页面关闭后销毁;变量在函数内则是局部变量,作用局部作用域,变量只能在该函数内有效,函数执行完将自动销毁
  • 我们使用var来创建变量,声明后未赋值的变量输出会提示 “undefined”。在方法函数外声明的变量未使用var ,会报错“x is not defined”
  • 在函数内未使用var声明的变量自动变为全局变量

问题:
1.解决ES5使用var初始化变量时会出现的变量提升问题
2.解决使用闭包时出错的问题
3.解决使用计数的for循环变量时候会导致泄露为全局变量的问题,
4.ES5只有全局作用域和函数作用域(对应var声明的全局变量和局部变量时),没有块级作用域(ES6中{}中的代码块)。同理只能在顶层作用域window中和函数中声明函数,不能在块级作用域中声明函数;

let块级作用域
let和const是ES6新增特性,都可生成块级作用域(是指声明在花括号内的变量只在该区域内有效)。let用来声明变量,const用来声明常量(不可修改变量值,数组和对象除外);如果区块内存在let或const命令,这个区块对这些命令声明的变量会形成封闭的区域,该区域外不能被使用,且变量声明前使用变量会报错(又叫暂时性死区)

块级作用域外不能访问该区块内的变量或者常量,子块级作用域可以访问父块级作用域的变量
{
  const num = 99;
  {
    console.log(num); //可以在子块内访问父块定义的常量
  }
}
console.log(num); //报错, 不可以在块作用外访问let、const定义的变量或者常量

注释:
1.let声明的变量只在其声明的块或子块中可用,而var声明的变量的作用域是整个封闭函数可用
2.let和const关键词声明的变量不具备变量提升的特效,存在暂时性的死区,只能在声明的位置后使用,同一块级作用域中不能反复声明同一变量名(子块级可以重复声明父块级变量),var可以。
3.let和const声明只在最靠近的一个块(花括号内)中有效
2. `` 反引号(模板字符号)

let age= 28
<div>`赵丽颖年龄为:${age}岁`</div>

3.

1.keys()     获取键数组
2. values()  获取值数组
3. import、 export default  模块导入、到出
4. object.assign(目标,源1,源2...) 浅拷贝
5. for..of.. 循环
6. map 

4.引值

let obj = {
  name: '袁冰妍',
  age: 28
}
let { username } = obj

5.promise
javaScript的世界中,所有代码都是单线程执行的
异步编程的一种解决方案,解决回掉地狱问题

  • Promise 异步操作有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。除了异步操作的结果,任何其他操作都无法改变这个状态。
  • Promise 对象只有:从 pending 变为 fulfilled 和从 pending 变为 rejected 的状态改变。只要处于 fulfilled 和 rejected ,状态就不会再变了即 resolved(已定型)。
function test(resolve, reject) {
    var timeOut = Math.random() * 2;
    log('set timeout to: ' + timeOut + ' seconds.');
    setTimeout(function () {
        if (timeOut < 1) {
            log('call resolve()...');
            resolve('200 OK');
        }
        else {
            log('call reject()...');
            reject('timeout in ' + timeOut + ' seconds.');
        }
    }, timeOut * 1000);
}
promise异步
var p1 = new Promise(test);
var p2 = p1.then(function (result) {
    console.log('成功:' + result);
});
var p3 = p2.catch(function (reason) {
    console.log('失败:' + reason);
});
简化代码
new Promise(test).then(function (result) {
    console.log('成功:' + result);
}).catch(function (reason) {
    console.log('失败:' + reason);
});

除了串行执行若干异步任务外,Promise还可以并行执行异步任务。
试想一个页面聊天系统,我们需要从两个不同的URL分别获得用户的个人信息和好友列表,这两个任务是可以并行执行的,用Promise.all()

var p1 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 600, 'P2');
});
Promise.race([p1, p2]).then(function (result) {
    console.log(result); // 'P1'
});

6.async/await
正常情况下,await 命令后面是一个 Promise 对象,它也可以跟其他值,如字符串,布尔值,数值以及普通函数。
await只能放在async函数里
为了使我们的异步代码,更像同步的代码
await针对所跟不同表达式的处理方式:
Promise 对象:await 会暂停执行,等待 Promise 对象 resolve,然后恢复 async 函数的执行并返回解析值。
非 Promise 对象:直接返回对应的值。

function yao(){
    return new Promise((resolve, reject)=>{
        let sino = parseInt(Math.random() * 6 +1)
        setTimeout(()=>{
            resolve(sino)
        },3000)
    })
}
async function test(){
    let n = await yao()
    console.log(n)
}

7. 运算符(…)
用于展开或者合并作用

数组
let arr1 = [1, 2, 3]
let arr2 = [2, 3, 4]
let arr3= [...arr1, ...arr2] 
console.log(arr3) // [1, 2, 3, 2, 3, 4]
对象
let arr1 = {
    name: '2u',
	age:18
}
let arr2 = {
	name: '123'
}
let arr3= {...arr1, ...arr2}
console.log(arr3) // { age: 18, name: "123" }

五、jq
六、vue
1.vue特性
Vue 只关注视图层, 采用自底向上增量开发的设计。
Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件
vue属于MVVM模式
响应式系统
特点:

MVVM框架、数据驱动、组件化、轻量、简洁、高效、快速、模块友好
性能好、简单易用、前后端分离
单页面应用用户体验好、双向数据绑定
它不适于seo优化,适用于中小型项目
  • MVVM
    实现了view和model的自动同步,当model的属性改变时,对应的view层显示自动改变
    在这里插入图片描述
  • MVC
    模型,视图、控制器
    在这里插入图片描述
  • MVP
    在这里插入图片描述
  • 前后端的分离

人类早期的B/S应用程序中, 每次访问服务器端, HTML就会整体发给浏览器,即所谓的整体刷新。
后来人类发明了AJAX, 可以做到局部刷新。
于是浏览器端的应用变得越来越复杂,再后来人类竟然发明了Web上的SPA(单页应用程序),用起来的体验和最初的桌面应用程序越来越像。

2.vue生命周期函数

beforeCreate(){
  表示实例完全被创建出来之前, 会执行它,date 和 methods 中的数据都还没有初始化
},
created(){
  date 和 methods 中的数据都已经初始化好了, 要操作 date 和 methods最早只能在created中操作
},
beforeMount(){
  表示 模板已经在内存中编辑完成,但尚未把模板渲染到页面中,准备工作
},
mounted(){
  表示内存中的模板, 已经真实的挂载到页面中,用户已经可以看到渲染好的页面了,
  是实例创建的最后一个生命周期函数,最早只能在这操作页面上的DOM节点
},
beforeUpdate(){
  这时候表示我们的界面没有被更新, 数据被更新了
},
updated(){
  updated事件执行的时候 页面 和 data 数据已经保持同步了
},
beforeDestroy(){
  实例销毁之前调用
},
destroyed(){
  实例销毁后调用
}	

3.vue组件之间传值

  • 父组件向子组件传值 props
    父组件部分在这里插入图片描述子组件部分
    在这里插入图片描述
  • 子组件向父组件传值 $emit
    子组件部分
    在这里插入图片描述父子件部分
    在这里插入图片描述
  • 兄弟组件之间传值
 使用一个公用js 比如:bus.js
 在组件中分别引入,
 import bus form './bus.js'
 发送消息:bus.$emit()
 接收消息:bus.$on()
  • 多个嵌套组件里面的传值(后代)

依赖注入

<google-map>
  <google-map-region v-bind:shape="cityBoundaries">
    <google-map-markers v-bind:places="iceCreamShops"></google-map-markers>
  </google-map-region>
</google-map>

后代组件希望也能访问到传的值
用到了依赖注入的两个新的实例选项:provide 和 inject
祖先:
provide: function () {
  return {
    getMap: this.getMap
  }
}
后代:
使用 inject 选项来接收
inject: ['getMap']

注释:如果传值层级较多,数据处理较大,多个页面运用,可以考虑vuex或者缓存

4.计算监听属性(computed、watch)

https://blog.csdn.net/qq_46346301/article/details/105707482

5.v-show与v-if

1.v-if创建,销毁切换,适用于显示隐藏切换次数比较少的
2.v-show 只创建一次,显示,隐藏切换,类似于display:none/block,适用于切换频率比较大的运用

5.vue路由传参

<router-link :to="{ path: 'home' }">Home</router-link>
<!-- 命名的路由 -->
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
<!-- 带查询参数,下面的结果为 /register?plan=private -->
<router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>

编程式导航跳转页面

 <li v-for=“(item, index) in shops” @click="getDetaill(item.id)">跳转</li>
  • 方法一
 getDetaill(id) {
  // 直接调用$router.push 实现携带参数的跳转
   this.$router.push({
      path: `/detail/${id}`,
    })
 }

配置路由

 {
     path: '/detail/:id',
     name: 'detail',
     component: detail
 }

获取参数

this.$route.params.id
  • 方法二 - params
    获取的数据刷新消失
 this.$router.push({
    name: 'detail',
    params: {
       id: id
     }
   })

配置路由

 {
     path: '/detail',
     name: 'detail',
     component: detail
 }

获取参数

this.$route.params.id
  • 方法三 - query
    获取的数据刷新不会消失,缓存作用
this.$router.push({
   name: 'detail',
   query: {
      id: id
    }
  })

配置路由

 {
     path: '/detail',
     name: 'detail',
     component: detail
 }

获取参数

this.$route.query.id

6.vue路由守卫
路由守卫:全局路由守卫、组件内路由守卫、route独享守卫
路由守卫一般用于页面权限设置,比如:登入注册、配合路由中meta属性来使用。

  • 全局路由守卫
beforeEach(from, to, next) { //全局前置守卫
 if (to.path === '/login') {
      next({ path: '/home' }) 
    } 
  next:调用方法后,决定是否展示你要看到的路由页面
}
afterEach() 全局后置守卫
  • 组件路由
1.beforeRouterEnter() 
2.beforeRouterUpdate()
3.beforeRouteLeave(to, from, next) {
   if (to.name == 'home' || to.name == 'searchShopList') {
        to.meta.keepAlive = true;  
    }
	 else{
		 to.meta.keepAlive = false; 
	 }
  next();
}
  • 路由独享守卫
    与全局守卫一样,只是将其写进其中一个路由对象中

7.axios请求
封装请求
特点:
1.从浏览器中创建XMLHttpRequest
2.从nodejs创建http请求
3.支持promiseAPI
4.Axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中
5.自动转换JSON数据
6.客户端支持防止CSRF

// 创建请求
const service = axios.create({ 
  // baseURL: process.env.VUE_APP_BASE_API, 
  // withCredentials: true, 
  baseURL: 'http://111.229.130.127:8882',
  timeout: 5000,// request timeout
})
// 请求拦截
service.interceptors.request.use(
  config => {
    // config.headers.common['access-token'] = 'CC4EF3A72A3552DA62D008D77E97853172FF21C2'
    if (store.getters.token) {
      config.headers['access-token'] = getToken()
    }
    return config
  },
  error => {
    console.log(error) // for debug
    return Promise.reject(error)
  }
)
// 响应拦截
service.interceptors.response.use(
  response => {
    const res = response.data
    if(res.code === 10007) { // token失效
      const data = ''
      setToken(data)
      router.push({path: '/login'})
      Message({
        message: res.message || 'Error',
        type: 'error',
        duration: 3 * 1000
      })
    }else if (res.code !== 200) {
      Message({
        message: res.message || 'Error',
        type: 'error',
        duration: 3 * 1000
      })
    } else {
      return res
    }
  },
  error => {
    console.log('err' + error) // for debug
    Message({
      message: error.message,
      type: 'error',
      duration: 3 * 1000
    })
    return Promise.reject(error)
  }
)

export default service

8.vue-router路由

1.引入包
import VueRouter from 'vue-router'
2.//导入对应的路由组件
import HomeContainer from './components/tabbar/HomeContainer.vue'
3.//.创建路由对象
var router = new VueRouter({
   routes:[ //配置路由规则
          {path: '/', redirect:'/home'},
             {path: '/home',  name:'home', component:HomeContainer, 
		   meta:{
				  keepAlive:true,
				  footNav:true
			  }
		   }
		 ],
	linkActiveClass: 'mui-active', //覆盖默认路由的高亮的类,
	scrollBehavior (to, from, savedPosition) {    //保存滚动的位置
	 if (savedPosition) {  
	   return savedPosition 
	 } else {  
	   if (from.meta.keepAlive) {  
	    from.meta.savedPosition = document.body.scrollTop || document.documentElement.scrollTop;  
	   }  
	   return { x: 0, y: to.meta.savedPosition || 0 } 
	  } 
    }
})
4.//把路由对象暴露出去
export default router

9.vuex状态管理器
包含五个部分
state、action、mutations、getters、modules
state:存放数据的地方
action:调用mutations里面的方法,异步调用
mutations:增删改查地方 some 同步调用
getters: 相当于计算属性 forEach
结构:
在这里插入图片描述在这里插入图片描述在这里插入图片描述或者:
在这里插入图片描述在这里插入图片描述
对应的辅助函数

import {mapGetters, mapActions, mapMutations, mapState} from 'vuex'
computed:{
  ...mapState({
          add: state => state.add,
          counts: state => state.counts
        }),
	...mapGetters('app',[
		'getGoodsSelected',
		'getGoodsCountAndAmount',
		'getGoodsCount'
	])
},
methods:{
...mapMutations('app',[
	 'remoeFromCar',
	 'updateGoodsSelected',
	 'deal'
	]),
...mapActions()
}
直接调用  this.remoeFromCar(id);

10.vue优化性能提升方法

1.压缩js、css
2.缓存(浏览器、路由缓存keep-alive)
3.预加载
4.promise异步请求
5.路由按需加载  resolve => require([url], resolve)
component:()=>import('./page/itemSearchShop/sellerShop.vue')
6.图片懒加载

七、小程序
1.微信小程序有多少个文件

1.app.js 必须要这个文件,要不然会报错,可以创建一下就可以,可以在这里监听并处理小程序的全局生命周期函数,全局变量等
2.app.json 必须要这个文件,框架把这个文件作为项目配置的入口文件,这个项目的全局配置包括:页面注册、网络设置、及小程序的window背景颜色、导航条、标题等。
3.app.wxss 配置全局css
4.页面中 WXSS 用于描述WXML的组件样式 js 用于逻辑处理  json小程序页面设置 WXML 用于页面的布局

2.微信小程序跟事件传值

给html添加 data-* 属性来传递我们需要的值,然后通过e.currentTarget.dataset.*获取,或者onload中的参数获取,
data - 名称不能大写字母和不能存放对象

3.登入流程
在这里插入图片描述 1.调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
2. 调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 和 会话密钥 session_key。
3.之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。

注意:

  1. 会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。
  2. 临时登录凭证 code 只能使用一次

4.支付流程
在这里插入图片描述

5.路由传值
在这里插入图片描述

未完待续。。。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值