网站链接: element-ui dtcms
当前位置: 首页 > 技术博文  > 技术博文

个人面试题整理(marksheng)

2021/4/23 8:52:38 人评论

个人面试题整理 常识基础部分: 前后端分离的好处? ① .开发人员分离(分工明确,谁的活就是谁的活): 术业有专攻 前端就负责(View和Controller层):把精力放在html5,c3,jq,bootstrap,模块化,设计模式,兼容上,性能优化等... 后端负责(负责Model层&#x…

 个人面试题整理

常识基础部分:

  1. 前后端分离的好处?

① .开发人员分离(分工明确,谁的活就是谁的活): 术业有专攻

前端就负责(View和Controller层):把精力放在html5,c3,jq,bootstrap,模块化,设计模式,兼容上,性能优化等...

后端负责(负责Model层,业务处理/数据等)

② .对开发的效率有所提升,前端通过ajax来调用http请求调用后端的api接口

  1. 常见浏览器兼容问题?

① 不同浏览器的标签默认的margin和padding不同
答:第一种 : 可以把所以标签写上 设置margin:0;padding:0;

第二种: 用normalize来清除默认样式

② 块属性标签float后,又有横行的margin情况下,在IE6显示margin比设置的大 (常见症状是IE6中后面的一块被顶到下一行)

答: 在float的标签样式控制中加入 display:inline;将其转化为行内属性

 

③ 设置较小高度标签(一般小于10px),在IE6,IE7,遨游中高度超出自己设置高度

答 : 给超出高度的标签设置overflow:hidden;或者设置行高line-height 小于你设置的高度

  1. 遇到技术难题?如何解决?

在控制台将每一部分代码分别打上断点,让代码一段一段执行,最终就可以找到在执行哪一段代码时候,进行报错,然后对其中的代码的逻辑性进行相应的解决方案。

  1. 如何优化页面加载速度?
  1. 减少 css,js 文件数量及大小(减少重复性代码
  2. 图片的大小把 css 样式表放置顶部,把 js 放置页面底部
  3. 减少 http 请求数
  4. 使用外部 Js 和 CSS
  5. 图片懒加载 

压缩、合并,减少请求,代码层析优化。。。

 

 

 

HTML5相关

  1. HTML5新增标签?HTML4 与HTML5 区别?

新增header, footer, nav  video,audio,canvas ,aside 等标签

新增的input元素的类型: email:表示必须输的email地址,number:表示数字,range:表示数字范围值

首先要注意的是,HTML5虽然现在很火,但是HTML5标准还在制定中,标准仍在改变。HTML4已经10多年了,不会有任何改变了。

HTML4中元素不能把文档结构表示清楚。

HTML5 更语义化、利于清晰化网页的结构,更有利于SEO。(搜索引擎)

 

  1. Js操作页面视频播放暂停?

举例(例如页面上有1个video):
<video id="myVideo" src="1.webm" controls />
  则对应的脚本代码为:
/*原生 JS代码 */
document.getElementById('myVideo').play(); // 播放
document.getElementById('myVideo').pause(); // 暂停
/* jQuery代码 */
$('#myVideo').play(); // 播放
$('#myVideo').pause(); // 暂停

 

  1. 如何处理HTML5新标签浏览器兼容?

处理兼容问题有两种方式:
1.IE8/IE7/IE6支持通过document.方法产生的标签,利用这一特性让这些浏览器支持HTML5新标签。
2.使用是html5shim框架
另外,DOCTYPE声明的方式是区分HTML和HTML5标志的一个重要因素,此外,还可以根据新增的结构、功能元素来加以区分。

  1. 本地存储cookie与webStorage区别?

共同点: 都是在浏览器里存储信息的.,最早用cookie存信息,但是cookie有大小限制所以H5新增了两个存储

 

Cookie:存储信息大小不超过4MB、不安全

cookie数据存放在客户的浏览器上,session数据放在服务器上。

 

localStorage 与 sessionStorage :

  1. .localStorage:永久性存储,只要不删数据一直存储在浏览器中
  2. sessionStorage:临时性存储,在当前窗口关闭后数据会自动消失

保存数据:localStorage.setItem(key,value); 

读取数据:localStorage.getItem(key); 

删除单个数据:localStorage.removeItem(key); 

删除所有数据:localStorage.clear(); 

得到某个索引的key:localStorage.key(index); 

 

  1. Flex布局?

 

响应式网站相关

响应式就是在不同的分辨率下,改变代码、都要让内容以最佳的展现形式呈现给你用户,提升用户体验。

自适应设计(AWD):为不同类别的设备建立不同的网页,检测到设备分辨率大小后调用相应的网页。

如何下手响应式?

第一步:设置viewport

第二步:设置断点

断点也就是我们说的media queries。

下面我们来规划下重要的断点,在此之前,先看下bootstrap 4的断点设置:

 

// 默认为手机端样式

 

// 等于或大于 34*16 = 544px(手机横屏)

@media (min-width: 34em) { … }

 

// 等于或大于 48*16 = 768px(平板竖屏)

@media (min-width: 48em) { … }

 

// 等于或大于 62*16 = 992px(pc窄屏)

@media (min-width: 62em) { … }

 

// 等于或大于 75*16 = 1200px( pc宽屏)

@media (min-width: 75em) { … }

这里再补充一个超大屏断点,一般用于图片居多的站点如视频,购物类站点(单位为em或px都是一样的)

 

// pc超大屏 1380px

@media (min-width: 1380px) { … }

在做响应式的时候我们一般有个原则叫做是移动优先还是pc优先。1、bootstrap采用的是移动优先,移动优先的特点是先考虑设计移动的样式,然后再设置断点一步步向大尺寸添砖加瓦增加样式,所以采用min-width(移动端的样式相对来说都比较简单,而pc相对来说要复杂点,所以这种顺序是样式由少到多,由简单到复杂的过程)。/

2、反过来如果你的业务是pc优先,那默认是pc的样式,兼容到移动的时候就是由大到小,所以采用max-width(这种方式后面的移动端需要重置覆盖默认pc上的很多样式,比较浪费)

 

CSS、C3相关

  1. Css 权重

!important 表示强制应用该样式,

内联样式  > id选择器样式 > 类选择器样式 > 元素选择器样式;

2、Css   (flex)实现如下布局:

 

 

 

使元素垂直水平居中

  1. Flex布局实现

 

  1. 相对定位、绝对定位实现

 

 

  1. 利用c3的 transform:translate(-50%,-50%)实现(此方法可以在未知宽度的情况下使用-比较好)

 

 

 

  1. 如何使用rem 单位、rem和em区别?

一、那么如果你确定要使用rem单位,就按以下三个步骤来计算:

1、确定基数:一般10px,自己记住就行,不用写进代码里

2、html {font-size:百分数;}    百分数=基数/16  

  基数10    百分数62.5%

  基数14    百分数87.5%

3、px换算rem   公式=想要的px值/基数

  也就是说,当你设置 html {font-size:62.5%;},你想给容器里的文字设置字号14px,换算成rem就是14px/10——1.4rem 这样子

  (如果自己想要测试的话,拿火狐Firebug测试,因为Chrome下字号低于12px失效哈,如果想设置小于12px的字号,Chrome也有解决方案,自己百度就好)

二、如果使用em单位的时候,计算机就会自己去找你body的设置,才不会管你html是如何设置的呢

比如我们伟大的bootstrap给 body {font-size:14px;} 这样设置后,如果我想要一个14px的外边距,我就用14px/14px——1em 这样啦。

rem是基于html元素的字体大小来决定,而em则根据使用它的元素的大小决定(很多人错误以为是根据父类元素,实际上是使用它的元素继承了父类的属性才会产生的错觉)

 

  1. 使用display:none 来隐藏内容

隐藏内容、元素不占空间。

Visibility:hidden 来隐藏内容

虽然隐藏了内容、但依旧占据空间。

 

  1. 怎样清除浮动?

1.增加空标签,给空标签增加clear:both;

2.使用overflow:hidden

3.通过伪元素::after添加clear:both;来清除浮动

为什么清除浮动?

果想要三个块级元素并排显示,都给它们加个float来得会比较方便。

什么时候清除浮动?

如果想要实现三个块级元素并排显示,期望效果如下图所示: 

 

给三个块级元素都加上float属性后,页面效果如下图所示:

 

 

问题出现了,父元素高度塌陷了

一目了然:如果我们给上面的三个绿颜色的方块设置display:inline-block也能达到让它们并排显示的效果。并且父元素的高度也不会塌陷。只不过无法控制是居左还是居右,display:inline-block只能从左往右。

清除浮动的方式?

我们说的清除浮动是指清除由于子元素浮动带来父元素高度塌陷的影响。

清除浮动的两大基本方法:

  • 方法1:脚底插入clear:both;
  • 方法2:父元素BFC(ie8+)或haslayout(ie6/ie7)

 

 

JS相关

  • 函数用法

①.变量作用域:全局  局部

②.函数:垃圾回收的机制

 

递归函数:指函数在内部直接或者间接的访问自己.虽然有代码简洁的优点,但是时间和空间消耗比较大

 

回调函数:把一个函数作为另一个函数的参数,当这个函数调用的时候,这个函数就叫做回调函数.

 

闭包:闭包是指有权访问其他函数作用域变量的函数,

创建闭包的通常方式,是在一个函数内部创建另一个函数.

 

(总结:   闭包作用 : 用来访问函数内部的局部变量,

  缺点 : 会导致局部变量始终存在内存中,耗性能)

 

  • 面向对象原型链?

每一个构造函数都有一个叫做prototype的属性,指向一个对象,当这个构造函数被new的时候,它的每一个实例都会拥有一个叫做__proto_属性,也指向这个对象.

 

  • 事件冒泡与事件捕获?

事件流:事件执行的一种机制,事件冒泡是最典型的事件流.

事件冒泡是由子一层一层向父层传递(由里到外)

事件捕获则相反

 

阻止事件传播:

Event.stopPropagation(); 阻止冒泡(支持高版本浏览器)

Event.cancelBubble = true;  IE浏览器(现在高版本也支持)

 

  • Js继承

 类式继承(构造函数)

JS中其实是没有类的概念的,所谓的类也是模拟出来的。特别是当我们是用new 关键字的时候,就使得“类”的概念就越像其他语言中的类了。类式继承是在函数对象内调用父类的构造函数,使得自身获得父类的方法和属性Call()和apply参数是数组方法为类式继承提供了支持。通过改变this的作用环境,使得子类本身具有父类的各种属性。

call和apply

call 和 apply 的作用,完全一样,唯一的区别就是在参数上面。

call 接收的参数不固定,第一个参数是函数体内 this 的指向,第二个参数以下是依次传入的参数。

apply接收两个参数,第一个参数也是函数体内 this 的指向。第二个参数是一个集合对象(数组或者类数组)

 

这种方式是通过构造函数实现的,当然也把构造函数自身的问题带过来了——破坏了复用性。因为每个实例都创建了一份副本。

如果仅仅借助构造函数,方法都在构造函数中定义,因此函数无法达到复用

 

原型继承

 原型继承在开发中经常用到。它有别于类继承构造函数是因为继承不在对象本身,而在对象的原型上(prototype)。每一个对象都有原型,在浏览器中它体现在一个隐藏的__proto__属性上。在一些现代浏览器中你可以更改它们。

案例1:

 

可以看到第七行实现了原型继承。很多人并不陌生这种方式。

 

案例2:

 

 

解析:son实例对象是如何找到getFatherValue()方法的呢?

首先在son对象自身中找。若对象自身没找到

然后在Son.prototype中找。若Son.prototype中没找到

继续往上一层,Son.prototype.__proto__(Fater.prototype)

依次类推,直到找到需要的属性或方法,或到达原型链顶端Object.prototype

 

如果到最后都没找到,会发生什么呢?

 

 

 

 

 

缺点:原型链中引用类型的属性会被所有实例共享的,即所有实例对象使用的是同一份数据,会相互影响。

不能直接调用父类的构造函数而是要调用子类

 

 

组合继承:

组合继承是将 原型链继承  构造函数 结合起来,从而发挥二者之长的一种模式。

思路就是使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。

这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有它自己的属性。

 

 

解析

借用构造函数部分:

Father.call(this, name)——name来自Father
this.age = age; Son.prototype.constructor = Son——age来自Son

原型链部分:

Father.prototype.getName——getName方法来自Father.prototype
Son.prototype.getAge——getAge来自Son.prototype

 

原型式继承

 

  重点:用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象。object.create()就是这个原理。

    特点:类似于复制一个对象,用函数来包装。

    缺点:1、所有实例都会继承原型上的属性。

2、无法实现复用。(新实例属性都是后面添加的)

五、寄生式继承

 

    重点:就是给原型式继承外面套了个壳子。

    优点:没有创建自定义类型,因为只是套了个壳子返回对象(这个),这个函数顺理成章就成了创建的新对象。

    缺点:没用到原型,无法复用。

 

 六、寄生组合式继承(常用)

寄生:在函数内返回对象然后调用

    组合:1、函数的原型等于另一个实例。2、在函数中用apply或者call引入另一个构造函数,可传参 

 

 

 

重点:修复了组合继承的问题

 

 

 

 

class继承 extends实现
ES6之后有的方法,比较直观,也符合逻辑

 

  • JS中深拷贝与浅拷贝?

JS 中的浅拷贝与深拷贝,只是针对复杂数据类型(Object,Array)的复制问题。浅拷贝与深拷贝都可以实现在已有对象上再生出一份的作用。但是对象的实例是存储在堆内存中然后通过一个引用值去操作对象,由此拷贝的时候就存在两种情况了:拷贝引用和拷贝实例,这也是浅拷贝和深拷贝的区别。

  • 浅拷贝:浅拷贝是拷贝引用,拷贝后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响
  • 深拷贝:在堆中重新分配内存,并且把源对象所有属性都进行新建拷贝,以保证深拷贝的对象的引用图不包含任何原有对象或对象图上的任何对象,拷贝后的对象与原来的对象是完全隔离,互不影响

 

浅拷贝

浅拷贝分两种情况,拷贝直接拷贝源对象的引用 和 源对象拷贝实例,但其属性(类型为ObjectArray的属性)拷贝引用。

拷贝原对象的引用

这是最简单的浅拷贝。例:

var a = {c:1};

var b = a;

console.log(a === b); // 输出true。

a.c = 2;

console.log(b.c); // 输出 2

 

源对象拷贝实例,其属性对象拷贝引用。

这种情况,外层源对象是拷贝实例,如果其属性元素为复杂杂数据类型时,内层元素拷贝引用。
对源对象直接操作,不影响两外一个对象,但是对其属性操作时候,会改变两外一个对象的属性的只。
常用方法为:Array.prototype.slice()Array.prototype.concat()jQury$.extend({},obj),例:

var a = [{c:1}, {d:2}];

var b = a.slice();

console.log(a === b); // 输出false,说明外层数组拷贝的是实例

a[0].c = 3;

console.log(b[0].c); // 输出 3,说明其元素拷贝的是引用

 

深拷贝

深拷贝后,两个对象,包括其内部的元素互不干扰。常见方法有JSON.parse(),JSON.stringify()jQury$.extend(true,{},obj)lodash_.cloneDeep_.clone(value, true)。例:

var a = {c: {d: 1}};

var b = $.extend(true, {}, a);

console.log(a === b); // 输出false

a.c.d = 3;

console.log(b.c.d); // 输出 1,没有改变。

  • 什么是跨域?

跨域问题来源于JavaScript的"同源策略",即只有 协议+主机名+端口号 (如存在)相同,则允许相互访问。也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。跨域问题是针对JS和ajax的,html本身没有跨域问题。

解决跨域问题,有如下种方式:

  1. 通过jsonp跨域
    2、 document.domain + iframe跨域
    3、 location.hash + iframe
    4、 window.name + iframe跨域
    5、 postMessage跨域
    6、 跨域资源共享(CORS)
    7、 nginx代理跨域
    8、 nodejs中间件代理跨域
    9、 WebSocket协议跨域

 

 

1、使用jsonp (只支持get请求不支持post请求)

jsonp解决跨域问题的原理是,浏览器的script标签是不受同源策略限制的,我们可以在script标签中访问任何域名下的资源文件。利用这一特性,用script标签从服务器中请求数据,同时服务器返回一个带有方法和数据的js代码,请求完成,调用本地的js方法,来完成数据的处理。

2、服务器代理 (可以是后台语言node.js 做代理)

3、CORS  

跨域资源共享重点就在于响应头

缺点:此种解决跨域方案,需要浏览器支持H5,因为这是HTML5解决跨域的方式,如果产品面向的是PC端,这种方式可能就不是一个好的解决方案,如果面向的是手机端,此方法不为一个简单、粗暴的好方式。

 

  • 什么是ajax?

是指一种创建交互式网页应用的网页开发技术。

Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。

特点: ajax 主要用在开发网站上,很明显的一个特点就是局部刷新,不需要下载插件。

ajax可以分为:

同步:事情一件一件去做

异步:多件事情一块去做

解释: 像ajax遵循的是同源策略,同一端口,同一域名,同一协议,发送的请求数据,不能请求其他服务器上的数据,所以不存在跨域,

响应状态:

0 : 请求未初始化 .(ajax刚刚创建)

1 : 服务器连接已建立 .(send已发送请求)

2 : 请求已接收  .服务器响应时发生

3 : 请求处理中  .服务器响应时发生

4 : 请求已完成 数据读取成功

原生ajax 请求步骤:

1. 创建 XMLHttpRequest 对象,也就是创建一个异步调用对象

2. 创建一个新的 HTTP 请求,并指定该 HTTP 请求的方法、URL 及验证信息

3. 设置响应 HTTP 请求状态变化的函数

4. 发送 HTTP 请求

5. 获取异步调用返回的数据

6. 使用 JavaScript 和 DOM 实现局部刷新

jquery的ajax请求: $.ajax,$.post, $.get, $.getJSON。

    $.ajax() :

        type:类型

        url:发送请求的地址。

        data:是一个对象,连同请求发送到服务器的数据

        dataType:预期服务器返回的数据类型。

        success:是一个方法,请求成功后的回调函数。

        error:是一个方法、请求失败时调用此函数。

  • Ajax 同步 异步区别?

同步是当JS代码加载到当前AJAX的时候会把页面里所有的代码停止加载,页面出去假死状态,当这个AJAX执行完毕后才会继续运行其他代码页面假死状态解除。
异步 执行到AJAX代码运行中的时候其他代码一样可以运行。

就是说当ajax发送请求后,在等待server端返回的这个过程中,前台会继续 执行ajax块后面的脚本,直到server端返回正确的结果才会去执行success,也就是说这时候执行的是两个线程,ajax块发出请求后一个线程 和ajax块后面的脚本(另一个线程)

  • 常见的http状态码?

200——服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。

400——无法找到请求的资源,

403——请求不允许,

404——没有发现文件、查询或URl

500——服务器解析错误

  • Hhttp和https区别?

 http的全称是Hypertext Transfer Protocol Vertion (超文本传输协议),说通俗点就是用网络链接传输文本信息的协议,

HTTPS的全称是Secure Hypertext Transfer Protocol(安全超文本传输协议),是在http协议基础上增加了使用SSL加密传送信息的协议。

所以http和https之间的区别就在于其传输的内容是否加密和是否是开发性的内容。这也是你为什么常常看见https开头的网址都是一些类似银行网站的这类网址的原因。

HTTPS和HTTP的区别:

      https协议需要到ca申请证书,一般免费证书很少,需要交费。

      http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议。

      http和https使用的是完全不同的连接方式用的端口也不一样,前者是80,后者是443。

      http的连接很简单,是无状态的。

      HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全

  • DOM加载流程?

①.解析HTML结构

②.加载外部脚本和样式表文件

③.解析并执行脚本代码

④.DOM树构建完成(DOMContentloaded)

⑤.加载图片等外部文件

⑥.页面加载完毕(onload)

 

  • 数组去重常用方法?
  1. IndexOf() 方法去重indexof()方法 如果检测到的值没有出现,则返回-1

数组的indexOf()方法可返回某个指定的元素在数组中首次出现的位置。该方法首先定义一个空数组res,然后调用indexOf方法对原来的数组进行遍历判断,如果元素不在res中,则将其push进res中,最后将res返回即可获得去重的数组

 

 

  1. Indexof() 方法2

利用indexOf检测元素在数组中第一次出现的位置是否和元素现在的位置相等,如果不等则说明该元素是重复元素

 

  1. 相邻元素去重

这种方法首先调用了数组的排序方法sort(),然后根据排序后的结果进行遍历及相邻元素比对,如果相等则跳过改元素,直到遍历结束

  • 什么是回流、重绘?

回流(reflow):比如我们增删DOM节点,修改一个元素的宽高,页面布局发生变化,DOM树结构发生变化,那么肯定要重新构建DOM树,而DOM树与渲染树是紧密相连的,DOM树构建完,渲染树也会随之对页面进行再次渲染,这个过程就叫回流

重绘(repaint)当你给一个元素更换颜色,这样的行为是不会影响页面布局的,DOM树不会变化,但颜色变了,渲染树得重新渲染页面,这就是重汇

你应该能感觉到,回流的代价要远大于重绘。且回流必然会造成重绘,但重绘不一定会造成回流。

 

  • 解决http的无状态性带来的问题?

http本身是一个无状态的链接协议、为了支持客户端服务器之间的交互、我们就要通过不同的技术为交互存储状态、而这些不同的技术状态就是Cookie和 Session。

  • 定时器?
  • setInterval() :按照指定的周期(以毫秒计)来调用函数或计算表达式。方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。
  • setTimeout() :在指定的毫秒数后调用函数或计算表达式。

 

  •  

 

  • For-in  for-of 的区别?

例1

 

 

以上代码通过 for in 和 for of 对一个obj对象进行遍历,for in 正常的获取了对象的 key值,分别打印 a、b、c,而 for of却报错了。

 

例2:

以上是遍历对象,下面再看一个遍历数组的例子。

 

以上代码是对一个数组进行遍历, for in 返回的值为 0、1、2,这不是数组的下标吗? 而 for of 返回的是 a、b、c,这一次没有报错,为什么呢?

例3:

 

 

for in 的特点

for ... in 循环返回的值都是数据结构的 键值名
遍历对象返回的对象的key值,遍历数组返回的数组的下标(key)。

for ... in 循环不仅可以遍历数字键名,还会遍历原型上的值和手动添加的其他键。如——例3

特别情况下, for ... in 循环会以任意的顺序遍历键名

总结一句: for in 循环特别适合遍历对象。

for of 特点

for of 循环用来获取一对键值对中的值,而 for in 获取的是 键名

For of 适合遍历数组

一个数据结构只要部署了 Symbol.iterator 属性, 就被视为具有 iterator接口, 就可以使用 for of循环。

例1这个对象,没有 Symbol.iterator这个属性,所以使用 for of会报 obj is not iterable

for of 不同与 forEach, 它可以与 break、continue和return 配合使用,也就是说 for of 循环可以随时退出循环。

提供了遍历所有数据结构的统一接口

哪些数据结构部署了 Symbol.iteratoer属性了呢?

只要有 iterator 接口的数据结构,都可以使用 for of循环。

  • 数组 Array
  • Map
  • Set
  • String
  • arguments对象
  • Nodelist对象, 就是获取的dom列表集合

以上这些都可以直接使用 for of 循环。 凡是部署了 iterator 接口的数据结构也都可以使用数组的 扩展运算符(...)、和解构赋值等操作。

我也想让对象可以使用 for of循环怎么办?使用 Object.keys() 获取对象的 key值集合后,再使用 for of

 

也可以给一个对象部署 Symbol.iterator属性。

 

  • Js常用 循环遍历(数组或对象)的方法?
  1. for 循环

let arr = [1,2,3];

for (let i=0; i<arr.length; i++){

 console.log(i,arr[i])

}

// 0 1

// 1 2

// 2 3

for 循环是 Js 中最常用的一个循环工具,经常用于数组的循环遍历。

  1. for in 循环(VUE中常用到)

let obj = {name:'zhou',age:'**'}

for(let i in obj){

 console.log(i,obj[i])

}

// name zhou

// age **

for in 循环主要用于遍历普通对象,i 代表对象的 key 值,obj[i] 代表对应的 value,当用它来遍历数组时候,多数情况下也能达到同样的效果,但是你不要这么做,这是有风险的,因为 i 输出为字符串形式,而不是数组需要的数字下标,这意味着在某些情况下,会发生字符串运算,导致数据错误,比如:'52'+1 = '521' 而不是我们需要的 53。

另外 for in 循环的时候,不仅遍历自身的属性,还会找到 prototype 上去,所以最好在循环体内加一个判断,就用 obj[i].hasOwnProperty(i),这样就避免遍历出太多不需要的属性。

 

  1. while 循环

cars=["BMW","Volvo","Saab","Ford"];

var i=0;

while (cars[i])

{

console.log(cars[i] + "<br>")

i++;

};

 

  1. do while 循环

let i = 3;

do{

 console.log(i)

 i--;

}

while(i>0)

// 3

// 2

// 1

do while 循环是 while 循环的一个变体,它首先执行一次操作,然后才进行条件判断,是 true 的话再继续执行操作,是 false 的话循环结束。

 

5、数组forEach 循环(VUE中常用到)

 

let arr = [1,2,3];

arr.forEach(function(i,index){

 console.log(i,index)

})

// 1 0

// 2 1

// 3 2

forEach循环,循环数组中每一个元素并采取操作, 没有返回值, 可以不用知道数组长度,他有三个参数,只有第一个是必需的,代表当前下标下的 value。

另外请注意,forEach 循环在所有元素调用完毕之前是不能停止的,它没有 break 语句,如果你必须要停止,可以尝试 try catch 语句,就是在要强制退出的时候,抛出一个 error 给 catch 捕捉到,然后在 catch 里面 return,这样就能中止循环了,如果你经常用这个方法,最好自定义一个这样的 forEach 函数在你的库里。

6、数组 map()方法 (VUE中常用到)

arr.map(function(i,[index],[arr]){    // i 代表数组中每一项 必须  index 代表数组中元素的下标 可选  arr 代表当前元素所属的数组对象 可选

..........

})

1

2

3

4

5

6

let arr = [1,2,3];

let tt = arr.map(function(i){

 console.log(i)

 return i*2;

})

// [2,4,6]

map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
注意:map 和 forEach 方法都是只能用来遍历数组,不能用来遍历普通对象。

 

  1. 数组 filter() 方法(VUE中常用到)

arr.filter(function(i,[index],[arr]){    // i 代表数组中每一项 必须  index 代表数组中元素的下标 可选  arr 代表当前元素所属的数组对象 可选

..........

})

 

let arr = [1,2,3];

let tt = arr.filter(function(i){

 return i>1;  //遍历数组中是所有元素返回大于1的元素

})

// [2,3]

filter 方法是 Array 对象内置方法,它会返回通过过滤的元素,不改变原来的数组。

 

 

8、Array some() 方法 (VUE中也用到)

let arr = [1,2,3];

let tt = arr.some(function(i){

 return i>1;

})

// true

some() 方法用于检测数组中的元素(只要有一个满足条件就是true)是否满足指定条件(函数提供),返回 boolean 值,不改变原数组。

 

 

  1. 数组 every() 方法(VUE中用到)

arr.every(function(i,[index],[arr]){    // i 代表数组中每一项 必须  index 代表数组中元素的下标 可选  arr 代表当前元素所属的数组对象 可选

..........

})

1

2

3

4

5

6

let arr = [1,2,3];

let tt = arr.every(function(i){

 return i>1;

})

// 检测数组中元素是否都大于1

// false

every() 方法用于检测数组所有元素(或每一个元素都必须满足条件才为true)是否都符合指定条件(通过函数提供),返回 boolean 值,不改变原数组。

10、Array reduce()方法(VUE常用到)

1

2

3

4

5

let arr = [1,2,3];

let ad = arr.reduce(function(i,j){

 return i+j;     //就是计算从左到右 1+2+3

})

// 6

reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。

 

12、for of 循环

1

2

3

4

5

6

let arr = ['name','age'];

for(let i of arr){

 console.log(i)

}

// name

// age

for of 循环是 Es6 中新增的语句,功能非常强大用来替代 for in 和 forEach,for-of循环不仅支持数组,还支持大多数类数组对象,它允许你遍历 Arrays(数组), Strings(字符串), Maps(映射), Sets(集合)等可迭代(Iterable data)的数据结构,注意它的兼容性。

// 类数组对象

let obj = { 100: 'a', 2: 'b', 7: 'c' }

 

 

 

jQuery相关

  • jQuery优势?

1.轻量级2.出色的浏览器兼容3.出色的dom操作 4.链式操作方式5.支持扩展6.开源

7、jQuery采用的是构造函数模式进行开发的,jQuery是一个类

8、上面说的常用的方法(CSS、属性、筛选、事件、动画、文档处理)都是定义在jQuery.prototype上的 ->只有jQuery的实例才能使用这些方法

 

$ 和 $() 区别?

$就是jquery对象,$()就是jQuery(),在里面可以传参数,作用就是获取元素

 

  • jq常用动画?

Show()显示、hide()隐藏、 fadeout()淡出, fadein() 淡入、

fadeToggle淡入淡出切换、

fadeto()渐变为给定的不透明度(值介于 0 与 1 之间)。

slideDown()向下滑动、slideUp向上、 slideToggle 上下来回切换滑动。

animate() 自定义的动画。  

Stop() 停止动画

Jquery获取子元素的方法有2种,

分别是children()方法和find()方法

  • jquery 的ready() 与window.onload()的区别

 window.onload() 必须等待网页全部加载完毕(包括图片等),然后再执行JS代码只能执行一次,如果第二次,那么第一次的执行会被覆盖

 

$(document).ready()只需要等待网页中的DOM结构加载完毕,就能执行JS代码可以执行多次,第N次都不会被上一次覆盖

  • Jq过滤

三个最基本的过滤方法是:first(), last() 和 eq(),

first() 方法返回被选元素的首个元素。

last() 方法返回被选元素的最后一个元素。

eq() 方法返回被选元素中带有指定索引号的元素。

filter() 方法允许您规定一个标准。不匹配这个标准的元素会被从集合中删除,匹配的元素会被返回。

下面的例子返回带有类名 "url" 的所有 <p> 元素:

$(document).ready(function(){ $("p").filter(".url"); });

 

not() 方法返回不匹配标准的所有元素。

提示:not() 方法与 filter() 相反。

下面的例子返回不带有类名 "url" 的所有 <p> 元素:

$(document).ready(function(){ $("p").not(".url"); });

 

  • Js和jq实现从a页面跳入b页面?

1.a标签

a标签:<a href="http://www.jb51.net" title="脚本之家">Welcome</a>

<a href= “javascript:history.go(-1)”>  :上一个页面,就是前一个页面

<a href= “javascript:history.go(1)”>  :下一个页面,就是后一个页面

<a href="http://www.jb51.net" title="脚本之家" target="_blank">Welcome</a>

 

2 . location对象的href属性:

window.location.href="http://www.jb51.net";      //在同当前窗口中打开窗口

3.open :

window.open(“http://www.w3schools.com”,”_blank”);     //在另外新建窗口中打开窗口

使用jQuery的属性替换方法

$(location).attr('href', 'http://www.jb51.net');

$(window).attr('location','http://www.jb51.net');

$(location).prop('href', 'http://www.jb51.net')

 

ES6相关

  • ES6和ES5   this指向区别?

ES5:

1.在普通函数中的this总是代表他的直接调用者,默认情况下指向windos

  2.在严格模式下,没有直接调用者的函数中的thisundefined使用  

  3.call,apply,bind,this指向的是绑定的对象;

this指向:

  1. 在全局的调用函数this指向windos

2.对象函数调用,那个函数调用this就指向那个对象

3.定时器中this指向全局

4.addEventListener this的指向    addEventListener this指向事件前的dom对象在IE11下attachEvent this 指向window

5.构造函数下this指向  构造函数中的this指向构造出来的新对象

 

ES6:

箭头函数没有自己的this,他的this是继承来的,默认指向在定义他时所在的对象,

 

  • ES6新特性?
  1.  let、var const  区别?

et表示声明变量,而const表示声明常量,两者都为块级作用域;

所谓块级作用域是指:将多个代码语句封装在一起,通常是包含在一个大括号中,没有返回值。 

 

众所周知,在ES6之前,JavaScript中只有全局作用域和局部(函数)作用域,不存在块级作用域。而且也只能使用关键字var来声明变量。所以用var声明的变量要么是属于全局作用域的全局变量,要么就是属于局部(函数)作用域的局部变量。

Let 关键词声明的变量不具备变量提升(hoisting)特性 let声明的变量只在其所在的块级作用于有效

Var  关键词声明的变量具备变量提升。

用var声明的变量,会在其作用域中发生变量提升的过程变量会被提升到作用域顶部,JS默认给变量一个undefined值。在使用var声明一个变量前访问它,得到的值永远是undefined。

但是,在ES6中使用let声明的变量,不存在变量提升过程。也就是说,不能在使用let声明任何一个变量前访问它,否则都会报错。

为什么ES6中需要引入块级作用域的概念呢?为什么要增加使用let来声明变量的方式呢?

因为,如果没有块级作用域会导致一些不合理的情形出现。

  1. 内层变量可能会覆盖外层变量

 

这个例子,当在函数inner内部if代码块内首先访问变量a时,却得到的是undefined。这是因为紧随其后var声明的同名变量a会变量提升并覆盖全局变量a。所以打印出a的值为undefined。

  1. 计数的循环变量会泄露为 全局变量

 

上面的例子,for循环中的循环变量按道理来说应该只属于for循环体,循环结束就不能再访问。但实际这样用var声明的i,属于外层作用域中的变量,也就是说i泄露为全局变量。所以当执行到console.log(i)时,因为i经过循环已经增加到10,所以打印出i的值为10。

let声明的变量不允许再次重复声明

使用var声明变量,可以多次重复声明一个同名变量。最终变量的值为最后一次声明赋值的结果。

但是,在同一作用域(全局/局部/块级)中不允许使用let重复声明变量。或者说不允许存在与用let声明的变量同名的变量。以下代码都会报错!

 

let声明的全局变量不会作为window对象的一个属性

 

 

let 与const 的区别

在ES6中,上述所有let所具有的特性,对于const来说同样存在。但const与let、var的区别在于const是用来声明常量的。常量具有以下特点:

常量值不可修改

一个常量,一旦声明,任何时间、任何地点都不能修改它的值。

常量在声明时必须必须立即初始化(赋初始值)

不能只声明一个常量名,但不对其进行初始化赋值。否则在声明常量时就会报错。

常量的值不可修改的实质(重要!!)

实际上,常量的值不变,是指常量指向的那个内存地址中所保存的数据不可更改。对于简单的数据类型(数值,字符串、布尔值),他们本身具体的值就保存在常量所指向的那个内存地址中,所以不能修改改简单类型的数据值。

但是,如果一个常量的值是一个引用类型值,那么常量所指向的内存地址中实际保存的是指向该引用类型值的一个指针(也就是引用类型值在内存中的地址)。所以const只能保证该引用类型地址不变,但该地址中的具体数据是可以变化的。

 

 

  1. 模板字符串

在ES6之前,我们往往这么处理模板字符串:
通过“\”和“+”来构建模板

$("body").html("This demonstrates the output of HTML \

content to the page, including student's\

" + name + ", " + seatNumber + ", " + sex + " and so on.");

而对ES6来说

  1. 基本的字符串格式化。将表达式嵌入字符串中进行拼接。用${}来界定;
  2. ES6反引号(``)直接搞定;

$("body").html(`This demonstrates the output of HTML content to the page,

including student's ${name}, ${seatNumber}, ${sex} and so on.`);

 

  1. 箭头函数

ES6 中,箭头函数就是函数的一种简写形式,使用括号包裹参数,跟随一个 =>,紧接着是函数体;

箭头函数最直观的三个特点。

  • 不需要 function 关键字来创建函数
  • 省略 return 关键字
  • 继承当前上下文的 this 关键字

 

// ES5var add = function (a, b) {

    return a + b;

};// 使用箭头函数var add = (a, b) => a + b;

// ES5

[1,2,3].map((function(x){

    return x + 1;

}).bind(this));

    // 使用箭头函数

[1,2,3].map(x => x + 1);

细节:当你的函数有且仅有一个参数的时候,是可以省略掉括号的。当你函数返回有且仅有一个表达式的时候可以省略{} 和 return;

  1. 函数参数默认值

 

// ES6之前,当未传入参数时,text = 'default';function printText(text) {

    text = text || 'default';

    console.log(text);

}

// ES6;function printText(text = 'default') {

    console.log(text);

}

 

printText('hello'); // hello

printText();// default

 

  1. 对象数组解构

// 对象const student = {

    name: 'Sam',

    age: 22,

    sex: '男'

}//

数组// const student = ['Sam', 22, '男'];

// ES5;

const name = student.name;

const age = student.age;

const sex = student.sex;

console.log(name + ' --- ' + age + ' --- ' + sex);

// ES6

const { name, age, sex } = student;

console.log(name + ' --- ' + age + ' --- ' + sex);

 

 

  1. ES6中的类

ES6 中支持 class 语法,不过,ES6的class不是新的对象继承模型,它只是原型链的语法糖表现形式。

函数中使用 static 关键词定义构造函数的的方法和属性:

class Student {

  constructor() {

    console.log("I'm a student.");

  }

 

  study() {

    console.log('study!');

  }

 

  static read() {

    console.log("Reading Now.");

  }

}

 console.log(typeof Student); // functionlet stu = new Student(); // "I'm a student."

stu.study(); // "study!"

stu.read(); // "Reading Now."

类中的继承和超集:

class Phone {

  constructor() {

    console.log("I'm a phone.");

  }

}

 class MI extends Phone {

  constructor() {

    super();

    console.log("I'm a phone designed by xiaomi");

  }

}

 let mi8 = new MI();

extends 允许一个子类继承父类,需要注意的是,子类的constructor 函数中需要执行 super() 函数。
当然,你也可以在子类方法中调用父类的方法,如super.parentMethodName()。
在 这里 阅读更多关于类的介绍。

有几点值得注意的是:

  • 类的声明不会提升(hoisting),如果你要使用某个 Class,那你必须在使用之前定义它,否则会抛出一个 ReferenceError 的错误
  • 在类中定义函数不需要使用 function 关键词

 

 

VUE相关

  • VUE原理

vue是一套构建用户界面的渐进式框架,Vue是一个典型的MVVM框架。

MVVM模式:

MVVM分为Model、View、ViewModel三者。

Model 代表数据模型,数据和业务逻辑都在Model层中定义;

View 代表UI视图,负责数据的展示;

ViewModel 负责监听 Model 中数据的改变并且控制视图的更新,处理用户交互操作;

Model 和 View 并无直接关联,而是通过 ViewModel 来进行联系的,Model 和 ViewModel 之间有着双向数据绑定的联系。因此当 Model 中的数据改变时会触发 View 层的刷新,View 中由于用户交互操作而改变的数据也会在 Model 中同步。

这种模式实现了 Model 和 View 的数据自动同步,因此开发者只需要专注对数据的维护操作即可,而不需要自己操作 dom。

MVC模式:

即 Model-View-Controller 的缩写,就是 模型-视图-控制器 , 也就是说一个标准的Web 应用程式是由这三部分组成的:

View UI布局,展示数据。

Model:管理数据。

Controller 响应用户操作,并将 Model 更新到 View 上。

mvvm和mvc区别?它和其它框架(jquery)的区别是什么?

mvc和mvvm其实区别并不大。都是一种设计思想。主要就是mvc中Controller演变成mvvm中的viewModel。mvvm主要解决了mvc中大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。

区别:vue数据驱动,通过数据来显示视图层而不是节点操作。

 

  • Vue生命周期? Vue 实例从创建到销毁的过程,就是生命周期

beforeCreate  实例初始化后被调用

Created       在实例创建后被调用

beforeMount   在挂载开始之前被调用

Mounted       在实例加载完成被调用

beforeUpdate  在数据更新时调用

Updated       在数据更新后被调用

activated     keep-alive组件激活时调用

deactivated   keep-alive组件停用时调用

beforeDestroy  vue对象销毁之前

Destroy        vue对象销毁之后

errorCaptured  捕获子孙组件的错误时调用

 

Created 和mounted 区别?

在created的时候,视图中的html并没有渲染出来,所以此时如果直接去操作html的dom节点,一定找不到相关的元素

而在mounted中,由于此时html已经渲染出来了,所以可以直接操作dom节点。

 

 

 

  • Vue自定义 directives

 

自定义指令的钩子函数:

  bind: function () {},

  inserted: function () {},

  update: function () {},

  componentUpdated: function () {},

  unbind: function () {}

 

bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。

inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。

update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。

componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。

unbind: 只调用一次, 指令与元素解绑时调用。

 

 

 

 

 

 

  •  vue全家桶包括什么?

全家桶:

Vue-cli:脚手架;

vue核心:vue.js;

Vue-router:路由;

Vuex:状态管理;

Axios: ajax请求

vue-cli是什么?

vue-cli 是vue.js的脚手架,用于自动生成vue.js+webpack的项目模板,分为vue init webpack-simple 项目名 和vue init webpack 项目名 两种。

 

 

 

 

  • 第一次加载页面会触发那几个钩子?

第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子

 

  • Vue生命周期的作用?

它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。

  • 至少说出4种vue的指令及用法?

v-if:判断是否隐藏;v-for:数据循环;v-bind:class:绑定一个属性;v-model:实现双向绑定

vue常用的修饰符

  1. 按键修饰符.delete(捕获“删除”和”退格“键)      用法上和事件修饰符一样,挂载在v-on:后面,语法:v-on:keyup.xxx=’yyy’  <inputclass = 'aaa' v-model="inputValue" @keyup.delete="onKey"/>

b、系统修饰符

可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器

  • .ctrl
  • .alt
  • .shift
  • .meta

c、鼠标按钮修饰符

  • .left
  • .right
  • .middle
    这些修饰符会限制处理函数仅响应特定的鼠标按钮。如:<button @click.middle ="onClick">A</button>  鼠标滚轮单击触发   Click默认是鼠标左键单击

 

 

  • 为什么避免 v-if 和 v-for 在一起 区别?

当Vue 处理指令时,v-for 比 v-if 具有更高的优先级。

 

相同点: 两者都是在判断DOM节点是否要显示

不同点:

  1. 实现方式: v-if是根据后面数据的真假值判断直接从Dom树上删除或重建元素节点。  v-show只是在修改元素的css样式,也就是display的属性值,元素始终在Dom树上。
  • Scss是什么?安装步骤、几大特性?

答:预处理css,把css当前函数编写,定义变量,嵌套。 先装css-loader、node-loader、sass-loader等加载器模块,在webpack-base.config.js配置文件中加多一个拓展:extenstion,再加多一个模块:module里面test、loader

  • 请说下封装vue组件的过程?

答:首先,组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块,解决了我们传统项目开发:效率低、难维护、复用性等问题。

然后,使用Vue.extend方法创建一个组件,然后使用Vue.component方法注册组件。子组件需要数据,可以在props中接受定义。而子组件修改好数据后,想把数据传递给父组件。可以采用emit方法。

  • 说出vue-cli项目中src目录每个文件夹和文件的用法?

答:assets文件夹是放静态资源;components是放组件;router是定义路由相关的配置;view视图;app.vue是一个应用主组件;main.js是入口文件

  • Vue组件传值 常用方法?
  1. 父子组件传值 props  $emit

父传子  props   子组件使用 props 接收。

子传父 

// childByValue是在父组件on监听的方法 // 第二个参数this.childValue是需要传的值

 子组件写一个点击事件,使用this.$emit(‘childByValue’,参数值

  1. 使用 v-model?

父组件通过v-model传递值给子组件时,会自动传递一个value的prop属性,在子组件中通过this.$emit(‘input’,val)自动修改v-model绑定的值

利用默认 input 事件 - 父组件

1

2

3

<template>

  <subComponent  v-model="param"></subComponent>

</template>

利用默认 input 事件 - 子组件

1

2

3

4

5

6

7

8

9

<script >

  export default {

    methods:{

      updateData (newParam) {

        this.$emit('input',newParam)

      }

    }

  }

</script>

这样,我们就能省掉父组件上的一列席处理代码,vue 会自动帮你处理好

 

V-model 传值写法1:一般双向绑定用v-model写法一。

 

 

 

 

 

V-model 传值写法2:

 

 

  1. $parent 和$children组件传值?

子组件:

 

 

父组件:

 

 

 

  • vue中计算属性computed和watch侦听器?

Computed:

如果 computed 所依赖的数据发生改变时,计算属性才会重新计算,并进行缓存;当改变其他数据时,computed 属性 并不会重新计算,从而提升性能。

Watch:

immediate和handler

 

watch时有一个特点,就是当值第一次绑定的时候,不会执行监听函数,只有值发生改变才会执行。如果我们需要在最初绑定值的时候也执行函数,则就需要用到immediate属性。

 

Immediate:表示在watch中首次绑定的时候,是否执行handler,值为true则表示在watch中声明的时候,就立即执行handler方法,值为false,则和一般使用watch一样,在数据发生变化的时候才执行handler。

 

 

 

deep

当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听。

 

设置deep: true 则可以监听到cityName.name的变化,此时会给cityName的所有属性都加上这个监听器,当对象属性较多时,每个属性值的变化都会执行handler。如果只需要监听对象中的一个属性值,则可以做以下优化:使用字符串的形式监听对象属性:

 

这样只会给对象的某个特定的属性加监听器。

数组(一维、多维)的变化不需要通过深度监听,对象数组中对象的属性变化则需要deep深度监听。

 

 

 

  • Vue路由跳转?

声明式(标签跳转) 编程式( js跳转)

声明

1.直接修改地址栏中的路由地址 

②通过router-link实现跳转

编程式: 在js里 this.$router.push(‘路由地址’)

Router-link 标签 相等于a标签  实现路由跳转、 to是路由的路径

 

Router-view标签  用于路由展示  不能设置样式、 最后外层拿div包裹起来用于调整位置

 

 

Router-link-active: class类作用?

 

 

 

Vue 路由 导航守卫全局守卫、路由独享守卫、组件内守卫

一.全局守卫

 router.beforeEach((to,from,next)=>{})

回调函数中的参数,to:进入到哪个路由去,from:从哪个路由离开,next:函数,决定是否展示你要看到的路由页面。

·  在main.js中,有一个路由实例化对象router。在main.js中设置守卫已是全局守卫。

·  如下,判断to.path当前将要进入的路径是否为登录或注册,如果是就执行next(),展示当前界面。如果不是,就弹出alert,然后移至登录界面。

·  这样就可实现,用户在未登录状态下,展示的一直是登录界面。

 

router.beforeEach((to,from,next)=>{

  if(to.path == '/login' || to.path == '/register'){

    next();

  }else{

    alert('您还没有登录,请先登录');

    next('/login');

  }

})

全局后置钩子router.afterEach((to,from)=>{})

 

 

  • 只有两个参数,to:进入到哪个路由去,from:从哪个路由离。
  • 如下,每次切换路由时,都会弹出alert,点击确定后,展示当前页面。

router.afterEach((to,from)=>{

  alert("after each");

})

 

 

二.组件内的守卫

 到达这个组件时,beforeRouteEnter:(to,from,next)=>{}

·  在Admin.vue文件中,点击转到admin路由时,执行beforeRouteEnter函数

·  to,from参数与上面使用方法一致。next回调函数略有不同。

·  如下例,data 组件内守卫有特殊情况,如果我们直接以
beforeRouteEnter:(to,from,next)=>{ alert("hello" + this.name);}进行访问admin页面,会发现alert输出hello undefined。这是因为,现在访问不到我们的data属性,执行顺序是不一致,这与的声明周期有关。在执行完之前,data数据还未渲染。所以这里,next()会给一个对应的回调,帮助完成。

<script>export default {

    data(){

        return{

            name:"Arya"

        }

    },

    beforeRouteEnter:(to,from,next)=>{

        next(vm=>{

            alert("hello" + vm.name);

        })

    }

}</script>

 

离开这个组件时,beforeRouteLeave:(to,from,next)=>{}

  • 点击其他组件时,判断是否确认离开。确认执行next();取消执行next(false),留在当前页面。

beforeRouteLeave:(to,from,next)=>{

        if(confirm("确定离开此页面吗?") == true){

            next();

        }else{

            next(false);

        }

    }

 

三.路由独享的守卫

beforeEnter:(to,from,next)=>{},用法与全局守卫一致。只是,将其写进其中一个路由对象中,只在这个路由下起作用。

 

 

 

  1. vue.cli中怎样使用自定义的组件?遇到的问题?
  •  Vue.cli中 怎么使用自定义组件? 遇到的问题?

·         第一步:在components目录新建你的组件文件(如:indexPage.vue),script一定要export default {}

·       第二步:在需要用的页面(组件)中导入:import indexPage from '@/components/indexPage.vue'

·  第三步:注入到vue的子组件的components属性上面,components:{indexPage}

·        第四步:在template视图view中使用,
遇到的问题: 比如有indexPage命名,使用的时候则index-page

  • Vuex 是什么? 怎么使用? 那个场景使用?

vue框架中状态管理。在main.js引入store,注入。新建一个目录store,….. export 。场景有:单页应用中,组件之间的状态。音乐播放、登录状态、加入购物车

  • Vuex 有哪些属性?

有五种,分别是 State、getters、mutations、actions、modules

  • V-if   v-show共同点 不同点?

·         v-show指令是通过修改元素的display的CSS属性让其显示或者隐藏

·         v-if指令是直接销毁和重建DOM达到让元素显示和隐藏的效果

  • Vue中解决跨域?

1、proxyTable

  这里vue脚手架生成的标准项目为准。一般在项目config目录下面有个index文件。里面格式如下:

 

上面配置中,我们根据实际情况只需要修改proxyTable对于配置即可。假设我后端请求地址是http://localhost:7001,所有api的接口url都以/api开头。所以首先需要匹配所有以/api开头的.然后修改target的地址为http://localhost:7001。最后修改pathRewrite地址。将前缀 '^api' 转为 '/api'。如果本身的接口地址就有 '/api' 这种通用前缀,就可以把 pathRewrite 删掉。注意这个方式只能在开发环境中使用。

  1. CORS

 CORS即跨源资源共享,它定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。它是一个妥协,有更大的灵活性,但比起简单地允许所有这些的要求来说更加安全。但是CORS也具有一定的风险性,比如请求中只能说明来自于一个特定的域但不能验证是否可信,而且也容易被第三方入侵。 这里一般需要后端配合,开启cors。一般各种语言都有类似的包。比如NodeJS的koa2-cors

 

这个方式解决的跨越问题支持开发和生产环境。但是有一定的安全性问题。

  1. Nginx

当我们明白跨越的含义之后。只要解决了'源'的问题。那么跨越也就不存在了。这里我们便会想到proxy,同时也会想到Nginx。

我们只需要在部署静态资源配置下面加上红框里面的配置就可以了。同时这个方法支持开发环境和生产环境。

 

后端程序代理

当然上面2个方法都需要后端的配合和需要修改服务器配置。所有还有一种方法不需要他们配合 ,我们自己就可以做到。就是我们自己启一个后端程序做代理。

 

 

 

 

 

  • Active-class 是那个组件的属性/

vue-router模块的router-link组件。

路由传参:vue-router的动态路由与如何获取传过来的动态参数?

1、在router目录下的index.js文件中,对path属性加上/:id。

在子组件中可以使用来获取传递的参数值this.$route.params.id

2、通过路由属性中的name来确定匹配的路由,通过params来传递参数。

在子组件中可以使用来获取传递的参数值this.$route.params.id

3、父组件:使用path来匹配路由,然后通过query来传递参数
这种情况下 query传递的参数会显示在url后面?id=?

    this.$router.push({

          path: '/describe',

          query: {

            id: id

          }

        })

对应路由配置:

   {

     path: '/describe',

     name: 'Describe',

     component: Describe

   }

对应子组件: 这样来获取参数

this.$route.query.id

这里要特别注意 在子组件中 获取参数的时候是$route.params 而不是
$router 这很重要~~~

 

V-el 代表什么: 通过v-el我们可以获取到DOM对象。

Vue定义动态路由 ?

 

 

 

  • Require.js 和 seajs前端模块化?

它们都是前端模块化开发依赖管理的代码工具

  requirejs 与 seajs 的不同:

      1) seajs 引入模块的根目录是 sea.js 文件所在的目录, requirejs 的根目录是 引入require.js 的html文件所在目录

      2) 模块内引入其他模块, seajs 依然是相对seajs所在根目录为基础, 但是 requirejs 则是相对当前文件为基础的相对路径

      3) seajs 可以使用 define 传递一个字符串定义一个模块,但是require不行

  • 预处理器、 less、sass:

都是一种动态的样式语言,属于css的预处理器,比如:变量,继承,运算,函数等, 更加方便css的书写和维护

区别:

1) . Sass的安装需要Ruby环境,是在服务端处理的,而Less是需要引入less.js来处理Less代码输出css到浏览器

2) . 变量符不一样,Less是@,而Scss是$,而且变量的作用域也不一样。

3) . Sass支持条件语句,可以使用if{}else{},for{}循环等等。而Less不支持。等....

  • Vue 与其他框架区别?

1.与AngularJS的区别

相同点:

都支持指令:内置指令和自定义指令。

都支持过滤器:内置过滤器和自定义过滤器。

都支持双向数据绑定。

都不支持低端浏览器。

不同点:

1.AngularJS的学习成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比较简单、直观。

2.在性能上,AngularJS依赖对数据做脏检查,所以Watcher越多越慢。

Vue.js使用基于依赖追踪的观察并且使用异步队列更新。所有的数据都是独立触发的。

对于庞大的应用来说,这个优化差异还是比较明显的。

2.与React的区别

相同点:

React采用特殊的JSX语法,Vue.js在组件开发中也推崇编写.vue特殊文件格式,对文件内容都有一些约定,两者都需要编译后使用。

中心思想相同:一切都是组件,组件实例之间可以嵌套。

都提供合理的钩子函数,可以让开发者定制化地去处理需求。

都不内置列数AJAX,Route等功能到核心包,而是以插件的方式加载。

在组件开发中都支持mixins的特性。

不同点:

React依赖Virtual DOM,而Vue.js使用的是DOM模板。React采用的Virtual DOM会对渲染出来的结果做脏检查。

Vue.js在模板中提供了指令,过滤器等,可以非常方便,快捷地操作DOM。

 

  • Ajax、axios、fetch的区别?

Ajax:方法里面需要传入一个对象参数,里面包括了一些常见的参数,其实jquery维护了这么多年了,ajax请求其实已经很方便了,如果非要说有什么缺点的话,就是依然对回调嵌套不方便,然后就是如果为了一个JqueryAjax就引入整个jquery,文件比较大,成本过高。

 

Fetch:我们可以看到IE浏览器完全不支持Fetch,并且移动端的很多浏览器也不支持Fetch,不过可以使用第三方的Fetch polyfill来获得支持

 

 

 

 

1、fetch() 返回的是一个Promise对象。

fetch使用的promise对象可以使得我们使用同步的方式写异步函数。

2、 fetch api是可以结合 async 和 await 来使用的。 

fetch是基于promise实现的,但是使用promise的写法,我们还是可以看到callback的影子,如果结合 async和await来使用,还是非常不错的。

3、 Fetch api 提供的spi囊括但是不限于xhr的所有功能。

4、 fetch api 可以跨域。 

  跨域请求必须包括  Origin 作为header. 

 

 

 

 

 

 

 

其实有这么多种的请求方法和解决方案,总结一下:原生XHR几乎很少开发会用,JqueryAjax属于老当益壮的那种,虽然很老,但是很好用,Fetch是属于初生牛犊,还需要慢慢成长,axios就目前来说,算是非常好的了,无脑使用即可.

 

 

 

 

 

  • 什么是json-server?

JSON-Server 是一个 Node 模块,运行 Express 服务器,你可以指定一个 json 文件作为 api 的数据源。

  • 2
  • 2
  • 22
  •  

Git相关

mkdir  创建目录

cd  进入

pwd 查看当前路径

Clear 清空操作

git init 初始化仓库

git add 添加到目录

Git rm --cached <文件名>  删除某个文件

Git add . 上传所有文件

Git add *.html 上传某一类文件

git status 仓库当前状态

Git commit -m “描述信息”:提交到仓库

git log 查看历史操作记录

git log --pretty=oneline 将输出的信息改成一行

git reset--hard HEAD^ 回退到上一个版本

git reset--haed HEAD~100 回退到上一百个版本

git reflog 查看git操作日志

git rm    git当中删除文件

git remote  关联一个远程仓库

git remote remove origin 删除关联的某一个仓库

git push master origin  

git checkout-b 分支名称     创建并切换分支

git merge 分支名称       合并分支

git branch-d 分支名称    删除分支

git branch-D 分支名称    强制删除没有被合并的分支

git merge--no-ff         禁用fast forword分支

git stach            保存当前工作状态

git stash list    查看刚才的工作现场保存了几次

git stash pop   恢复工作现场并删除stach保存记录

 

小程序相关

  • 小程序生命周期?

生命周期是指一个小程序从创建到销毁的一系列过程

在小程序中 ,通过App()来注册一个小程序 ,通过Page()来注册一个页面

先来看一张小程序项目结构

 

从上图可以看出,根目录下面有包含了app.js,app.wxss,app.json三个文件

这是小程序的全局文件,app.js是小程序逻辑 ,app.json是小程序公共设置,app.wxss是小程序公共样式表

在app.js文件中 , 定义了一些生命周期方法 , onLaunch,onShow,onHide,onError,以及任意开发者添加的函数或者数据(通过this可以访问)

以下是各个生命周期方法作用和描述

onLaunch 生命周期函数--监听小程序初始化 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)

onShow 生命周期函数--监听小程序显示 当小程序启动,或从后台进入前台显示,会触发 onShow

onHide 生命周期函数--监听小程序隐藏 当小程序从前台进入后台,会触发 onHide

onError 错误监听函数 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息

这是我们打开一个小程序打印出来的一些方法

可以看出, 打开程序依次执行了app.js下面onLaunch和onShow方法,以及page页面中的onLoad,onShow和onReady方法

其中 , onLaunch, onShow 方法会返回一个参数对象, 里面包含了三个参数 , path,query和scene ,path是打开小程序的路径

query是打开小程序页面url的参数,scene是打开小程序的场景值

在page页面中定义的生命周期方法

onLoad 生命周期函数--监听页面加载

onReady 生命周期函数--监听页面初次渲染完成

onShow 生命周期函数--监听页面显示

onHide 生命周期函数--监听页面隐藏

onUnload 生命周期函数--监听页面卸载

 

 

 

 

 

 

 

  • 2
  •  

 

 

其他相关

  • 常见的javascript设计模式?
  •  

 

 

① 单体模式:单体模式在我们平时的应用中用的比较多的,相当于把我们的代码封装在一个起来,只是暴露一个入口,从而避免全部变量的污染。

② 工厂模式:

 

 

 

 

 

 

 

24种设计模式(gof23+1):

  • 创建型模式:
    1. 简单工厂模式(不包含在gof23中)
    2. 工厂模式
    3. 抽象工厂模式
    4. 单例模式
    5. 原型模式
    6. 创建者模式
  • 结构型模式:
    1. 组合模式
    2. 装饰者模式
    3. 外观模式
    4. 适配器模式
    5. 代理模式
    6. 享元模式
    7. 桥接模式
  • 行为型模式:
    1. 观察者模式
    2. 策略模式
    3. 状态模式
    4. 中介模式
    5. 模板方法
    6. 命令模式
    7. 备忘录模式
    8. 访问者模式
    9. 解释器模式
    10. 迭代器模式
    11. 职责链模式

 

 

 

 

 

 

 

 

 

 

相关资讯

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?