前端面试题

基础面试题

DOM和BOM

  1. BOM是浏览器对象模型,用来获取或设置浏览器的属性、行为,例如:新建窗口、获取屏幕分辨率、浏览器版本号等。
  2. DOM是文档对象模型,操作文档HTML的JS处理方式

虚拟dom

遍历真实dom找到指定dom,消耗资源,所以vue建立一个与dom树对应的虚拟dom对象,以对象嵌套方式表示dom树,dom更改,就变成对js对象属性增删改查.这样查找对象属性,要比查找dom树开销小。

dom操作会引起浏览器回流重绘使得性能开销巨大。

当尺寸、布局、隐藏、等等,改变了,引起重新构建,称为回流。

当属性只影响外观、风格、而不影响布局就是重绘。回流一定会引发重绘。

1.解析html:浏览器有专门的html解析器,解析过程中还会构建dom树。

2.构建dom树:跟解析同步执行的

3.构建呈现树rendertree:将css用到dom节点上

4.布局:计算 呈现树 大小和位置

5.绘制:布局完成,将呈现树绘制显示到屏幕上

盒模型

盒子有4个边界:外边距、边框、内边距、内容边界

css3中有个box-sizing属性可以控制盒子计算方式

content-box: padding和border不包含在定义的宽高之内。盒子实际宽度等于设置的width值和border、padding之和。(W3C盒子模型)

border-box:padding 和 boder被包含在定义的width和height之内。对象的实际宽度就等于设置的width值。(IE6盒子模型)

居中方法

- 利用子绝父相
#container{
    width:500px;
    height:500px;
    position:relative;
}
#center{
    width:100px;
    hight:100px;
     position: absolute;
     top: 50%;
     left: 50%;
    margin-top:-50px;
    margin-left:-50px;
    
}
- 利用Css3的transform
#container{
    position:relative;
}
#center{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
- 利用弹性布局
#container{
    display:flex;
    justify-content:center;
    align-items: center;
}

px、em、rem

px实际上就是像素,与物理像素有一定区别,用px设置字体大小,比较精确,但是有缺陷,浏览器页面缩放时,px不能跟随变化。

em是根据父元素来对应大小,是一种相对值,并不是绝对值。

rem是根元素html的font-size来对应大小。

var let const

var:存在变量提升,没有块作用域限制

let:存在暂时性死区(先声明后使用),有块级作用域限制,

const:存在暂时性死区(先声明后使用),有块作用域限制,不能重复声明变量,声明时必须赋值,不可以重复赋值,可以修改引用类型值

检测数据类型

  1. typeof: 只能检测出基本数据类型,数组、对象、null返回object
let a = 1;
console.log(typeof a); //number
  1. instanceof:不能检测原始值类型,通过原型链来判断实例的__proto__是否与检测类型的prototype一致
let houdunren = {};
console.log(hd instanceof Array); //true
  1. constructor:无法判断基本类型值,原理原型prototype上都有一个constructor属性,自身没有这个属性,向原型上找然后比对
console.log(arr.constructor === Array); //true
  1. Object.prototype.toString.call:可以返回所有数据类型,以字符串输出
Object.prototype.toString.call(true); //'[object Boolean]'

数据类型

类型说明
number数值型
string字符串
boolean布尔
null
undefined未定义
object对象
Symbol唯一性,防止属性名冲突
BigInt大整数

数组方法API

push:末尾压入数组,改变原数组,返回值为数组元素数量

pop:删除原数组最后一个,改变原数组,返回值为删除元素

shift:删除原数组第一个,改变原数组,返回值为删除元素

unshift:从数组前面添加数组,改变原数组,返回数组元素数量

fill:在数组固定位置替换内容,改变原数组,返回替换后数组

let a = [1,6,6,3]
console.log(a.fill("后盾人", 1, 2)); //[1, '后盾人', 6, 3]  a=[1, '后盾人', 6, 3]

slice:截取元素,不会改变原数组,返回截取数组,slice(1, 3)截取索引1和索引2元素

splice:可以添加、删除、替换数组中的元素,会对原数组进行改变,返回值为删除的元素

arr.splice(1, 3, 'hdcms', '后盾人')  //删除索引123的元素,然后替换成'hdcms', '后盾人'

join:将数组连接为字符串,不改变原数组,返回连接后数组

let arr = [1, "后盾人", "hdcms"];
console.log(arr.join('-')); //1-后盾人-hdcms 使用join可以指定转换的连接方式

split:将字符串分割成数组,不改变原字符串,返回连接后数组

let price = "99,78,68";
console.log(price.split(",")); //["99", "78", "68"]

indexOf:从前向后查找元素出现的位置,如果找不到返回 -1 arr.indexOf(2)

includes:查找字符串返回值是布尔类型更方便判断 arr.includes(6)

reverse:翻转数组顺序 arr.reverse()

遍历

sort:数组排序,默认从小于大排序数组元素,arr.sort()

console.log(arr.sort(function (v1, v2) {
	return v2 - v1; //从大到小
    return v1 - v2; //从小到大
})); //[9, 4, 2, 1]

find:方法找到后会把值返回出来

findIndex:方法找到后会把索引返回出来

every:用于递归的检测元素,要所有元素操作都要返回真结果才为真

some:如果有一个返回true,表达式结果就是真

filter:返回所有符合条件元素

reduce:可以迭代数组的所有元素

this指向问题

1、普通函数中的this指向window
2、定时器中的this指向window
3、箭头函数没有this,会继承定义函数时的上下文,可以理解为和外层函数指向同一个this
4、事件中的this指向事件的调用者
5、 构造函数中this和原型对象中的this,都是指向构造函数new 出来实例对象
6、类 class中的this 指向由constructor构造器new出来的实例对象
7、自调用函数中的this 指向window

apply/call/bind

相同点:改变this指针。

不同点:

apply:用数组传参

call: 需要分别传参

bind:不会立即执行函数

闭包

闭包:闭包是指有权访问另外一个函数作用域里变量的函数,js中所有函数都是闭包。

特点:

  1. 在子函数本身作用域以外执行,即延申作用域。

  2. 子函数可以访问外部作用域变量。

  3. 容易造成内存泄漏,因为内部使用外部变量,垃圾回收机制认为变量一直被使用,得不到回收,解决方法,用完让他地址指向null。

  4. 将变量定义在内部,使内部拥有自己的变量,同时可以不污染全局变量

Promise

Promise 是一个对象,一般作为构造函数来使用(new Promise),它里面有 3 种状态,pending(准备)、fulfilled(成功)、rejected(失败)。

  • 怎么用

拿到一个 Promise 实例后,原型上具有 then、finally 和 catch 方法,then里面有2个回调函数,第一个成功,第二个失败,catch 可以统一处理失败,finally无论状态是resolvereject 都会执行此动作。

Promise有reject、resolve,race、all、allSettled这几个API:reject生成失败的Promise;resolves生成成功Promise ;race哪个resolve执行快执行哪个;all可以发多个异步请求,有失败状态就不往下走;allSettled不管成功失败状态都返回结果,控制台不报错。

多个请求中,有错误请求可以用then失败回调接收错误,或者用catch统一接收错误,让代码接着往下执行

  • 解决了什么问题

它主要解决一个异步请求套着一个异步请求,一个异步请求依赖于另一个的执行结果,使用回调的方式相互嵌套。
回调地狱的问题。

  • 替代方案

一般工作的时候都会配合 async/await 语法糖来使用,这样既解决了回调地狱又简化了代码,第一个await 之前代码同步执行,后面代码异步执行,await关键字只能出现 async修饰符里面。

缺点:一旦执行无法结束。

es6新增特性

特性说明
Let和const关键字let a = [],const names = [];
结构赋值
字符串模板
展开运算符[…fruits,…vegetables]
箭头函数name => name.toUpperCase()
symbol表示独一无二的值
set使用Set实现数组去重new Set(guaiguai)
promise

常见http的状态码

状态码说明
200请求成功
400错误请求
401未授权
403(禁止) 服务器拒绝请求
404未找到
304协商缓存

防抖节流

共同点:限制函数执行次数

不同点:

  1. 节流(throttle): 所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。

  2. 防抖(debounce): 所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

  3. 防抖可以用于用户输入,节流可以用于页面滚动,无限加载

都是用setTimeout实现,节流通过判断变量boolean值 return出去,防抖通过判断变量是否为空删除定时器,但是要保证代码往下走。

eventloop事件循环

事件轮询就是解决javaScript单线程对于异步操作的一些缺陷,让 javaScript做到既是单线程,又绝对不会阻塞的核心机制,是用来协调各种事件、用户交互、脚本执行、UI 渲染、网络请求等的一种机制。

执行顺序:

  1. 同步任务由javaScript 主线程次序执行
  2. 异步任务委托给宿主环境执行
  3. 已完成的异步任务对应的回调函数,会被加入到任务队列中等待执行
  4. javaScript 主线程的执行栈被清空后,会读取任务队列中的回调函数,次序执行
  5. javaScript 主线程不断重复上面的4步

异步任务又分为:

  1. 宏任务:当前调用栈中执行的代码称为宏任务。(主代码块,定时器等)
  2. 微任务:当前(此次事件循环中)宏任务执行完,在下一个宏任务开始之前需要执行的任务。可以理解为回调事件。(promise.then , nextick等)

http缓存

作用:减少网络请求和数量

强缓存:是取决于服务器判断是否缓存,不需要前端做任何事,服务器会在请求头设置设置相应缓存时间

协商缓存:第一次请求服务器会返回资源标识,后续相同请求携带相同标识发送给服务器,服务器判断资源更新与否,未更新返回304状态码,直接从本地缓存拿资源,更新返回最新数据和200状态码

描述输入url地址到网页展示的过程

  1. DNS域名解析(解析成ip地址)

  2. TCP 3次握手(第一次浏览器发出,第二次服务器,第三次浏览器)

  3. 发送请求报文

  4. 接受响应

  5. 渲染页面

  6. 4次挥手

跨域问题及解决方案

跨域:域名,端口,协议三者中只要有一个不同就是跨域。对于端口和协议的不同,只能通过后台来解决。我们要解决的是域名不同的问题。
解决:

  • jsonp,利用在页面创建

哈希路由和history路由的区别

hash路由

  1. hash就是指url尾巴后的#号以及后面的字符

  2. 刷新 不会导致浏览器向服务器发出请求

  3. hash传参是基于url的,传参有体积限制

  4. hash不会被包含在HTTP请求中,对后端没有影响,改变hash不会重新加载页面

history模式

  1. history路由地址栏URL上没有#

  2. history模式利用了HTML5 History Interface 中新增的pushState()和replaceState()方法

  3. 刷新 history路由url必须和实际后端发起请求的url一致,刷新是网络请求,没有后端准备时会报错404

  4. history模式不仅可以在url里放参数,还可以将数据存放在一个特定的对象中

深拷贝浅拷贝

浅拷贝:创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
方法:
• Object.assign ( {} , 对象1,对象2 ),第一级属性深拷贝,从第二级属性开始就是浅拷贝。
• 使用 es6 展开符
深拷贝:会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。拷贝前后两个对象互不影响。
方法:
• JSON.parse( JSON.stringify (object) ) JSON.stringify 拷贝一个字符串会新辟一个新的存储地址,这样就切断了引用对象的指针联系,所以先转成一个字符串,在JSON.parse解析出对象,这样就可以深拷贝一个对象

https和http的区别

HTTPS 协议需要到 CA (Certificate Authority,证书颁发机构)申请证书,一般免费证书较少,因而需要一定费用。(以前的网易官网是http,而网易邮箱是 https 。)
HTTP 是超文本传输协议,信息是明文传输,HTTPS 则是具有安全性的 SSL 加密传输协议。
HTTP 和 HTTPS 用的端口不一样,前者是80,后者是443。

如何减少重绘和回流

重绘:当前节点需要更改外观而不会影响布局的,比如更改颜色
回流:回流是布局或者几何属性需要改变就称为回流
回流必定会发生重绘,重绘不一定引发回流
• 减少回流方案:
1、使用 css3 的 transform
2、减少 display 使用
3、css 选择符从右到左匹配查找,避免节点层级过多

垃圾回收机制

垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。开销比较大,所以垃圾回收器会按照固定的时间执行。

策略:标记清除

对于脱离作用域的变量进行回收,当进入作用域时,进行标记,离开作用域时,标记并回收这些变量。

get和post区别

1.get参数url可见,post不可见,所以 post更安全

2.get通过拼接url传递参数,post用请求头传递

3.get请求支持http缓存机制,post不支持

4.get请求页面后退,不产生影响,post会重新提交请求

5.get一般传输数据大小不超过4k,post可以无限大

6.get只能是json数据格式,post可以是json、form等格式

如何添加和删除事件

通过addEventListener添加事件,必须通过removeEventListener移除事件
document.addEventListener(‘事件类型’, 事件名);
document.removeEventListener(‘事件类型’, 事件名);

事件冒泡和事件捕获

事件冒泡:当某个元素事件触发时,那么他的父级同类型元素也会触发,一直触发到根源上。
事件铺获: 从根元素(HTML)到事件源,当某个元素事件触发时,朝同类型子级触发,一直到事件源。

事件委托

将所有元素的事件绑定委托给同一个父元素,根据事件冒泡捕获机制,可以在父元素绑定事件中获取的触发事件的这个元素。根据这个元素不同特征,做不同处理。

原型

当我们定义普通对象时候会生成一个__proto__ ,他指向这个对象的构造函数的prototype,也就是原型。我们都知道对象都有一个toString方法,而实例化对象没有toString方法,那就会沿着他的proto向他的构造函数prototype原型对象去找,prototype也是一个对象,也有proto属性,也没有toString方法的话,就会沿着prototype.proto向上找。而他指向顶级Object.prototype。Object.prototype再找的话就是null.

举例:Object.prototype.toString.call()判断数据类型,利用call调用Object原型对象上未被改造的toString方法。

继承

  1. 原型链继承

缺点:2个实例使用同一个原型对象,存在空间共享,当一个发生改变,另外一个也发生变化

  1. 构造函数继承借助call

缺点:只能继承父类的实例属性和方法,不能继承原型属性或者方法。

  1. 组合继承:原型继承构造函数继承结合

缺点:增加了性能开销

  1. 原型式继承:利用ES5 里面的 Object.create 方法

缺点:多个实例的引用类型属性指向相同的内存,存在篡改的可能

  1. 寄生式继承:在原型式继承浅拷贝基础上再添加一些方法

  2. 寄生组合继承:所有继承方式里面相对最优的继承方式

Vue面试题

常用的指令

指令用法
v-text更新标签包含的文本
v-html绑定一些包含html代码的数据在视图上
v-show取值为true/false,分别对应着显示/隐藏
v-if取值为true/false,控制元素是否需要被渲染
v-else当v-if的值false,v-else才会被渲染出来
v-for遍历data中存放的数组数据
v-bind用于动态绑定DOM元素的属性
v-on可以绑定事件的监听器
v-model实现表单控件和数据的双向绑定
v-once只渲染一次,后面元素中的数据再更新变化,都不会重新渲染

v-if和v-for不能同时使用

首先,vi-for比v-if优先级高,影响性能

第一种情况:v-if值不依赖列表,可以在循环外部用v-if判断

第二种情况:v-if值依赖列表,在vue实例,用计算属性过滤掉不需要显示项

计算属性监听属性

计算属性:

  1. 观察多个属性动作,是计算值
  2. 具有缓存性,依赖值不变,不会重新计算

watch特性:

  1. 是观察一个属性的动作
  2. 无缓存性,页面重新渲染时值不变化也会执行

key作用

  1. key的作用主要是利用diff算法更加高效的更新虚拟DOM,其原理是vue在patch过程中通过key可以精准判断两个节点是否是同一个,从而避免频繁更新不同元素,使得整个patch过程更加高效,减少DOM操作量,提高性能。

  2. 另外,若不设置key还可能在列表更新时引发一些隐藏的bug

  3. vue2中diff算法采用递归+双指针方法

data为什么是一个函数

data必须是函数为了保证组件的独立性和可复用性,data是一个函数,组件实例化的时候这个函数就会被调用,返回一个对象,计算机会给这个对象分配地址,实例化几次,分配几个地址,他们地址不一样,所以每个组件中数据不会互相干扰。

el、template、render属性的优先级

在进行dom树渲染时,render函数优先级最高,template次之且需要编译成渲染函数,而挂载点el属性对应的元素若存在,则在前二者不存在时,其outerHTML才会用于编译与渲染。

生命周期

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

阶段方法名方法名
初始化beforeCreate 没有初始化created 初始化完成
挂载beforeMount 获取到dom没有渲染视图mounted 渲染视图了
更新beforeUpdate 拿到更新数据没有渲染updated 渲染到视图
激活activateddeactivated
销毁beforeDestroy 销毁前,data,method可以用destroyed 销毁后

Vue中v-if和v-show的区别

原理:

v-if满足条件是会渲染到html中,不满足条件时是不会渲染到html中的,是通过操纵dom元素来进行切换显示

v-show原理是修改元素的css属性来决定实现显示与隐藏的

应用场景:

v-if需要操作dom元素,有更高的切换消耗,v-show只是修改元素的css属性有更高的初始渲染消耗,如果需要非常频繁的切换,建议使用v-show较好,如果运行条件很少改变,使用v-if较好

v-model和双向数据绑定原理

原理:

Object.defineProperty()劫持data里面各个数据,将它们转为 getter/setter,在属性被访问和修改时通知变化。整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化。通过Compile来解析编译模板指令。最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。

缺点:无法追踪局部状态变化,增加了排错难度

用法:包含两个指令
一个v-bind,把message的值时时放到value中,
另一个v-on,给当前元素绑定input事件,将event.target.value赋值给message

组件创建过程

1.首先,创建一个组件
2.然后,使用Vue.component()方法注册组件
3.接着,子组件可以通过props中接受父组件数据
4.最后,子组件修改数据,可以使用emit()方法

组件传值

props;$emit/$on
$bus => $emit / $on;vuex
$attrs / $listeners
$attrs / $listeners
provide / inject
localStorage / sessionStorage
sync
v-model
ref

组件缓存

在keep-alive里面放入要缓存的组件,他有include以及exclude属性:

  • include - 字符串或正则表达式。只有名称匹配的组件会被缓存。

  • exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。

生命周期钩子:

activated :路由组件被激活时触发。(当进入缓存的路由组件时触发)

deactivated:路由组件失活时触发。(当离开缓存的路由组件时触发)

父子组件生命周期顺序

父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

子组件更新生命周期

父beforeUpdate->子beforeUpdate->子updated->父updated

组件销毁生命周期

父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

Vue性能优化

编码优化:

  1. 不要将所有的数据都放在data中,data中的数据都会增加getter和setter,会收集对应的watcher
  2. key保证唯一性
  3. .合理使用路由懒加载、异步组件
  4. 拆分组件( 提高复用性、增加代码的可维护性,减少不必要的渲染 )
  5. 页面采用keep-alive缓存组件

Vue加载性能优化:

  1. 第三方模块按需导入
  2. 图片懒加载
  3. 滚动到可视区域动态加载

SEO优化:

  1. 预渲染插件
  2. 服务端渲染

打包优化:

  1. 使用cdn的方式加载第三方模块
  2. 多线程打包 happypack
  3. 抽离公共文件

缓存压缩:

  1. 客户端缓存、服务端缓存
  2. 服务端gzip压缩

路由钩子函数

  • 全局路由勾子
    • beforeEach:
    • afterEach
    • beforeResolve
  • 路由所对应组件勾子(路由配制中的component所对应组件)
    • beforeRouteEnter:进入前,进入路由所对应组件前,在beforeCreate前产生的,它不能使用实例化对象this
    • beforeRouteUpdate:更新前,路由更新了,但是路由所对应组件不变,它是更新前触发,更新没有完成,如果需要获取更新完成后信息,要加$nextTick
    • beforeRouteLeave:离开前,切换页面离开前就会触发,它在beforeDestroy前执行
  • 路由配制所对应勾子
    • beforeEnter:读取路由配制前会执行该勾子

进入一个页面时路由勾子执行先后

  • beforeEach==>beforeEnter==>beforeRouteEnter==>beforeResolve==>afterEach

路由更新时路由勾子执行先后

  • beforeEach==>beforeResolve==>afterEach

路由传参

router:路由实例化对象,里面有很多属性子对象。

route:提供当前路由基本信息

路由传参有3种模式,基本路由传参,动态路由匹配,name传参

  1. 基本路由传参
    • this.$router.push(’/path地址?参数名=值&参数2=值2‘)
    • this.$router.push({
          path:'/path地址',
          query:{
              参数名:,
              参数2:2
          }
      })
      
  • 收:this.$route.query.参数名
  1. 动态路由匹配
  • 路由配制

    • {
          path:'/xxx/:参数名?',  // ?代表参数值可传可不传,不写?一定要传
          component...
      }
      
  • 传:this.$router.push(’/xxx/123’)

  • 收:this.$route.params.参数名

  1. name传参
  • 路由配制

    • {
          path:'/',
          name:'home',
          ....
      }
      
  • 传:(刷新不受影响):this.$router.push({name:‘home’,query:{参数名:参数值}})—和以前基本路由传参一样

  • 收:this.$route.query.参数名

  • 传(params):刷新后传参就没了,数据长度与数据类型不受限制

    • this.$router.push({name:‘home’,params:{参数名:参数值}})—和以前基本路由传参一样
  • 收(params):this.$route.params.参数名

动画

传统动画class切换结合c3的transition,他有4个属性:transition-property过渡属性,transition-duration完成过渡时间,transition-timing-function指定完成过渡曲线;transition-delay延迟时间

vue提供了单元素动画和多元素动画封装,只能给元素组件添加进入离开动画。单元素动画用transition包裹动画标签,多元素动画用transition-group包住动画元素,每个动画都要有key值。

vuex

vuex是状态数据管理工具,是通过全局注入store对象,来实现组件间状态数据共享。当vue.use注册全局时,会调用install方法,每个组件实例化过程中,会调用钩子beforeCreate,通过mixin混入机制,把store注入到组件中。store中有5个组成部分:

state:是存储基本数据的;

mutations:更改state数据的,

getter:对state加工,跟vue计算属性一样,

actions:处理异步,通过store.commit方法触发mutations中方法更改state值;

module:是store分割的模块,每个模块拥有state,mutations,getter,actions;

调用vuex其他模块的方法在后面加上{root:true}表示从根查找。

还有4个辅助函数:

mapstate,mapgetters,mapActions,mapmutations

vue自定义指令

主要是通过Vue.directive来定义。每个指令有5个钩子函数如下:

bind:绑定时,自定义指令绑定于相应dom时执行,获取dom,没有渲染到视图
inserted:已经渲染到视图
update:更新时
componentUpdated,:更新完成时,指令所在组件更新完成
unbind:解除绑定

每个指令都有3个参数,dom:指令所在dom, obj:值,vnode:虚拟dom节点信息

Axios 封装了哪些东西

创建了一个请求实例、baseURL(基地址),timeout、拦截器(请求拦截器:统一携带token,token超时。响应拦截器:统一错误处理信息,401页面)

rem适配

安装淘宝 flexible.js ,在 main 文件引入,他把 html 下的 font-size 设置成屏幕10分之一,1rem = 屏幕/设计稿/10,手动计算太麻烦了,可以安装 postcss-pxtorem 插件,根据文档配置,就可以自动把 px 转换 rem .转换过程读取文件路径,根据文件路径判断是组件库的,还是自己设计搞得,进行分开计算。一般 ui 设计稿比较大,因为大图片缩小清晰,小图片放大模糊。

rem 在开发中会出现一些大大小小问题,官方也说了不建议使用 flexible.js ,以前很多公司不用 vw 百分比是兼容问题,现在很多浏览器兼容了。

还是安装插件,postcss-px-to-viewport ,在根目录下 postcss.config.js 中配置,他只做一件事,把 ps 转为百分比。

token过期处理

服务器生成token时会有2时间,token失效时间,和刷新时间,刷新时间比失效时间长。利用axios响应拦截,interceptors.response,里面有2函数,响应成功,把值返回return出去,响应失败进入第二个函数拦截401,判断vuex有没有数据,然后发请求获取新的token替换vuex里面token,然后把请求结果返回给请求体。

webpack

主要 api 有 entry(项目入口),output(出口文件),modul(模块的处理),plugin(loader不能做的处理都能交给plugin来做)

常用的loader有 label-loader :把es6转为es5 ,style-loader:把 CSS 代码注入到 JavaScript 中, eslint-loader:通过eslint检查代码

常见Plugin有:commons-chunk-plugin;提取公共代码 uglifyjs-webpack-plugin:压缩代码

loader是加载器,webpack只能解析js,打包其他文件得用到,plugin是插件,可以扩展webpack功能

loader在module中配置,plugin在plugins中配置

权限

  1. 用户登录成功之后,后端返回当前用户权限标识
  2. 前端根据后端返回得权限标识删选出有权限路由
  3. 删选出来后做了2件事
    第一件事把删选出来得动态路由通过addRoutes 添加到路由实例,目的:能够通过地址栏访问。
    第二件事把删选出来得动态路由添加到Vuex中,目的:给菜单栏使用
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

25氪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值