-
全是从网上整理的(狗头保命)
-
vue3.0 与vue2.0的区别:https://juejin.im/post/6844904128628391944
- 目录结构发生变化:
- 移除了配置文件目录(config与build文件夹),但是多了env.production与env.development,除了文件位置,实际配置和2.0没有什么不同,没有config文件,跨域配置转移到vue.config文件中,配置方法不变
- 部分命令发生变化:
- 删除了vue list
- 数据监听发生变化:
- 2.0用的是object.definePromerty的getter与setter
- 3.0使用proxy监听,按需监听,速度加快。
- Vue更小:runtime-core体积压缩成了约10kb
- 创建命令:
- 2.0:vue init webpack project-name
- 3.0:vue create project-name
- 启动:
- 2.0:npm run dev
- 3.0:npm run serve
- 目录结构发生变化:
-
双向绑定与vuex的冲突:
- 不允许将vuex的值绑定到组件上,直接使用会报错:have no setter
- 解决:
- 使用get与set:
-
- 使用watch监听:
-
vue3.0的响应式原理
- 使用proxy代替object.defineproperty,因为proxy可以直接监听对象与数组的变化
- 但是Proxy只会代理对象的第一层,Vue3.0是如何处理这个问题的
- 判断当前的reflect.get是否为一个obj,如果是,就使用reactive做代理
- 检测数组的时候可能多次触发get、set,如何避免该问题?
- 可以判断key是否为当前被代理对象target自身属性,也可以判断旧值与新值是否相等,满足条件之一,才可能只需trigger
-
虚拟DOM与key值
-
什么是虚拟dom:
- 是js对象记录dom节点的副本,通过对象的方式表示dom结构,通过一些机制,将多次dom修改的结果一次性更新到页面上,来减少页面渲染次数,减少修改dom的重绘重拍次数,提高渲染性能
- 在每次数据变化前,都会把虚拟dom缓存一份,将现在的虚拟dom与缓存的虚拟dom使用diff进行对比,不同的地方就重新渲染,大大的缩减了操作真实dom的性能
- 现在前端框架基本要求就是不需手动操作dom,尤雨溪说过:框架给你保证的是,你不需要手动优化的情况下,我依然给你过得去的性能
- 修改真实dom:
- 生成html结构 =》重绘重排
- 虚拟dom:
- 生成vnode =》使用diff算法 =》更新必要的dom
- 优点:
- 跨平台:本质是js对象,可以方便的垮平台操作,比如服务端渲染,uniapp
- 缺点:
- 首次渲染大量dom,由于多了一层虚拟dom,会比innerHTML慢
- key:
- 在diff中,当新旧子节点顺序不同的时候,最佳操作应该移动元素位置达到目的
- 需要在新旧子节点中保存映射关系,以便能够在旧节点中找到哦啊可以复用的节点
-
-
keep-alive:
- 对组价进行缓存,当组件切换时不会将组件进行卸载
- 狗子函数:
- actived:每进入缓存的页面就会触发一次,不像created、mounted只会触发一次
-
类数组与数组区别:
- 类数组是个对象,具有length属性,但是不具有数组的方法
- 常见的类数组:
- arguements
- document.getElementsByTagName
- 类数组如何转换为数组:
- Array.property.slice.all
- Array.from
- Array.prototype.forEach遍历生成新的数组
-
浏览器和node的event loop
- 首先js是单线程,同一时间只能执行一个任务,那么他是如何做到异步回调的呢
- CPU:
- 计算机的核心,就像是一个工厂,所有的任务都在其中执行,并且是实时的
- 进程:
- 代表cpu所能处理的单个任务,就像一个工厂资源有限,只能一个车间运行,其他停止工作,也就是说一个cpu只能进行一个进程,但是可以通过时间片轮调度算法,同时运行多个进程
- 线程:
- 好比这一个车间的每一个工人,完成同一个任务,共享同一个资源,所以一个进程可以包含多个线程,多个线程共享同一个资源
- CPU:
- 浏览器的event loop
- js任务分为同步与异步任务,同步任务会在执行栈先执行,异步任务放到任务队列中,等待js引擎线程执行空闲之后才会依次执行异步任务
- 先执行宏任务
- 如果遇到微任务,就将其添加到任务队列中
- 宏任务执行完毕,执行任务队列的微任务
- 渲染进程:包含以下线程
- GUI渲染线程:
- 负责页面的绘制、布局
- 页面重绘重排就执行该线程
- 与js引擎线程互斥,可能会影响绘制ixaoguo
- js引擎线程:
- 负责解析执行js相关脚本
- 事件触发线程:
- 用于控制事件循环
- 满足触发条件,执行事件,将回调放入任务队列中
- 定时器触发线程:
- 执行相关定时任务
- 执行完毕后将相关的回调函数交由事件触发线程处理
- 异步http请求线程:
- 处理http请求
- 回调函数给事件触发线程处理
- GUI渲染线程:
- 首先js是单线程,同一时间只能执行一个任务,那么他是如何做到异步回调的呢
-
promise
- 是异步编程的一种解决方案,每一个异步任务都返回一个promise对象,该对象都可以使用then方法,允许指定的回调函数
- 从语法上来说,是一个构造函数
- 方法:
- then:可以接收构造函数状态处理变化,有两个参数,resolve与reject
- then也会返回一个promise对象,可以继续使用.then方法,这样也可以解决回调地狱
- all:他接收一个以promise对象组成的数组作为参数,当这个数组的所有promise对象状态变为resolve或者rejected,才会调用then方法
- race:也是以promise对象组成的数组作为参数,当数组其中一个promise对象状态为resolve或者rejected,就会调用then方法
- then:可以接收构造函数状态处理变化,有两个参数,resolve与reject
- 状态:
- pending、fulfilled、rejected
- 原理:
- 构造一个promise实例需要给promise构造函数传入一个函数,传入的函数有两个形参,同时这两个形参都是函数类型的参数,分别为resolve与reject
- promise的原型上还有个then方法,then方法就是来指定promise状态改变时确定执行的操作,resolve时执行第一个函数(onFulfilled),reject执行第二个(Onrejected)
- 当状态为resolve就不能变为reject
- 缺点:
- 一旦执行,无法取消
- 当处于pending状态,无法得知他进展到哪一步了
- 如果不设置回调函数,内部错误无法抛出
- 优点:
- 解决回调地狱
- peomise构造函数是同步执行,then是异步执行
-
既然 Vue 通过数据劫持可以精准探测数据在具体dom上的变化,为什么还需要虚拟 DOM diff 呢?
- vue初始化的时候会对data的数据进行依赖收集,一旦数据发生变化,响应式就会立马得知,所以vue是一开始就知道是哪个在发生变化了,
- 但是vue的响应式(push代表)是一个数据就需要一个watcher,一旦绑定数据细粒度过多就会产生大量的watcher,会带来内存以及依赖追踪的开销,但是细粒度过低的话,就无法精确的探测变化,所以vue使用中等细粒度的方案,在第一时间内检测到组件变化,然后在组件内部使用virtual dom diff获取更细致的差异(pull操作)
-
虚拟dom的优缺点
- vue通过编译将模板转换为渲染函数,执行一个渲染函数就可以得到一个虚拟dom,虚拟dom提供虚拟节点vnode和对两个新旧vnode进行对比得出差异,diff算法逐层比较,删除,添加操作,以此来更新需要更新的dom,达到减少对dom的操作,提高渲染速度,改善用户体验。
- 缺点:
- 首次渲染有大量的dom,需要做一层虚拟dom计算,会比innerhtml慢
- 优点:
- 无需手动操作dom,极大提高开发效率
-
v-model是如何实现的以及语法糖
- 语法糖:
- @input是对input输入的一个监听
-
<input v-model="test"> <input :value="test" @input="test = $event.target.value">
- 修饰符:
- .lazy:v-model.lazy:按回车触发@change事件(替代了@change事件),但是输入的值为string类型
- .number
- .trim
- 一般使用的元素:
- radio
- checkbox
- select
- 语法糖:
- 单页面与多页面
- 单页面:
- 一个项目中只有一个html页面,页面跳转只是局部刷新,不会重新加载全部资源
- 为什么切换快:因为每次切换时,不需要发送http请求,
- 首屏加载慢
- https://www.jianshu.com/p/90e95b203be0
- 单页面:
- 防抖与节流
- 防抖:尽管你触发事件,但是我是在触发该事件之后的n秒内执行,如果你在这n秒之内又触发事件,那么就会清楚之前的计时器(核心就是在n秒之内不要再触发该事件,那么我才会执行)
- 节流:高频率触发事件,但在n秒内只会执行一次
- 使用场景:
- 防抖:
- 登录、搜索用户点击按钮过快,发送多次请求
- 文本编辑器实时保存,当无任何操作后最后一秒保存
- 点赞取消点赞,需要获取最后一次操作结果发送给服务器
- 节流事件:
- 每隔几秒计算播放进度信息
- 拖拽:固定时间执行一次,防止高频率触发位置变动
- 防抖:
- 堆、栈
- 基本数据类型保存于栈,值都有固定大小,通过值访问即可
- 引用数据是保存于堆的对象,大小不固定,栈内存中存放对象的访问地址指向堆内存中的对象
- js不允许直接访问堆的对象,所以实际操作的是对象的引用地址
- 堆栈溢出:
- 操作系统会自动给每个进程分配最大2M栈空间,如果超过该上限,就会溢出
- 什么会导致溢出:
- 递归调用:就像你一直往一个空间一直放东西,一直入栈,直到调用结束,才会将地址出栈,同样的,如果你创建一个过大的数组,也会引起堆溢出
- 闭包
- 概念:两个函数互相嵌套,内部函数可以访问外部函数的变量
- 作用:
- 可以读取函数内部的变量
- 让这些变量的值始终保存在内存中
- 闭包就会让js的垃圾回收机制不会回收外部函数所占用的资源,因为外部函数内部嵌套的需要依赖于外部函数的变量
- 缺点:
- 最严重的问题就是内存泄漏,因为闭包会让函数内的变量都在内存中,导致内存消耗大
- 优点:
- 避免变量污染到全局
- 将变量存储到独立的作用域,作为私有成员使用
- GC:
- 在js中,如果一个对象不再被引用,就会被回收,如果两个对象互相引用,没有被第三方引用,也会被回收,但是函数a被其内部的b引用,函数b又被函数a外部引用,所以不会被回收
- 内存泄漏:
- 意外的全局变量,这里的全局指的是window,将变量使用完毕后设置为null
- 计时器使用完毕后没有回收
- 闭包
- 使用场景:
- 使用setimeout:
//原生的setTimeout传递的第一个函数不能带参数 setTimeout(function(param){ alert(param) },1000) //通过闭包可以实现传参效果 function func(param){ return function(){ alert(param) } } var f1 = func(1); setTimeout(f1,1000);
- 比如封装一个弹框点击组件:
- 点击确定按钮会触发点击相对应的事件,调用接口,如果事件写的是普通函数,那么this指向的是该函数而不是vue,里面方法就不能正常执行,当然也可以在函数外部声明that = this
- 使用setimeout:
-
箭头函数与普通函数
-
箭头函数this:
-
没有prototype
-
不能修改this指向
-
在定义的时候继承他外层的普通函数的this
-
如果外部没有普通函数,在严格模式下或者非严格模式都会指向window
-
-
-
什么是构造函数,他与类的区别
-
定义:通过new操作符来调用的,首字符大写,用new生成实例
-
创建过程:
-
当以new关键字调用时,会新开辟一个内存空间(堆)
-
函数体的内部指向该内存
-
执行函数体内的代码
-
返回该this
-
-
es6:class
- 他的绝大部分功能es5都可以做到
-
类中定义方法不需要加function,可以被子类继承的方法定义在类的prototype中
// es5 function Person (name , age){ this.name = name; this.age = age } Person.prototype.saying = function(){ return 'im saying ' } // es6 class Person (){ construcotr(name , age){ this.name = name ; this.age = age } saying(){ return 'im saying' } }
-
类中的内部所有定义的方法都是不可枚举的(not enumerable)
- 枚举:对象的属性是否可以遍历出来
-
在js中,基本数据类型原型上的属性是not enumberable
-
类和模块内部默认采用严格模式
-
子类继承了父类之后,必须在constructor中调用super方法,否则不能新建实例
-
因为子类没有属于自己的this对象,而是继承了父类的this对象
-
-
- 枚举:对象的属性是否可以遍历出来
-
-
改变this指向问题:
- this指向的是最后调用他的对象
- new关键字改变this指向
- 存储this到变量中
- 上下文调用:当第一个参数为null或者undefined,this指向window
-
call
-
apply
-
bind:先是创建一个新的函数,与被调用的函数有着相同的函数体,必须得调用,否则只是单一的绑定了而已
var Person = { name: "zhangsan", age: 19 } function aa(x, y) { console.log(x + "," + y); console.log(this); console.log(this.name); } aa.bind(Person, 4, 5); //只是更改了this指向,没有输出 aa.bind(Person, 4, 5)(); //this指向Person--4,5 Person{}对象 zhangsan
-
call与apply区别:参数不同,apply第二个参数为数组
-
-
addEventListener(事件 , 函数处理 , boolean)
-
事件是click、mouseLeave
-
当事件发生时所需要调用的函数
-
true或者false,指定为事件捕获还是事件冒泡,默认false,使用冒泡
-
移除:removeEventListener
-
-
事件阶段:
-
捕获阶段:从根节点到目标节点,途中经过各个dom节点,触发事件
-
目标阶段:事件到达目标节点,就到了目标阶段,触发事件
-
冒泡阶段:事件在目标节点触发,一层层向上,直到根节点
-
阻止:e.stopProgation()
-
-
obj方法:
-
Object.assign:将所有可枚举属性值复制到目标对象,如果是相同属性名,后面的会覆盖前面的值(浅拷贝)
-
Object.create:创建一个新对象
-
Object.entry:将对象的每个键值对作为数组的每一项
let obj = { name:"张三", sex:"男", age:20, height:150 } for ( let val of Object.entries(obj)){ console.log(val) } // (2) ["name", "张三"] // (2) ["sex", "男"] // (2) ["age", 20] // (2) ["height", 150]
-
Object.keys:返回一个由对象的属性组成的可枚举数组
-
Object.values:返回一个对象的属性值组成的可枚举的数组
-
-
for in for of区别:
-
for in :(遍历索引)
-
遍历对象的话返回对象的key值,遍历数组返回数组的下标
-
还会遍历到原型上的key值与手动添加的键值
-
遍历对象原型上可枚举属性
-
可以通过asOwnProperty判断
-
-
-
-
type mull === object
-
不同的对象在底层都用二进制表示,在js中,二进制前三位都为0的话会判断为object类型,null的二进制全为0,前三位自然为0
-
110:布尔类型
-
100:string
-
1:整型,数据是31位带符号整数
-
typeof Nan === number
-
nan:s1111 11111 1111
-
-
-
什么是实例对象,实例对象和函数对象的区别
-
js中判断数据类型的方式有哪些,都有什么区别
-
typeof :判断基础类型
-
instanceof:判断一个实例属于哪种引用类型
-
instanceof是根据给定对象实例的原型链去判断的,他会判断给定的instanceof后面的构造函数的prototpe属性是否出现在这个实例原型链还是那个,如果出现了,为true
-
只能用来判断对象和函数,不能用来判断字符串和数字等。判断它是否为字符串和数字时,只会返回false
-
-
Object.prototype.toString.call()
-
toString是Object原型对象上的一个方法,这方法会返回调用着的具体类型,也就是toString this指向的对象类型,返回的类型格式为【object array(还包括其他类型)】
-
-
-
实现链式调用:
-
发
function Person (){} Person.prototype.say = function(params){ console.log(params) return this } Person.say('第一次调用').say('第二次调用')
-
-
Vue 为什么要用 vm.$set() 解决对象新增属性不能响应的问题 ?你能说说如下代码的实现原理么
- vue2.0使用obejcy,defineproperty实现数据双向绑定
- 在vue实例初始化时候,对属性进行了get set转化
- 所以属性必须要刚开始的存在于data里,才能进行响应式操作
- 所以就造成了vue无法检测到vue的添加或者删除
- 如果目标数据是数组,会直接用数组的splice触发响应式
- 反之如果是对象,会先判断属性是否存在,对象是否是响应式的
- 最终如果要对对象进行响应式处理,就使用defineReactive进行响应式处理
-
说一下 Vuex 的原理以及自己的理解
- vuex是一个采用集中式管理vue状态的管理模式
- 包含state、mutations、actions、module、getter
- state:存储数据的,可以用this.$store.state来访问,为响应式的
- mutations:更改state的方法
- getter:可以认为是store的计算属性,他的返回值会随着他的依赖存储起来,当依赖值发生变化而随之发生变化
- actions:可以写任意的异步操作,来触发mutations从而改变state
- module:将store分割成模块,每个模块都包含state、mutation、getter、actions
- 我们在组件中触发的动作,一般都是想改变数据啥的,但是在vuex中,数据是集中进行管理的,我们不能直接去修改state里面的数据,所以会把这个动作commit到mutation中
- 然后mutations改变state的数据
- 在组件中使用$dispatch去触发actions的方法
- 为什么要用vuex:
- 因为比如说对于多层嵌套组件,传参就会比较复杂,不像父子组件通信稍微简单一些,而且后期代码也不好维护,所以就需要把组件共享的状态给抽离出来,统一管理,并且让任何一个组价都可以使用,这样就会让代码变得更加结构化更加容易管理!!!!
- v-model语法糖:
- 当在input中使用v-model其实是触发了元素的@input事件嘛,
- 通过v-bind将父组件的数据绑定到了子组件的props属性中,然后就通过$emit触发父组件元素的$input事件
-
vue虚拟dom 以及diff 算法
- 真实dom渲染流程:
- 先根据html元素生成一个dom树
- 再根据样式生成页面的样式表
- 再将dom树与样式表联合起来,形成render树
- 浏览器根据render树再进行布局
- js操作真实dom的代价:
- 用js或者jquery操作dom,浏览器会把生成的dom树从开始到结尾执行一遍,如果我们要执行操作多个dom节点,浏览器会收到第一个dom操作请求,会马上执行流程一遍,但是还会执行对此重复的操作
- 为什么要虚拟dom,优点是什么?
- 虚拟dom可以理解为是dom的js副本
- 如果是要更新几十个dom节点的话,虚拟dom不会立即更新dom,会将这几十次变化先保存到一个js对象,然后再统一更新到dom上,
- 页面的更新先全部更新在虚拟dom上,操作内存中的js对象速度要快一些,等更新完成后,将最终的js对象映射到真正的虚拟dom上,浏览器再去重绘重排
- diff算法:
- 通过对树节点的同层节点进行对比
- 特点:
- 只会同级比较,不会垮层级比较
- 每次diff都会调用updateChildren方法来比较,然后一层层递归下去,直到将oldVnode与newVnode对比完,每次找到相同节点,都会一层一层往下比较他们的子节点,是一个逐渐深入的递归遍历过程
- 真实dom渲染流程:
- keep-alive:
- include:字符串、数组、正则匹配缓存组件
- exclude:字符串、数组、正则匹配不被缓存组件
- max:数字,最多缓存多少组件实例
- computed与普通属性区别:
- 是基于依赖进行缓存的,当相关依赖发生变化,就会重新计算,并进行缓存
- computed是响应式的,method不是
- computed定义就像属性一样访问就ok了,method需要调用
- computed不支持异步,监听不到数据变化
- 购物侧结算价格
- vuex与localstore区别
- vuex存储在内存
- localStorage存储在本地,并且只能存储
- 应用场景:
- localStorage一般在跨页面传递数据使用
- vuex可以是响应式的,local不能
- 永久性:
- 刷新页面时vuex存储的值会丢失,local不会
- vue-router原理:
- 更新视图但是不重新请求页面
- 默认是hash模式,使用window.addEventListener('hasChange' ,callback,false)对浏览器的地址进行监听,当调用push时,将新路由添加到浏览器访问历史的栈顶,使用replace时,将栈顶的路由换成新路由
- hsitory模式:使用window.onpopstate对浏览器地址进行监听,有pushstate()与replacestate()方法,但是该方法需要服务端来辅助配合,避免url无法匹配到资源时能够返回页面,不然空白咋整。
- vue data某一个属性值发生改变后,视图会立即同步并且执行渲染吗?
- 不会,vue实现响应式会按照一定的策略进行dom更新的,
- 在更新dom时是异步执行的,只要侦听到数据变化,vue开启一个队列,如果同一个watcher被监听,就会被推入到一个队列中,然后去除重复数据,对于不必要的计算还是非常重要的,
- object.definedProperty缺点:
- 无法监听原生数组
- 必须遍历对象的每个属性
- 如果属性是对象,还得进行深度遍历
- proxy:
- 支持监听原生数组
- 可以对新添加的属性进行监听
- vue hook:
- 使用场景:需要在父组件上知道子组件什么时候被创建、更新啥的,一般情况下我们可以使用@monuted
<parent-component> <child-component @hook:mounted="handleChildMounted"></child-component> </parent-component>
- 但是在第三方组件中,根本不好使
- 可以使用@hook在父组件中监听子组件的@hook:created函数,不需要在子组件中再$emit
- 使用场景:需要在父组件上知道子组件什么时候被创建、更新啥的,一般情况下我们可以使用@monuted
- 动态路由:
- 场景:比如说商品详情页,需要传商品id
- 主要是使用path属性,使用动态参数,可以是this.$route.params获取到动态参数
- 为什么子组件不可以直接修改父组件数据:
- 为了维护父子组件的单向数据流
- 每次父组件更新数据了,子组件中所有的prop都会刷新,这是为了防止意外的改变父组件状态,可能导致数据流混乱,如果破坏了单向数据流,当系统比较复杂,维护成本就会比较高
- 只能通过$emit定义事件,父组件修改数据
- html5新特性,如何解决兼容h5新标签?如何区分html与h5?
- 新特性:
- 语义化标签:header、footer、nav
- 音频:audio、video
- 画布:canvas
- 地理:geolocation
- 拖拽释放:drag and drop
- localstorage(本地离线存储):浏览器关闭数据不丢失
- sessionstorage:浏览器关闭数据丢失
- 表单控件:calendar、date、time
- 兼容:
- 使用html5shiv插件
- 区分:
- 文档声明:
- h5:<!doctype html>
- 结构化语义:
- html:div
- h5:header
- 文档声明:
- 新特性:
- b标签与strong标签区别:
- b:为了加粗而加粗
- strong:为了标明重点而加粗
- AMD、CMD、commonJS
- commonjs:同步加载node服务端
- 一个文件就是一个模块,拥有独立的作用域,普通方式定义的变量、函数等都属于该模块
- 通过require加载模块
- 通过export与module.exports暴露模块
- 注意:
- 当exports和module.export同时存在,后者会覆盖前者
- 不会污染全局,因为都有独立作用域
- AMD:异步加载模块(浏览器端模块化开发规范)依赖前置
- 使用require进行模块化,通过require(' ' , function(){})加载
- defined进行声明
- CMD:js模块化 依赖延迟
- commonjs:同步加载node服务端
- 回调函数与任务队列区别:
- 回调函数:作为参数传递给一个函数,在一个函数执行完成后执行
- 任务队列:是一个事件队列
- 同步任务:主线程上排队执行的任务,前一个执行完才能执行下一个
- 异步任务:进入任务队列,当主线程的任务执行完毕后,开始异步执行
- js内置对象:
- encodeURL()
- eval()将string作为js代码执行
- isFinite()是否为无限数,参数首先会转换为一个数值
- parseInt()
-
h5兼容问题:
- fastclick:移动端设备上的网页点击有300ms延迟
- 来源:ios为了能够将pc端网页展示在iphone,添加了双击缩放功能
- 原因:浏览器需要判断是否为双击
- 解决:使用fastclick
- 播放视频不会全屏:
- webket-playsinline = ‘true’
- opacity为c3属性,只有部分浏览器支持
- 使用私有前缀开头
- ios端滑动不流畅:
- -webkit-overflow-scrolling:touch:让滚动条产生滚动回弹效果
- ios上拉下拉出现白色空白
created () { document.body.addEventListener('touchmove', (e) => { if (e._isScroller) return; e.preventDefault() }, { passive: false }) },
- ios中,手指下拉会触发touchmove事件,该事件触发的是webview容器,所以容器会拖动剩下空白
- 解决:监听事件禁止滑动
- 移动端点击穿透:
- 产生条件:
- 上面的元素触发点击事件,随即隐藏
- 下面的具有点击特性的元素也会触发click
- 使用fastclick并js初始化
- 产生条件:
- fastclick:移动端设备上的网页点击有300ms延迟
- css兼容:
- ie6使用margin:0 auto无法居中,父元素设置textalign:center
- opacity与visibity、display
- opacity:不会改变布局,但是会触发事件
- vibisity:不会改变布局,会触发事件
- display:从页面中删除
- 移动端1px:transform:scale(0.5)
- 居中:
- display:table
- vertical-align:middile,text-align:center
- 已知高宽
- absolute,50%减去自身高宽
- absolute,上下左右0,margin:auto
- 未知高宽:
- absolute,left:-50%,right:-50%,trnasoform:transliate(-50%,-50%)
- flex,justify-content:center,align-item:center
- display:table
- 盒模型:
- 标准模型:box-sizing:content-box,宽高不包括内边距、边框
- 怪异模式:box-sizing:border-box
- 清除浮动:
- 父盒子:
- over-flow:hidden
- height
- after微元素清除法
- 在最后一个浮动元素后添加clear:both
- 父盒子:
- 塌陷:父盒子随着子盒子的margin-top一起往下
- 父盒子:
- border
- padding-top
- over-flow:hidden
- float
- 父盒子:
- 栅格化原理:
- 比如ant的row与col,将一行分为24份,那col是几就占几分,底层是按百分比实现,结合媒体查询,实现响应式
- 原型链:
- 对象都有原型对象,每一个原型对象又是一个对象,都有他的原型,那么这样环环相扣,形成连式结构 ,最终指向null
- commonjs与es6模块引入区别:
- commonjs:相当于一个拷贝,如果导出一个值,内部修改是不会影响到他的
- es6是动态引用,不会缓存,
- axios与fetch区别:
- axios:
- 是对xhr的封装,是一个基于promise的用于浏览器
- 特点:
- 可以使用promise方法
- 可以使用并发请求:axios.all
- 可以取消请求:cancelToken
- 自动转换json数据
- fetch:
- 语法更加简洁
- 但是只对网络请求报错
- axios:
- 地址栏输入url到加载完成
- 浏览器会根据给出的url交给dns域名解析,找到对应ip,再向服务器发请求
- 然后服务器再向后台处理请求,返回数据啥的,浏览器再接受文件
- 浏览器再对接受到的资源进行解析吧,形成dom树啥的
- 再渲染页面
- https://juejin.im/post/6844903807286001677
- 前端安全:
- XSS:
- 恶意往web页面写html代码,比如我们做一个留言功能,别人在留言板里写js代码,窃取用户浏览器存储的信息等
- 解决:
<meta http-equiv="Content-Security-Policy" content="form-action 'self';">
- 使用meta标签
-
前后端对一些页面元素做过滤检查,过滤掉<>、style样式等
-
禁止使用内敛样式
- CSRF:跨域请求伪造
- 攻击者引诱用户进入第三方网站,然后在第三方网站中,向需要攻击的网站请求,因为用户已经在第三方登录过,,所以就可以直接获取信息向攻击网站操作,冒充用户身份
- 解决:
- 使用token验证,
- 服务端给前端一个token,保存到session中
- 前端也保存到本地,提交表单携带token
- 如果token不一致话,就拒绝请求
- 使用token验证,
- sql注入:
- 页面与数据库交互使用sql语句,假如使用drop table啥的sql
- 解决:
- 限制输入长度
- 输入校验
- 过滤掉sql的特殊字符 '' 、'' ''
- XSS:
- 布局:
- 百分比布局(流式布局)
- 高度不变,宽度自适应
- 在pad横屏下,宽度被拉长,页面被拉伸很多
- 媒体查询:
- 设置几个分区,但是要设计出多个方案
- rem布局:
- 使用js或者media根据html值改变font-size值
- 百分比布局(流式布局)
- BFC:
- 相当于一个盒子,内部的布局不会影响外部
- 如何形成:
- overflow不是visibl
- float不是none
- position为ab或者fixed
- 作用:
- 清除浮动
- 防止垂直margin合并
- 比如说垂直排列的两个div都有margin,那么上面的margin-bottom与下面的margin-top会合并,取两者最大值作为margin
- 解决:为一个元素添加div,设置Overflow-hidden
- js设计模式:
- 单例模式
- 观察者模式:只要被观察者数据发生变化就做出一些操作
- 从输入url到显示资源步骤 :
- 客户端 先检查本地有没有对应的ip地址,如果有就返回,反之请求上级dns服务器,直到找到根节点
- 客户端再向服务端发送连接请求(tcp)
- 客户端带有一个syn的标志数据包给服务器,在一定的时间内等待接收回复
- 接收到数据包之后,返回一个带有syn、ack标志的数据包来确认信息
- 客户端收到后发送一个ack数据包来表示握手成功
- 客户端 发送http请求
- 服务器响应请求,查找资源,并返回响应报文与资源
- 客户端先渲染dom树,再添加css样式与js脚本啥的,最终渲染到页面
- vue的data为什么是个函数
- obj是引用数据类型,如果不是函数,那么多个组件实例data都指向的是同一个地址,修改一个,影响其他
- data是函数,就会有自己的单独作用域
- vue的key:
- 在vue中,我们无需直接操作dom,操作数据来改变视图,背后使用了diff算法
- 用key给每个节点做个唯一标识
- 作用就是高效更新虚拟dom,diff算法可以识别到该节点,找到正确位置插入新节点
-
vue 单页面应用首屏加载卡顿如何解决:
-
关闭vueconfig的productionsoucemap为false(为了调试看源码使用的)
-
路由懒加载
-
require(‘@/component’)
-
-
使用cdn加快请求速度
-
比如有时候服务器不稳定啥的
-
打包时间太长、体积过大啥的
-
去掉不必要的console
-
可以使用骨架屏
-
-
-
vue的seo:
-
prerender-spa-plugin
-
- vuex:
- 场景
- 兄弟组件
- 需要共享的数据信息
- 缺点:
- 每次刷新之后state数据初始化,可以存储于localstorage,或者使用vuex-along
- 场景
- 数据更新视图不更新,原因是什么,如何解决?
- 在vue中,只有在data数据初始化里的值才是可以响应式的
- 数组操作:
- 数组使用一些方法是无法检测变动:
- slice方法是会返回一个新数组,不会修改原数组
- 数组使用一些方法是无法检测变动:
- 对象属性添加:vue.set、this.$set
- 动态改变数据很慢啥的:this.$forceupdate()
- 或者使用Obejct.assign 将可枚举的值从一个或者多个源头复制到目标对象,返回新对象
- get与post区别:
- 传送方式:
- get:url
- post:报文传输
- 传送长度:
- get:受限于url的长度限制
- post:无限制
- get产生一个tcp数据包,post产生两个tcp数据包
- get:浏览器会把浏览器的http header与data一起发送出去,然后服务器响应200
- post:浏览器会先发送header,服务器响应100,然后浏览器发送data,服务器响应200
- 安全性get要差一些,一般涉及到用户信息密码啥的都,但是一般查询数据啥的都可以用get
- get在回退时是可以的,但是post会再次请求
- get请求会被浏览器保存到历史记录里,但是post不会
- 传送方式:
- settimeout为啥不准:
- 因为js是单线程,会先执行主线程任务,再执行任务队列
- vue性能优化:
- 可以通过代码、项目打包、项目部署来优化
- 代码:
- 在组件初始化时,使用v-if 来控制组件 在首次使用渲染 减少初始化渲染
- 比如说我在做这个政权项目的时候,有时候页面操作很多dialog,然后在页面初始化的时候如果将那么多的dialog都同时渲染,那肯定会影响到性能的呀
- 如果有大量的不需要响应式的数据,可以使用object.freeze冻结,提高初次渲染速度
- 图片大小、懒加载
- 使用image-webpack-loader,在webpack中配置
- 懒加载也可以使用vue-lazyload,在main中配置
- 组件库按需引入:
- elementui就可以,使用babel-pluin,先安装插件,在 babelrc配置一下
- 在组件初始化时,使用v-if 来控制组件 在首次使用渲染 减少初始化渲染
- nextTick使用场景:
- 在created中获取渲染后的dom
2020前端面试专题整理
最新推荐文章于 2024-05-06 23:49:48 发布
