HTML&CSS方面
1、CSS选择器权重-
- !important > 行内样式 > id选择器 > 类选择器 > 标签选择器 > 通配符 > 继承
-
- 在我们HTML页面中,每一个元素都可以被看作一个盒子,而这个盒子由:内容区(content)、填充区(padding)、边框区(border)、外边界区(margin)四部分组成。
- 盒子模型有哪两种
-
- 标准模式下: 一个块的总宽度(页面中占的宽度)= width + margin(左右) + padding(左右) + border(左右)
- 怪异模式下: 一个块的总宽度= width + margin(左右)(即width已经包含了padding和border值)(IE浏览器)
- 标准和怪异模型的转换
-
- box-sizing:content-box; 将采用标准模式的盒子模型标准
- box-sizing:border-box; 将采用怪异模式的盒子模型标准
- box-sizing:inherit; 规定应从父元素继承 box-sizing 属性的值。
- px是固定的像素,一旦设置了就无法因为适应页面大小而改变。
- em和rem相对于px更具有灵活性,他们是相对长度单位,意思是长度不是定死了的,更适用于响应式布局。
- em是相对于其父元素来设置字体大小的,一般都是以<body>的“font-size”为基准。这样会存在一个问题,进行任何元素设置,都有可能需要知道他父元素的大小。
- 而rem是相对于根元素<html>,这样就意味着,我们只需要在根元素确定一个参考值。
- 回流:页面中元素的尺寸,布局,隐藏等改变而需要重新构建页面,就会引起回流。
- 重绘:页面中元素属性发生改变,而这些属性只是影响元素的外观,风格,而不会影响布局的,则就叫称为重绘。
- 关系:回流必将引起重绘,而重绘不一定会引起回流。
- 如何避免:
- 1、尽可能在DOM树的末端改变class ,尽可能在DOM树的里面改变class,可以限制回流的范围,使其影响尽可能少的节点。
- 2、减少DOM操作,尽量将样式集中起来操作
- H5 新增标签:
- 语义化标签:header、footer、nav、section
- 多媒体标签:video、audio
- H5新增表单控件:color、number、url、email、time、date、search
- H5 新增本地存储:localStorage、sessionStorage
- css3新特性:
- 文本阴影、圆角边框、背景大小、边框阴影、盒子模型
static丝带提可 | 静态定位 | 静态定位,默认,无定位 | |||
relative | 相对定位 | 相对定位占原来位置,移动时,参照原来位置 | |||
absolute | 绝对定位 | 1、绝对定位不占原来位置,移动时参照浏览器边界 2、无父级或父级无定位时,绝对定位不占原来位置,移动时参照浏览器边界,随滚动条走 3、有父级且父级有定位,绝对定位不占原来位置,移动时参照父级边界,随滚动条走 | |||
fixed费渴死的 | 固定定位 | 固定定位不占原来位置,移动时参照浏览器边界,不随滚动条走或固定在屏幕某个位置 |
- link 属于 html 标签。@import 在 css 中使用表示导入外部样式表;
- 页面被加载的时,link 会同时被加载,而@import 引用的 CSS 会等到页面被加载完再加载;
- @import 只在 IE5 以上才能识别,而 link 是 HTML 标签,无兼容问题;
- link 方式的样式的权重 高于@import 的权重;
- link 支持使用 javascript 改变样式,后者不可
- href 是指向网络资源所在位置,建立和当前元素或当前文档之间的链接,用于超链接。
- src 是指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;
- 块级元素水平居中方式:margin:0 auto
- 行内元元素水平居中方式:text-aline:center
- 也可以使用弹性布局中的 justify-content:center
- 块级元素垂直居中方式:利用绝对定位,top给50%集合transform:translatY(-50%)
- 行内元素垂直居中方式:line-hight的高度和盒子的高度一样实现垂直居中
- 也可以使用弹性布局中的aline-items:center
- block 将行内元素转块元素
- none 隐藏页面元素
- inline 将块元素转行内元素
- inline-block 行内块元素
- 父级div设置高
- 结尾处加一个空标签给属性clear:both
- 父级div设置伪类:after和zoom
- 父级div设置overflow:hidden
- 让父级div也浮动,需要设置宽度
- IE浏览器:Trident(踹den特)内核,也是俗称的IE内核
- 谷歌浏览器:以前是Webkit内核,现在是Blink内核
- 火狐浏览器:Gecko(盖扣)内核
- 苹果浏览器:Webkit内核
- 欧朋浏览器:Blink内核
- cookie数据始终会随着http请求传递发送而sessionStorage和localStorage不会随着http请求发送出去
- cookie数据大小在不同浏览器有不同的大小基本上都是4Kb。
- sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,通常都是5Mb。
- localStorage:存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
- sessionStorage:数据在当前浏览器窗口关闭后自动删除
- cookie:设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
- 调用localstorage,cookie等本地存储方式
- localstroge另一个浏览器上下文被添加、删除或修改时,它都会触发一个事件,我们通过监听事件,控制它的值来进行页面信息通信。
- alt是图片加载失败时,显示在网页上的替代文字;
- title是鼠标放上面时显示的文字。
- 内联式
- 嵌入式
- 外部引用式
- 导入样式表(@import )
- 内联式 > 内嵌式 > 外部引用式 > 导入样式表
JavaScript方面
1、原型和原型链- 原型就是一个为实例对象定义了一些公共属性和公共方法都对象模板
- 再获取对象中的属性时,如果在当前对象中没有这个属性就会去它的原型上去找,如果还是找不到就会去它原型的原型上去找,直到找到最外层的原型上为止,这个查找的链式过程叫做原型链
- 构造函数的原型指向其原型对象,原型对象的constructor指向其构造函数,通过new关键字实例化构造函数,实例化对象的__proto__指向其原始的原型对象
- BOM是浏览器对象模型
- BOM没有相关标准。
- BOM的最根本对象是window。
- DOM是文档对象模型
- DOM是W3C的标准。
- DOM最根本对象是document
- 基本数据类型:boolean 布尔值,number 数字、null 无值、undefined 空、string 字符串、symbol唯一值、bigInt大数值
- 引用数据类型:object对象、function函数、array数组
- 浅拷贝: 将原对象或原数组的引用直接赋给新对象/新数组,新对象/数组只是原对象的一个引用
- 深拷贝: 创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”
- 为什么要使用深拷贝?
- 我们希望在改变新的数组或对象的时候,不改变原数组或原对象
- 浅拷贝的实现方法
- 数组的浅拷贝
- 直接遍历
- slice()
- concat()
- 对象的浅拷贝
- 直接遍历
- ES6的Object.assign
- ES6的扩展运算符
- 深拷贝的实现方法
- 用 JSON.stringify 把对象转换成字符串,再用 JSON.parse 把字符串转换成新的对象。
- 递归
- jQuery 的 extend方法
- 第一种:使用内置方法反转字符串
- 1. 使用 split()方法返回一个新数组
- 2.使用 reverse()方法 翻转数组
- 3.使用 join()方法 组合所有的数组元素,从而变成一个新字符串
- 第二种:用递减的 for 循环反转字符串
- 第三种:用递归反转字符串
- defer
- script标签中增加defer属性,异步加载
- 1、但要等dom文档全部解析完(dom树生成)才会被执行。
- 2、只有IE能用;
- async
- script标签中增加async属性,异步加载
- 1、加载完就执行;async只能加载外部脚本
- 2、不能把js写在script标签里。
- 3、w3c标准,IE9以下不支持
- 可以通过动态地创建<script>标签来实现异步加载js文件
- 协议、域名以及端口号相同就为同源,是由Netscape提出的一个著名的安全策略。
- 浏览器请求必须遵循同源策略,即同域名、同端口、同协议;
- 例如:
- http://www.abc.com到http://www.def.com的请求会出现跨域(域名不同)
- http://www.abc.com:3000到http://www.abc.com:3001的请求会出现跨域(端口不同)
- http://www.abc.com到https://www.abc.com的请求会出现跨域(协议不同)
- 节流是指在规定的时间内只运行一次,若在规定的时间内重复触发,只有一次有效
- 防抖是指在规定的时间后执行该事件,如果在此时间内被重复触发,则重新计时
- promise是es6自带的构造方法
- promise用于处理异步编程
- Promise 构造函数的使用
- new Promise(fn)
- fn 是一个立即执行的函数,因此它的内容是同步执行的
- fn 的形式为 function(resolve, reject) {}
- resolve 在成功时调用,并传值,将 promise 状态更改为成功
- reject 在失败时调用,并传错误原因,将 promise 状态更改为失败
- Promise 实例状态特点
- pending - 进行中,悬而未决(也是初始状态)
- fulfilled - 满足条件,成功
- rejected - 被抛弃,失败
- Promise 实例的方法
- .then(成功, 失败) - fulfilled 时进入 成功或 rejected 时进入 失败
- .catch(failedFn) - rejected 时进入回调函数
- .finally(fn) - 无论结果是 fulfilled 或者是 rejected,都会执行指定的回调函数
- then / catch / finally 返回新 promise
- 宏任务包括:setTimeout、setInterval、Ajax、DOM 事件
- 微任务:Promise、async/await
- 微任务比宏任务的执行时间要早
- 全局作用域:最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的;
- 局部作用域:局部作用域一般只在固定的代码片段内可访问到,而对于函数外部是无法访问的,最常见的例如函数内部。
- 当查找变量的时候,会先从当前作用域的变量对象中查找,如果没有找到,就会从父级作用域(上层环境)的变量对象中查找,一直找到全局作用域的变量对象,也就是全局对象。这样由多个作用域的变量对象构成的链表就叫做作用域链。
- 闭包就是一个能够读取外层函数内部变量的函数(可以在内部函数访问到外部函数作用域。)
- 为什么要使用闭包
- 使用闭包,一可以读取函数中的变量,二可以将函数中的变量存储在内存中,保护变量不被污染。
- 闭包的两种形式
- 函数作为返回值的形式
- 函数作为参数的形式
- 闭包的使用场景
- 封装功能时(需要使用私有的属性和方法),
- 函数防抖、函数节流
- 单例模式
- 优点:可以重复使用变量,且不造成变量污染
- 缺点:增加常驻内存, 容易造成内存泄漏
- 普通函数中调用,this 指向 window
- 对象方法中调用,this 指向当前对象
- call apply bind 中调用, this 指向被传入的对象
- class 中的方法中调用, this 指向实例对象
- 箭头函数,this 就是父级上下文中的 this
- 自执行函数的this指向window
- 原型链继承
- 父类的实例作为子类的原型
- 借用构造函数继承.
- 复制父类的实例属性给子类
- 组合式继承
- 调用父类构造函数,继承父类的属性,通过将父类实例作为子类原型,实现函数复用
- 通过ES6中的extends继承
- es5和es6继承的区别
- es5的继承是通过原型或构造函数机制实现的;它先创建子类,再实例化父类并添加到子类this中
- es6先创建父类,再实例化子类集中通过调用super方法访问父级后,再通过修改this实现继承
- var存在变量提升,let和const不存在变量提升
- var不存在暂时性死区,let和const存在暂时性死区
- var和let可以修改声明的变量,const不能修改声明的变量
- var可以重复声明,let和const不能重复声明
- 自执行函数是什么
- 自执行函数也叫立执行函数
- 是将函数的声明和调用合并在一起
- 自执行函数存在的意义
- 自执行函数是为了封装
- 不需要将普通的函数特意换成自执行函数的写法
- 自执行函数的优点
- 保护内部变量不受污染
- 自执行函数与普通函数无本质区别,简化了普通函数的步骤
- 自执行函数与普通函数一样,同样具有形参和实参
- 自执行函数实际是函数表达式,属于高阶函数
- 自执行函数一般使用匿名函数
- 递归: 针对的是函数; 是 JS 中一种重要的思想;
- 递归的两个重要因素:递归调用的过程、递归终止的条件
- 函数递归: 在函数体内部,调用函数自己本身,让其执行;这就是递归;
- 事件委托的原理
- 确定要添加事件元素的父级元素;
- 给父元素定义事件,监听子元素的冒泡事件;
- 使用 event.target 来定位触发事件冒泡的子元素。
- 好处:提高性能,减少了事件绑定,从而减少内存占用
- 应用场景 在 vue 中事件委托
- 我们经常遇到 vue 中 v-for 一个列表,列表的每一项都绑定了@click 处理事件。我们都知道绑定这么多监听,从性能方面来说是不太好的。那我们我们可以通过把每个 item 的 click 事件委托给父元素的形式来实现。
- 通过js创建一个Object对象来模拟真实DOM结构,通过vue中的render()函数把虚拟dom编译成真实dom,在通过appendChild()添加到页面中。
- 优点
- 可以减少DOM操作
- 能跨平台渲染
- 缺点
- 需要额外的创建函数,如 createElement 或 h,但可以通过 JSX或者vue-loader 来简化成 XML 写法。但是这么做会依赖打包工具。
- 箭头函数是匿名函数,不能作为构造函数,不能使用 new
- 箭头函数内没有 arguments,可以用展开运算符...解决
- 箭头函数的 this,始终指向父级上下文
- 箭头函数不能修改 this 指向。
- HTML方面优化
- CSS样式表置于头部,CSS会一边加载一边渲染
- 异步加载js
- 使用外部的样式表和脚本,优先加载出HTML结构
- CSS方面优化
- 避免使用css的@import
- 避免使用通配符
- 避免使用css表达式
- 提取公共css
- JS方面优化
- 如果没有兼容问题,尽量使用原生方法
- 需要使用定时器时,用setTimeout取代setInterval,setInterval会一直占用内存
- 使用节流、防抖、事件委托减少无用的操作
- 网络方面优化
- 尽量减少http请求次数
- 合理使用浏览器缓存
- 避免使用服务端字体
- typeof 主要用来检测基础数据类型
- instanceof 用于检测构造函数中的原型(prototype)属性是否出现在某个实例对象的原型链上
- constructor 用于检测实例对象是否由某个构造函数实例化出来的
- Object.prototype.toString.call()
- 适用于所有类型
- 检测对象的时候不用加 call 也可以
- 别的数据类型必须用 call,否则的话就变成了转成字符串的方法了
- 他们都是用来改变函数执行时的this指向
- 执行:
- call/apply改变了函数的this上下文后马上执行该函数
- bind则是返回改变了上下文后的函数,不执行该函数
- 返回值:
- call/apply 返回fun的执行结果
- bind返回fun的拷贝,并指定了fun的this指向,保存了fun的参数。
- 数组扁平化就是将一个多维数组转换为一个一维数组
- 实现方式:
- 常规方式 递归处理
- 使用 reduce 方法
- 扩展运算符
- 解析HTML,构建 DOM 树
- 解析 CSS ,生成 CSS 规则树
- 合并 DOM 树和 CSS 规则,生成 render 树
- 布局 render 树,负责各元素尺寸、位置的计算
- 绘制 render 树,绘制页面像素信息
- 浏览器会将各层的信息发送给 GPU,GPU 会将各层合成,显示在屏幕上
- 1、浏览器的地址栏输入URL并按下回车。
- 2、浏览器查找当前URL是否存在缓存,并比较缓存是否过期。
- 3、DNS解析URL对应的IP。
- 4、根据IP建立TCP连接(三次握手)。
- 5、HTTP发起请求。
- 6、服务器处理请求,浏览器接收HTTP响应。
- 7、渲染页面,构建DOM树。
- 8、关闭TCP连接(四次挥手)。
- 在下次 DOM 更新循环结束之后执行延迟回调。
- 在修改数据之后立即使用这个方法,获取更新后的 DOM。
- axios 是一个基于 Promise 的方法,可以发送 get、post 等请求,并且前后端都可以使用。
- axios封装步骤
- 引入axios
- 创建axios实例
- 设置请求拦截器
- 设置响应拦截器
- 创建xhr对象
- 调用 open 准备发送
- open的参数:methods、url、flag、name、password
- 如果是post请求方式需要设置请求头
- 调用 send 发送请求 (如果不需要参数,就写 null)
- 监听异步回调 onreadystatechange,onload
- 状态值:readyState
- 0:创建了 xhr 对象
- 1:与服务器建立了连接,向服务器发送数据
- 2:服务器开始接收数据
- 3:服务器接受完数据,开始处理数据
- 4:数据处理完成,js 可以调用处理的结果
- status:状态码
- 200:请求成功
- 304:请求的文件没有修改,去本地缓存读数据
- 404:路径错误
- 403:权限(forbidden)
- 50x:服务器错误
- jsonp 是一种跨域通信的手段,它的原理其实很简单:
- 利用 script 标签的 src 属性来实现跨域。
- 通过将前端方法作为参数传递到服务器端,然后由服务器端注入参数之后再返回,实现服务器端向客户端通信。
- 由于使用 script 标签的 src 属性,因此只支持 get 方法
- 单例模式
- 保证一个类仅有一个实例,并提供一个访问它的全局访问点
- 代理模式
- 为一个对象提供一个代用品或占位符,以便控制对它的访问
- 发布订阅模式
- 也称作观察者模式,定义了对象间的一种一对多的依赖关系,当一个对象的状态发 生改变时,所有依赖于它的对象都将得到通知
- 工厂模式
- 根据不同的参数,返回不同类的实例。
- 适配器模式
- 用于解决兼容问题,接口/方法/数据不兼容,将其转换成访问者期望的格式进行使用。
- 装饰器模式
- 在不改变原对象的基础上,增加新属性/方法/功能。
- 策略模式
- 定义一系列算法,根据输入的参数决定使用哪个算法。
- CORS跨域
- 前端不动,后端设置请求头
- JSONP跨域
- 利用 script 标签的 src 属性来实现跨域。
- 代理跨域
- 通过修改nginx服务器配置实现代理转发
- 前端修改,后端不用
- 正向代理
- 正向代理即是客户端代理, 代理客户端, 服务端不知道实际发起请求的客户端.
- 反向代理
- 反向代理即是服务端代理, 代理服务端, 客户端不知道实际提供服务的服务端
- 区别:
- 从用途上来讲:
- 反向代理的典型用途是为后端的多台服务器提供负载平衡,或为后端较慢的服务器提供缓冲服务。
- 从安全性来讲:
- 正向代理允许客户端通过它访问任意网站并且隐藏客户端自身,因此你必须采取安全措施以确保仅为经过授权的客户端提供服务。
- 反向代理对外都是透明的,访问者并不知道自己访问的是一个代理。
- 从使用方来看:
- 正向代理是浏览器端进行配置的,与服务器端无关,甚至可以对服务端隐藏。
- 反向代理是服务器端配置的,对浏览器端是透明的。
- null表示此处无值或是后期需要给赋值而undefined是表示此处应该有值而没给赋值
- 在内存中创建一个新对象
- 新对象内部的prototype属性被赋值为构造函数的prototype属性
- 构造函数的this指向其新对象
- 执行构造函数内部的代码(即给新对象添加属性)
- 如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象
- $号是jQuery“类”的一个别称,$()构造了一个jQuery对象。所以,“$()”可以叫做jQuery的构造函数。
1** | 信息,服务器收到请求,需要请求者继续执行操作 |
2** | 成功,操作被成功接收并处理 |
3** | 重定向,需要进一步的操作以完成请求 |
4** | 客户端错误,请求包含语法错误或无法完成请求 |
5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
- get请求一般是去取获取数据(其实也可以提交,但常见的是获取数据)post请求一般是去提交数据。
- get因为参数会放在url中,所以隐私性,安全性较差,而post请求数据是放在body中的,安全性较高。
- get和post 请求的数据长度是有限制的,不同的浏览器和服务器不同,一般限制在 2~8K 之间,更加常见的是 1k 以内;post请求是没有的长度限制。
- get请求可以被缓存,post请求不会被缓存。
- get请求会被保存在浏览器历史记录当中,post不会。
- get请求刷新服务器或者回退没有影响,post请求回退时会重新提交数据请求。
- Object构造函数式
- 对象字面量式
- 构造函数模式
- 原型模式
- 所有的变量、函数存储在内存中,当作用域消失的时候,内存自动释放
- 不再用到的内存,没有及时释放,就叫做内存泄漏
- 全局变量、闭包、DOM 清空或删除时,事件未清除、子元素存在引用
- 数组表示有序数据的集合,而对象表示无序数据的集合。
- 数组的数据没有”名称”(name),对象的数据有”名称”(name)。
- 会话cookie(关闭浏览器是清除cookie)
- 持久cookie,date是指定过多久之后清除cookie
- 序列化:js中的object转化为字符串
- 反序列化:json字符串转化为object
- for循环是通过 生成 数组的索引下标 循环遍历数组的每一个数据元素
- forEach是 JavaScript定义的数组的函数方法 通过 JavaScript底层程序 循环遍历数组的数据元素
- for循环 可以 通过 break 关键词 来终止循环的执行
- forEach 中 调用执行 break 程序会报错
- for循环可以通过 控制循环变量 的数值 控制 对于循环的执行
- forEach循环 中 参数存储数据都是底层程序进行赋值 无法进行赋值修改等操作
- for循环 在循环外 可以调用循环变量
- forEach循环 在循环外 不能调用 循环变量
- 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了;
- 面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
- 面向对象是以功能来划分问题,而不是步骤。面向对象使用对象,类,继承,封装等基本概念来进行程序设计。
- 优缺点:
- 面向过程:
- 优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是重要的因素。
- 缺点:没有面向对象易维护、易复用、易扩展
- 面向对象:
- 优点:可读性高,易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护。
- 缺点:类调用时需要实例化,开销比较大,性能比面向过程低
- 栈:栈会自动分配内存空间,会自动释放,存放基本类型,简单的数据段,占据固定大小的空间。
- 堆:动态分配的内存,大小不定也不会自动释放,存放引用类型,指那些可能由多个值构成的对象,保存在堆内存中,包含引用类型的变量,实际上保存的不是变量本身,而是指向该对象的指针。
- 基本数据类型存储在栈中
- 引用类型的对象存储于堆中
VUE方面
vue是什么- vue是渐进式框架
- 双向数据流
- 是一个创建单页应用的Web应用框架
- 双向数据绑定。
- 组件系统。
- 就是只有一个Web页面的应用,是加载单个HTML页面,并在用户与应用程序交互时动态更新该页面的Web应用程序。
- 与传统多页面程序的区别:
- 传统多页面程序:每次请求服务器返回的都是一个完整的页面
- 单页应用程序:只有第一次会加载页面, 以后的每次请求, 仅仅是获取必要的数据.然后, 由页面中js解析获取的数据, 展示在页面中
- 优势:
- 减少了请求体积,加快页面响应速度,降低了对服务器的压力
- 更好的用户体验,让用户在web app感受native app的流畅
- 缺点:
- 因为技术使用了ajax,导致页面不利于SEO,但是可以通过其他技术去规避
- 相同点:
- 都可以动态控制dom元素的显示隐藏
- 不同点:
- v-if: 控制 DOM 元素的显示隐藏是将 DOM 元素整个添加或删除
- v-show: 控制 DOM 的显示隐藏是为 DOM 元素添加 css 的样式 display,设置 none 或者是 block,DOM 元素是还存在的
- 性能消耗
- v-if 有更高的切换消耗;
- v-show 有更高的初始渲染消耗
- 使用场景
- v-if 适合运营条件不大可能改变的场景下;
- v-show 适合频繁切换;
- v-for的优先级要比v-if的高,v-if要运行在每一个循环出来的标签上,性能会很低。
- 减小入口文件体积
- 路由懒加载
- 静态资源本地缓存
- 合理利用localStorage
- UI框架按需加载
- 为了保证组件的独立性和可复用性,如果data是个函数的话,每复用一次组件就会返回新的data,类似于给每个组件实例创建一个私有的数据空间,保护各自的数据互不影响。
- 如果为对象添加少量的新属性,可以直接采用Vue.set()
- 如果需要为新对象添加大量的新属性,则通过Object.assign()创建新对象
- 编写形式
- 每一个.vue文件我们都可以看成是一个组件
- vue插件的实现应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象
- 注册形式
- 组件注册的话全局通过Vue.component方法,局部注册直接通过component
- 组件注册则需要通过Vue.use
- 使用场景
- 组件是用来构成你的 App 的业务模块,它的目标是 App.vue
- 插件是用来增强你的技术栈的功能模块,它的目标是 Vue 本身
- 父子组件之间的通信
- 在父组件中的子组件标签上写一个自定义属性
- 在子组件的配置项中添加一个props配置项
- 在props中接收自定义属性的值
- 在子组件中就可以使用props中的属性来拿到传递的值
- 兄弟组件之间的通信
- 创建一个js文件,在该文件中导出一个空的vue实例
- 需要在向外传递数据的组件中触发一个事件函数,并且需要导入js文件中的vue实例
- 在事件函数中通过 bus.$emit() 来进行自定义事件的发出
- 在需要接受数据的组件中,导入js文件中的vue实例
- 通过bus.$on() 来触发自定义事件,从而拿到相应的数据 $on方法 可以传递两个参数,第一个参数是自定义事件名,第二个参数回调函数,该回调函数有一个默认参数,就是传递过来的值
- 如果在组件中使用了$on绑定事件,最好是在组件销毁时,使用$off将该事件进行解绑,这样可以减少内存的消耗
- 祖孙与后代组件之间的通信
- $parent 或$ root
- $attrs 与$ listeners
- provide 与 inject
- 父子关系的组件数据传递选择 props 与 $emit 进行传递,也可选择 ref
- 兄弟关系的组件数据传递可选择 $bus,其次可以选择 $parent 进行传递
- 祖先与后代组件数据传递可选择 attrs 与 listeners 或者 Provide 与 Inject
- 复杂关系的组件数据传递可以通过 vuex 存放共享的变量
- 定义:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
- 理解:nextTick(),是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数
- 使用场景:
- 更改数据后当你想立即使用js操作新的视图的时候需要使用它
- Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中
- mixin 是一种类,在vue中就是js文件,主要的作用是作为功能模块引用。因为在项目中,可能不同组件会有相同的功能,比如控制元素的显示和隐藏,如果他们的变量和规则也完全相同的话,就可以把这个功能单独提取出来,放在 mixin.js 中,再引入,就可以实现一样的功能了。引入的方法也分为全局混入和局部混入,局部混入就是在每个组件中引入,全局混入就是在 main.js中 通过 Vue.mixin() 引入。
- 插槽:简单理解就是组件内部留一个或多个的插槽位置,可供组件传对应的模板代码进去。插槽的出现,让组件变的更加灵活。
- 匿名插槽
- 默认插槽
- 具名插槽
- 通过插槽的name属性给插槽指定名称
- 在使用时可以通过slot="name"方式, 指定当前内容用于替换哪一个插槽
- 作用域插槽
- 作用域插槽就是带数据的插槽, 就是让父组件在填充子组件插槽内容时也能使用子组件的数据。
- ①、在slot中通过 v-bind:数据名称=“数据名称” 方式暴露数据。
- ②、在父组件中通过 <template slot-scope=“作用域名称”> 接收数据。
- ③、在父组件的<template></template>中通过 作用域名称.数据名称 方式使用数据。
- 插槽的使用情景?
- 默认情况下是不能在使用子组件的时候, 给子组件动态的添加内容的。
- 如果想在使用子组件的时候, 给子组件动态的添加内容, 那么就必须使用插槽,在子组件中创建<slot>插槽。
- 插槽的作用?
- 让用户可以拓展组件,去更好地复用组件和对其做定制处理。
- 特点?
- 插槽可以指定默认数据, 如果父组件没有使用这个插槽, 那么就会显示插槽中的默认数据,如果父组件向插槽中插入数据, 那么就会利用父组件插入的内容替换子组件中的整个插槽。有多少个匿名插槽, 填充的数据就会被拷贝几份。
- keep-alive 是用来缓存组件 避免多次加载相应的组件 增加性能消耗 如果频繁切换组件就需要keep-alive
- keep-alive可以设置以下props属性:
- include - 字符串或正则表达式。只有名称匹配的组件会被缓存
- exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存
- max - 数字。最多可以缓存多少组件实例
- 被包含在 keep-alive 中创建的组件,会多出两个生命周期的钩子: activated 与 deactivated:
- activated:在 keep-alive 组件激活时调用
- deactivated:在 keep-alive 组件停用时调用
- vue 中的权限控制分为页面级的权限控制和按钮级的权限控制,页面级的权限控制就是不同人员登录看到的页面菜单是不一样的比如一个公司的老板登录可以看到公司的营收和业绩情况,但是员工登录的话是没有权利看到的,按钮级别的权限控制,比如学校的系统,一个页面中有一个确认成绩按钮,这个按钮只有老师有权利点击,其他学生登陆是无法点击的。
- 页面级的权限(用户是否有权限能看到这个页面)
- 后端返回路由信息,前端存储完整路由表:
- 后端返回路由权限名,前端存储完整路由权限表,并动态生成路由(真正的权限控制)
- 按钮级的权限(用户是否能看到或者能用页面中的某个按钮)
- 判断登录进来用户是否拥有点击这个按钮的权限,有了显示没有就隐藏
- 为什么会出现闪烁问题
- 因为浏览器是 html 从上到下执行,先执行 Dom 元素,然后执行 javaScript 元素,当走到 javaScript 时,Dom 元素已经开始走动,所以如果网慢的话,会显示的特别明显
- 可以用 v-cloak 和 v-text
- 子组件想要修改时,须要经过 $emit 派发一个自定义事件,父组件收到后,由父组件进行修改
- 当你传入的 prop 为 Object 类型或者 Array 的时候,修改子组件内部的 prop 可以对应的改变父组件中的值
- 通过 .sync 修饰符在子组件中修改
- delete 和Vue.delete 都是对数组或对象进行删除的方法
- delete 只是被删除的元素变成了 empty/undefined 其他的元素的键值还是不变。数组长度也不变。(逻辑删)
- Vue.delete 是直接删除该元素,长度发生变化。(物理删)
- $router
- $router 是全局 router 的实例, 包含了一些路由的跳转方法 push, replace 等
- $route
- $route 是当前激活路由的信息对象。每个对象都是局部的,可以获取当前路由的 path, name, params, query 等属性
- vue的生命周期有四个大的阶段分别是创建、挂载、更新、销毁,在每一个阶段中都有两个生命周期函数,分别是:
- beforeCreate( ) 初始化前
- Created( ) 初始化后
- beforeMount( ) 挂载前
- Mounted( ) 挂载后
- beforeUpdate( ) 更新前
- Updated( ) 更新后
- beforeDestory( ) 销毁前
- destoryed( ) 销毁后
- 如果组件被keep-alive缓存后,会多出两个生命周期函数分别是activated与deactivated
- vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty()来劫持各个数据的 setter 和 getter ,在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图
- 通过js创建一个对象来模拟真实的dom结构
- 在节点中如果为节点绑定了一个 key 值,那么这个 key 值会为这个节点绑定唯一的 id 标识,这也是 diff 算法的一种优化,可以根据 key 值,更准确,更快速的找到对应的节点,减少 DOM 的操作,优化页面的性能
- 快速查找到节点,减少渲染次数,提升渲染性能
- 原因
- 用 index 作为 key 时,在对数据进行,逆序添加,逆序删除等破坏顺序的操作时,会产生没必要的真实 DOM 更新,从而导致效率低
- 作用
- key 是虚拟 DOM 对象的唯一标识
- 在 diff 算法中 key 起着极其重要的作用。
- watch 与 computed之间区别
- computed有return,watch没有return
- computed用于计算,watch用于监听数据变化
- computed存缓存 watch没有缓存
- mutations是处理同步方法,actions是处理异步方法,
- mutations可以修改state状态,actions不能修改,
- mutations中第一个参数是state,actions中第一个参数是vuex的实例,
- mutations中的方法中无法使用then来监听回调,actions中的方法可以使用then来监听回调
- 有三种导航守卫:
- 全局路由守卫
- beforeEach():全局前置守卫,在进入到某一个路由之前会触发这个函数
- afterEach():全局后置守卫,在进入到某一个路由之后会触发这个函数
- beforeResolve():全局解析守卫,在进入到某一个路由之前,同时将进入到的路由组件解析完成后触发这个函数,类似于前置守卫
- 路由独享守卫
- beforeEnter():在进入到当前路由之前会触发这个函数
- 组件内的守卫
- beforeRouteEnter():在路由进入到该组件之前触发这个钩子函数
- beforeRouteUpdate():在路由的 url 路径上通过动态路由实现路径的变化,但是该组件重复复用时,会被触发。比如 home/张三跳转到 home/李四,这个时候函数会被触发
- beforeRouteLeave():在路由离开这个组件之前触发钩子函数
- 全局指令: 通过 Vue.directive() 函数注册一个全局的指令。
- 局部指令:通过组件的 directives 属性,对该组件添加一个局部的指令。
- 动态路由传递参数使用params传递,这样传递过去的值刷新页面也不会丢失,如果使用query传值,则刷新数据丢失
- 静态路由传递参数使用query传递,这样传递数据刷新页面不会丢失,如果使用params传递,数据刷新页面会丢失
- 有两种模式 分别是 hash 和 history 默认使用 hash 模式如果需要转换成 history 模式,需要在路由的配置中添加一个 mod 属性,值改写成history , hash 模式在 url 路径上会有一个 #,而 history 模式没有,但是如果在项目中想要使用 history 模式,一般需要后台设置对应模式的接口
- 区别
- history 和hash 都是利用浏览器的两种特性实现前端路由,history 是利用浏览历史记录栈的 API 实现,hash 是监听 location 对象 hash 值变化事件来实现
- history 的 url 没有 # 号,hash 的 url 上面带 # 号
- 相同的url,history会触发添加到浏览器历史记录栈中,hash不会触发,history需要后端配合,如果后端不配合刷新新页面会出现404,hash不需要。
- 原理:
- location中的hash可以实现
- history中的pushState方法实现
- vuex是一个专为 Vue.js 应用程序开发的状态管理模式, 采用集中式存储管理应用的所有组件的状态,解决多组件数据通信。
- 情况1:在老项目中使用。 先额外安装 vuex 包,然后在配置。
- 情况2:在新项目中使用。 在配置 vue-cli 中创建项目时,就可以直接选中 vuex 项,这样就不用做任何配置了(脚手架会自动帮我们完成的)
- state:单一状态树,用于存储状态
- mutations:用于保存所有的同步方法,是唯一可以修改state状态的地方
- actions:用于保存所有的异步方法,里面封装了promise,使用时可以使用.then进行回调处理
- getters:用于计算属性,当需要对state中的状态进行计算处理时,可以使用
- modules:如果vuex中的状态过多,可以利用模块化进行管理
- 在组件中如果想要修改state中的数据,最好是通过dispatch调用actions中的方法,然后在actions的方法中通过 commit 调用 mutations 里面的方法,最后在 mutations 的方法中来修改state中的数据,不建议直接在组件中使用 commit 调用 mutatios 中的方法,这样无法使用 then 来回调接收判断是否 vuex 响应成功
- 插件的使用 Vuex-persistedstate
- 安装:npm i vuex-persistedstate --save
标签:面试题,vue,函数,DOM,对象,前端,经典,组件,页面 From: https://www.cnblogs.com/6-2-1/p/16853215.html