(完整版)前端面试题及答案2019.doc
-面试题-1 vuex的五个状态 VueX 是一个专门为 Vue.js 应用设计的状态管理架构,统一管理和维护各个vue组件的可变化状态(你可以理解成 vue 组件里的某些 data )。Vue有五个核心概念,state, getters, mutations, actions, modules。state => 基本数据 =datagetters => 从基本数据派生的数据 =computedmutations => 提交更改数据的方法,同步! =methodsactions => 像一个装饰器,包裹mutations,使之可以异步。 modules => 模块化Vuex 2 vue周期 (钩子函数) created可获取数据 Mounted可操作DOMVue实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载Dom、渲染更新渲染、销毁等一系列过程,我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程,就是生命周期。分为三个阶段:初始化、运行中、销毁。beforeCreate:实例、组件通过new Vue() 创建出来之后会初始化事件和生命周期,然后就会执行beforeCreate钩子函数,这个时候,数据还没有挂载呢,只是一个空壳,无法访问到数据和真实的dom,一般不做操作Created:挂载数据,绑定事件等等,然后执行created函数,这个时候已经可以使用到数据,也可以更改数据,在这里更改数据不会触发updated函数,在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取beforeMount:接下来开始找实例或者组件对应的模板,编译模板为虚拟dom放入到render函数中准备渲染,然后执行beforeMount钩子函数,在这个函数中虚拟dom已经创建完成,马上就要渲染,在这里也可以更改数据,不会触发updated,在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取Mounted:接下来开始render,渲染出真实dom,然后执行mounted钩子函数,此时,组件已经出现在页面中,数据、真实dom都已经处理好了,事件都已经挂载好了,可以在这里操作真实dom等事情.beforeUpdate:当组件或实例的数据更改之后,会立即执行beforeUpdate,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染,一般不做什么事儿Updated:当更新完成后,执行updated,数据已经更改完成,dom也重新render完成,可以操作更新后的虚拟dombeforeDestroy:当经过某种途径调用$destroy方法后,立即执行beforeDestroy,一般在这里做一些善后工作,例如清除计时器、清除非指令绑定的事件等等Destroyed:组件的数据绑定、监听.去掉后只剩下dom空壳,这个时候,执行destroyed,在这里做善后工作也可以钩子函数的的实际应用beforecreate : 举个栗子:可以在这加个loading事件 created :在这结束loading,还做一些初始化,实现函数自执行 mounted : 在这发起后端请求,拿回数据,配合路由钩子做一些事情beforeDestroy: 你确认删除XX吗? destroyed :当前组件已被删除,清空相关内容3 cookie、localstroge、localSeesion的区别共同点:都是保存在浏览器端,且同源的。区别: 安全性、大小、有效期、作用域1 cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。2存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。3 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。4 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。4 get和post区别get参数通过url传递,post放在request body中。 传递路径get请求在url中传递的参数是有长度限制的,而post没有。 长度限制get比post更不安全,因为参数直接暴露在url中,所以不能用来传递敏感信息。 安全get请求只能进行url编码,而post支持多种编码方式 编码方式get请求会浏览器主动cache,而post支持多种编码方式。get请求参数会被完整保留在浏览历史记录里,而post中的参数不会被保留。 保存GET和POST本质上都是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。5 你是如何操持登录1利用Token实现APP登录成功后,服务器以某种方式,如随机生成N位的字符串作为Token,同时设置一个有效期,存储到服务器中,并返回Token给APP。后续APP发送请求时,都要带上该Token,每次服务器端收到请求时,都要验证Token和有效期,Token数值对且在有效期内,服务器返回所需要的结果,否则返回错误信息,提示用户重新登录。(这种方式目前使用的最多)2利用Cookie实现APP登录成功后,服务器创建一个包含session_id和Expires两个属性值的Cookie,存储在服务器中,并发送给APP。后续APP发送请求时,都要带上一个包含此session_id的Cookie,每次服务器端收到请求时,都要验证session_id和有效期,session_id数值对且在有效期内,服务器返回所需要的结果,否则返回错误信息,提示用户重新登录。6 vue怎么实现双向数据绑定vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的。其实主要是用了Es5中的Object.defineProperty;来劫持每个属性的getter,和setter。这也正是Vue不兼容IE8以下的原因。发布者-订阅者模式:订阅是请求在某些事件(event)到达时可以通知它并执行对应的动作(action),而发布则相对的是向订阅告知事件(event)已经到达,你可以执行对应的动作(action)了。7 promise 的简述Promise 是异步编程的一种解决方案,通俗的来讲Promise是一个许诺、承诺,是对未来事情的承诺,承诺不一定能完成,但是无论是否能完成都会有一个结果。 应用场景1 解决回调地狱 比如我们经常可能需要异步请求一个数据之后作为下一个异步操作的入参2 promise 可以实现在多个请求发送完成后 再得到或者处理某个结果最简单的实现基于上面的应用场景发现promise可以有三种状态,分别是pending 、Fulfilled、Rejected。Pending Promise对象实例创建时候的初始状态Fulfilled 可以理解为成功的状态Rejected可以理解为失败的状态构造一个Promise实例需要给Promise构造函数传入一个函数。传入的函数需要有两个形参,两个形参都是function类型的参数。分别是resolve和reject。Promise上还有then方法,then 方法就是用来指定Promise 对象的状态改变时确定执行的操作,resolve 时执行第一个函数(onFulfilled),reject时执行第二个函数(onRejected)当状态变为resolve时便不能再变为reject,反之同理。基本api(1) new Promise(2) PromiseObj.then(resolveFn,rejectFn)resolveFn:就是Promise对象成功的回调处理函数,指向 resolverejectFn:就是Promise对象失败的回调处理函数(3) Promise.all() 这个静态方法的参数是一个可迭代的对象,这个对象的item应该都是promise对象,若不是的话,就会先调用上面的Promise.resolve(item)方法转换成新的promise对象。 Promise.all()方法返回的也是一个promise对象。 (4) PromiseObj.resolve() 将一个值,数字,字符串.转换为Promise对象(5) Promise.reject(reason) 方法返回一个用reason拒绝的Promise。你可以这样理解,返回的这个promise对象在初始化的时候,什么都没有做,直接给reject(your reject reson)8 es6的了解es6是一个新的标准,它包含了许多新的语言特性和库,是JS实质性的一次升级。新增模板字符串 (为JavaScript提供了简单的字符串插值功能)箭头函数(操作符左边为输入的参数,而右边则是进行的操作以及返回的值Inputs=>outputs。)for-of(用来遍历数据例如数组中的值。)for (let index of 'a', 'b'.keys() console.log(index);arguments对象可被不定参数和默认参数完美代替。ES6将promise对象纳入规范,提供了原生的Promise对象。增加了let和const命令,用来声明变量。增加了块级作用域。let命令实际上就增加了块级作用域。ES6规定,var命令和function命令声明的全局变量,属于全局对象的属性;let命令、const命令class命令声明的全局变量,不属于全局对象的属性。还有就是引入module模块的概念9 路由拦截主要是利用vue-router提供的钩子函数beforeEach()对路由进行判断。* to: Route: 即将要进入的目标 路由对象 $route (常用)* from: Route: 当前导航正要离开的路由 * next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。 * next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。 * next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。 * next(/) 或者 next( path: / ): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。10 vue路由传值 (主要使用三种方法)$router.push/ name+params/ path+query方案一getDescribe(id) / 直接调用$router.push 实现携带参数的跳转 this.$router.push( path: /describe/$id, )/ 方案一,需要对应路由配置如下: path: '/describe/:id', name: 'Describe', component: Describe / 很显然,需要在path中添加/:id来对应 $router.push 中path携带的参数。/ 在子组件中可以使用$route.params.id来获取传递的参数值。方案二/ 父组件中:通过路由属性中的name来确定匹配的路由,通过params来传递参数。 this.$router.push( name: 'Describe', params: id: id )/ 对应路由配置: 注意这里不能使用:/id来传递参数了,因为父组件中,已经使用params来携带参数了。 path: '/describe', name: 'Describe', component: Describe /子组件中: 这样来获取参数 $route.params.id方案三/ 父组件:使用path来匹配路由,然后通过query来传递参数 这种情况下 query传递的参数会显示在url后面?id=? this.$router.push( path: '/describe', query: id: id )/ 对应路由配置: path: '/describe', name: 'Describe', component: Describe / 对应子组件: 这样来获取参数$route.query.id/ 这里要特别注意 在子组件中 获取参数的时候是$route.params 而不是$router 11 从输入URL到页面加载的过程1 DNS解析2 TCP连接3发送HTTP请求4服务器处理请求并返回HTTP报文5浏览器解析渲染页面6连接结束12 js冒泡排序(双重for循环+if判断+交换位置)13 http状态码一些常见的状态码为:200 - 服务器成功返回网页404 - 请求的网页不存在503 - 服务不可用详细分解:1xx(临时响应)表示临时响应并需要请求者继续执行操作的状态代码。100 (继续) 请求者应当继续提出请求。服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。 101 (切换协议) 请求者已要求服务器切换协议,服务器已确认并准备切换。2xx (成功)表示成功处理了请求的状态代码。200 (成功) 服务器已成功处理了请求。通常,这表示服务器提供了请求的网页。201 (已创建) 请求成功并且服务器创建了新的资源。202 (已接受) 服务器已接受请求,但尚未处理。203 (非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。204 (无内容) 服务器成功处理了请求,但没有返回任何内容。205 (重置内容) 服务器成功处理了请求,但没有返回任何内容。206 (部分内容) 服务器成功处理了部分 GET 请求。3xx (重定向)表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。300 (多种选择) 针对请求,服务器可执行多种操作。服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。301 (永久移动) 请求的网页已永久移动到新位置。服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。303 (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。304 (未修改) 自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。305 (使用代理) 请求者只能使用代理访问请求的网页。如果服务器返回此响应,还表示请求者应使用代理。307 (临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。4xx(请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。400 (错误请求) 服务器不理解请求的语法。401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。403 (禁止) 服务器拒绝请求。404 (未找到) 服务器找不到请求的网页。405 (方法禁用) 禁用请求中指定的方法。406 (不接受) 无法使用请求的内容特性响应请求的网页。407 (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。408 (请求超时) 服务器等候请求时发生超时。409 (冲突) 服务器在完成请求时发生冲突。服务器必须在响应中包含有关冲突的信息。410 (已删除) 如果请求的资源已永久删除,服务器就会返回此响应。411 (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。412 (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。413 (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。414 (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。415 (不支持的媒体类型) 请求的格式不受请求页面的支持。416 (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。417 (未满足期望值) 服务器未满足"期望"请求标头字段的要求.5xx(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。500 (服务器内部错误) 服务器遇到错误,无法完成请求。501 (尚未实施) 服务器不具备完成请求的功能。例如,服务器无法识别请求方法时可能会返回此代码。502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。通常,这只是暂时状态。504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。HttpWatch状态码Result is200 - 服务器成功返回网页,客户端请求已成功。 302 - 对象临时移动。服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。304 - 属于重定向。自上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。401 - 未授权。请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。404 - 未找到。服务器找不到请求的网页。2xx - 成功。表示服务器成功地接受了客户端请求。3xx - 重定向。表示要完成请求,需要进一步操作。客户端浏览器必须采取更多操作来实现请求。例如,浏览器可能不得不请求服务器上的不同的页面,或通过代理服务器重复该请求。4xx - 请求错误。这些状态代码表示请求可能出错,妨碍了服务器的处理。5xx - 服务器错误。表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。14 js中的原型链每个对象都会在其内部初始化一个属性,就是prototype(原型),当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下去,也就是我们平时所说的原型链的概念。应用:原型链是实现继承的主要方法。15 闭包是什么,有什么特性,对页面有什么影响通俗的讲:就是函数a的内部函数b,被函数a外部的一个变量引用的时候,就创建了一个闭包。闭包的特性:.封闭性:外界无法访问闭包内部的数据,如果在闭包内声明变量,外界是无法访问的,除非闭包主动向外界提供访问接口;.持久性:一般的函数,调用完毕之后,系统自动注销函数,而对于闭包来说,在外部函数被调用之后,闭包结构依然保存在系统中,闭包中的数据依然存在,从而实现对数据的持久使用。优点: 减少全局变量。 减少传递函数的参数量 封装; 缺点: 使用闭包会占有内存资源,过多的使用闭包会导致内存溢出等.16怎么实现跨域请求1、jsonp最常见的一种跨域方式,其背后原理就是利用了 script 标签不受同源策略的限制,在页面中动态插入了 script,script 标签的 src 属性就是后端 api 接口的地址,并且以 get 的方式将前端回调处理函数名称告诉后端,后端在响应请求时会将回调返还,并且将数据以参数的形式传递回去。jsonp 只能发送 get 请求。2、CORSCross-Origin Resource Sharing(跨域资源共享)是一种允许当前域(origin)的资源(比如html/js/web service)被其他域(origin)的脚本请求访问的机制。当使用 XMLHttpRequest 发送请求时,浏览器如果发现违反了同源策略就会自动加上一个请求头 origin,后端在接受到请求后确定响应后会在 Response Headers 中加入一个属性 Access-Control-Allow-Origin,值就是发起请求的源地址(http:/127.0.0.1:8888),浏览器得到响应会进行判断 Access-Control-Allow-Origin 的值是否和当前的地址相同,只有匹配成功后才进行响应处理。现代浏览器中和移动端都支持 CORS(除了opera mini),IE 下需要8+3、服务器跨域在前后端分离的项目中可以借助服务器实现跨域,具体做法是:前端向本地服务器发送请求,本地服务器代替前端再向真实服务器接口发送请求进行服务器间通信,本地服务器其实充当个中转站的角色,再将响应的数据返回给前端缺点:服务器跨域需要另起服务器4、postmessage跨域在 HTML5 中新增了 postMessage 方法,postMessage 可以实现跨文档消息传输 Cross Document Messaging,IE8,Firefox 3,Opera 9,Chrome 3 和 Safari 4 都支持 postMessage。该方法可以通过绑定 window 的 message 事件来监听发送跨文档消息传输内容。使用 postMessage 实现跨域的话原理就类似于 jsonp,动态插入 iframe标签,再从 iframe 里面拿回数据,私认为用作跨页面通信更加适合总结当然还有其他实现跨域的方式比如在ie8、9下 XDR 跨域方案,flash 方案,以上是一些常用的跨域方案,都各有利弊,比如:jsonp 只能发送 get 请求、服务器跨域需要另起服务器等等,大家可以根据自己项目需求选择适合的解决方案,17 介绍一下js的同源策略-安全同源策略是由 Netscape 提出的著名安全策略,是浏览器最核心、基本的安全功能,它限制了一个源(origin)中加载文本或者脚本与来自其他源(origin)中资源的交互方式,所谓的同源就是指协议、域名、端口相同。当浏览器执行一个脚本时会检查是否同源,只有同源的脚本才会执行,如果不同源即为跨域18 引入样式表的方式内样式、内部样式表、外部样式表。一 行内样式使用style属性引入CSS样式。二 内部样式表在style标签中书写CSS代码。style标签写在head标签中。三 外部样式表CSS代码保存在扩展名为.css的样式表中HTML文件引用扩展名为.css的样式表,有两种方式:链接式、导入式。19 面向对象、面向过程的区别面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。 面向过程优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、 Linux/Unix等一般采用面向过程开发,性能是最重要的因素。 缺点:没有面向对象易维护、易复用、易扩展。面向对象优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统 更加灵活、更加易于维护 缺点:性能比面向过程低20 面向对象的特点1.封装 所谓封装,就是将客观事物封装成抽象的类,并且类可以把数据和方法让可信的类或者对象进行操作,对不可信的类或者对象进行隐藏。类就是封装数据和操作这些数据代码的逻辑实体。在一个类的内部,某些属性和方法是私有的,不能被外界所访问。通过这种方式,对象对内部数据进行了不同级别的访问控制,就避免了程序中的无关部分的意外改变或错误改变了对象的私有部分。2.继承 继承有这样一种能力,就是能使用现有的类的所有功能,并无须重新编写原来的这些类的基础上对这些功能进行扩展。通过继承创建的新类称为子类或派生类,被继承的称为基类。继承有两种,一种是实现继承,另外一种是接口继承。实现继承可以直接使用基类的属性和方法而无需额外编码,接口继承是指使用属性和方法的名称,但是子必须提供实现的能力。 3.多态 所谓多态就是对一个实例的相同方法在不同的情形下有不同的表现形式。多态机制使得不同内部结构的对象可以共享相同的外部接口,这就意味着,虽然不同的类的内部操作不同,但可以通过一个公共的类,它们可以通过相同的方式予以调用。21 jquery动画jQuery animate() 方法用于创建自定义动画。语法:$(selector).animate(params,speed,callback);必需的 params 参数定义形成动画的 CSS 属性。可选的 speed 参数规定效果的时长。它可以取以下值:"slow"、"fast" 或毫秒。可选的 callback 参数是动画完成后所执行的函数名称。22 数组去重1.遍历数组法 它是最简单的数组去重方法(indexOf方法)实现思路:新建一个数组,遍历去要重的数组,当值不在新数组的时候(indexOf为-1)就加入该新数组中;var arr=2,8,5,0,5,2,6,7,2;function unique1(arr) var hash=; for (var i = 0; i < arr.length; i+) if( hash.indexOf(arri)=-1) hash.push(arri); return hash;2.数组下标判断法 调用indexOf方法,性能和方法1差不多实现思路:如果当前数组的第 i 项在当前数组中第一次出现的位置不是 i,那么表示第 i 项是重复的,忽略掉。否则存入结果数组。function unique2(arr) var hash=; for (var i = 0; i < arr.length; i+) if(arr.indexOf(arri)=i) hash.push(arri); return hash;3.排序后相邻去除法 实现思路:给传入的数组排序,排序后相同的值会相邻,然后遍历排序后数组时,新数组只加入不与前一值重复的值。function unique3(arr) arr.sort(); var hash=arr0; for (var i = 1; i < arr.length; i+) if(arri!=hashhash.length-1) hash.push(arri); return hash;4.优化遍历数组法(推荐)实现思路:双层循环,外循环表示从0到arr.length,内循环表示从i+1到arr.length将没重复的右边值放入新数组。(检测到有重复值时终止当前循环同时进入外层循环的下一轮判断)function unique4(arr) var hash=; for (var i = 0; i < arr.length; i+) for (var j = i+1; j < arr.length; j+) if(arri=arrj) +i; hash.push(arri); return hash;5.ES6实现ES6中新增了Set数据结构,类似于数组,但是 它的成员都是唯一的 ,其构造函数可以接受一个数组作为参数,如: let array = 1, 1, 1, 1, 2, 3, 4, 4, 5, 3; let set = new Set(array); console.log(set); / => Set 1, 2, 3, 4, 5ES6中Array新增了一个静态方法Array.from,可以把类似数组的对象转换为数组,如通过querySelectAll方法得到HTML DOM Node List,以及ES6中新增的Set和Map等可遍历对象,如: let set = new Set(); set.add(1).add(2).add(3); let array = Array.from(set); console.log(array); / => 1, 2, 323 盒子居中1)使用CSS方法:父盒子设置:display:table-cell; text-align:center;vertical-align:middle;Div设置: display:inline-block;vertical-align:middle;2)使用CSS3 transform:父盒子设置:display:relativeDiv设置:transform: translate(-50%,-50%);position: absolute;top: 50%;left: 50%;24 jsonp的使用最常见的一种跨域方式,其背后原理就是利用了 script 标签不受同源策略的限制,在页面中动态插入了 script,script 标签的 src 属性就是后端 api 接口的地址,并且以 get 的方式将前端回调处理函数名称告诉后端,后端在响应请求时会将回调返还,并且将数据以参数的形式传递回去。25 vue组件之间的传值问题组件关系可分为父子组件通信、兄弟组件通信。1、父组件向子组件:父组件可以使用 props 把数据传给子组件。2、 子组件向父组件:子组件可以使用 $emit 触发父组件的自定义事件。子组件用$emit ()来触发事件,父组件用$on()来监昕子组件的事件。父组件可以直接在子组件的自定义标签上使用v-on 来监昕子组件触发的自定义事件。3、兄弟之间的通信:通过实例一个vue实例Bus作为媒介const bus = new Vue(),要相互通信的兄弟组件之中都引入Bus,之后通过分别调用Bus事件触发和监听来实现组件之间的通信和参数传递。26 性能优化(1) 减少http请求次数:CSS Sprites, JS、CSS源码压缩、图片大小控制合适;网页Gzip,CDN托管,data缓存 ,图片服务器。(2) 前端模板 JS+数据,减少由于HTML标签导致的带宽浪费,前端用变量保存AJAX请求结果,每次操作本地变量,不用请求,减少请求次数(3) 用innerHTML代替DOM操作,减少DOM操作次数,优化javascript性能。(4) 当需要设置的样式很多时设置className而不是直接操作style。(5) 少用全局变量、缓存DOM节点查找的结果。减少IO读取操作。(6) 避免使用CSS Expression(css表达式)又称Dynamic properties(动态属性)。(7) 图片预加载,将样式表放在顶部,将脚本放在底部。或者懒加载。(8) 避免在页面的主体布局中使用table,table要等其中的内容完全下载之后才会显示出来,显示比div+css布局慢。27 深拷贝28 vue中ref的作用是什么?ref 被用来给DOM元素或子组件注册引用信息。引用信息会根据父组件的 $refs 对象进行注册。如果在普通的DOM元素上使用,引用信息就是元素; 如果用在子组件上,引用信息就是组件实例注意:只要想要在Vue中直接操作DOM元素,就必须用ref属性进行注册怎么防止元素重复绑定事件29 ProxyVue 框架开发的时候,会遇到跨域的问题,可在config/index.js 里配置proxyTable内容,使用proxy 代理。/ config/index.js 文件proxyTable: '/api': target: 'http:/192.168.149.90:8080/', / 设置你调用的接口域名和端口号 changeOrigin: true, / 跨域 pathRewrite: '/api': '/' ,这里理解成用/api'代替target里面的地址,后面组件中我们掉接口时直接用api代替 比如我要调用'http:/192.168.149.90:8080/xxx/duty?time=2017-07-07 14:57:22',直接写/api/xxx/duty?time=2017-07-07 14:57:22'即可在de