HTML
HTML语义化
使用更加具有语义化的标签来代替以前没有语义的div等 好处:结构清晰,方便维护,利于seo搜索
BFC
BFC(块级格式化上下文),创建了新的BFC的盒子是独立布局的,盒子内的元素不会影响盒子外面的元素。
BGC是在浏览器中创建了一个独立的渲染区域,在该区域的元素不会影响区域外元素的布局,这个渲染区域只对块级元素起作用
平时用了哪些方法进行性能优化
减少http请求、打包压缩上线的代码、使用图片懒加载、使用雪碧图、动态渲染组件、路由懒加载、CDN替换npm包
常用的2种盒子模型
标准盒子模型 width 和 height 指的是内容区域的宽度和高度,边框和外边距不影响内部尺寸 和 盒子尺寸
怪异模型 width 和 height 指的是内容区域+border+padding的宽度和高度
CSS
rem移动端适配
rem是css3新增的一个相对单位。rem是相对于HTML根元素的大小,使用flexible。
vm/vh 是相对于窗口的宽度和高度
常见的盒子垂直居中的方法
- 子绝父相定位来实现 top left 50% margin-top margin-left -50%
- 使用css3中的transform top left 50% translate -50%
- flex justify-content:center align-items:center
平时都是怎么实现跨域的
jsonp:利用 script 标签的src属性 没有跨域限制的漏洞,可以从其他来源动态产生 JSON 数据。JSPNP请求需要服务器支持 jsonp的优点 简单、兼容好 缺点仅支持get方法具有局限性
CORS:跨域资源共享是一种机制 当一个资源访问到另外一个资源(这个资源放在不同的域名或者协议或者端口),资源就会发起一个跨域的HTTP请求 需要浏览器和服务器的支持
Cookie、localstorage、sessionstorage 之间有什么区别
1.有效时间:
- localStorage 浏览器关闭后数据除非手动删除不然不会丢失
- sessionStorage 数据在浏览器窗口关闭后自动删除
- cookie 设置的cookie 过期时间之前一直有效,与浏览器关闭无关 2.存储大小:
- cookie 数据根据不同浏览器限制 大小不超过4k
- sessionStorage 和 localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大 3.与服务器之间的交互:
- cookie 是为了标识用户身份而存储在用户本地的数据(加密)
- cookie 始终 会在请求头在中自动携带
- sessionStorage 和 localStorage 不会自动把数据发生给服务器,仅在本地保存
清除浮动的方法有哪些?
为什么清除浮动,因为浮动的盒子脱离了标准流,下面的盒子会浮上来
1.给父级盒子添加 overflow:hidden 属性
2.额外标签法,在最后一个浮动的标签后新添加一个标签 设置clear:both
3.使用伪元素和双伪元素
css3动画
通过 @keyframes 规则,能够创建动画,以百分比来规定改变发生的时间,或者通过关键词 "from" 和 "to",等价于 0% 和 100%。
animation 的属性
-
animation-name keyframe的名字
-
animation-duration 默认0s 运行的总时长
-
animation-timing-function ease 运行的速度变化
-
animation-delay 0s 延迟时间
-
animation-iteration-count 1 重复的次数 infinite 无限
-
animation-direction normal 动画的执行方向 反向reverse
-
animation-fill-mode none 结束是否返回初始未知
-
animation-play-state running 是否被强制暂停
JS
js有哪几种数据类型
7种原始数据类型1种复杂数据类型 基础 number string boolean undefined null bignt symbol 复杂 Object
判断数据类型
- typeof
- 优点 使用简单
- 缺点只能检验基本数据类型 对象 函数 统一为object
- instanceof
- 优点 能检测出复杂数据类型
- 不能检测出基本数据类型
- constructor 原型检测
- 优点 基本能检测出来
- 缺点 null和undefined 检测不出来
- Object.prototype.toString.call()
- 能检测出所有的数据类型
常见的字符串方法有哪些
- includes() 用于判断一个字符串是否包含在另一个字符串当中 返回true或false
- indexOf() 查找传递的当前参数在当前字符串中首次出现的位置,如果找不到返回-1
- replace("终古","中国") 替换 将 终古 替换为 中国
- slice() 提取某个字符串中的一部分 不会修改原来的字符串
- split() 使用指定的分隔符来进行字符串的分割 分割后为数组
- substr() 返回字符串从指定位置开始到指定字符数的字符
常见的数组方法
- find() 返回数组中满足条件的第一个元素的值。否则为undefined
- findIndex() 返回数组中满足条件的第一个元素的索引。否则返回**-1**
- includes() 判断数组中是否有满足指定条件的值,返回true和false
- indexOf() 返回满足条件的第一个元素的索引。否则返回**-1**
- join() 将数组转换为字符串
- pop() 删除数组中最后一项
- push() 在数组的最后一项添加数据
- shift() 删除数组中第一个元素
- unshift() 在数组中第一项添加数据
- splice()第一个参数为索引值 第二个参数为删除的数量 第三个是替换或添加的元素
- reveres() 方法将数组进行颠倒 改变原数组
- sort() 冒泡排序 从小到大
数组的循环方式
every() 当数组里面的元素都满足条件时返回 true或false forEach() 遍历数组中所有数据 filter() 遍历并创建一个新数组 map() 遍历创建新数组 some() 遍历数组 当有一个满足条件时 返回 true 或 false
DOM事件流
分为 捕获 目标 冒泡
- 捕获阶段:从window对象依次往下传播,直到目标节点
- 目标阶段:在目标节点触发事件
- 冒泡阶段:从目标阶段依次往上传波 直到window对象
事件代理
利用事件冒泡机制把里层的元素需要响应的事件绑定到外层元素身上
Event loop
event loop又为事件循环 是一种任务的执行排队机制 所有的任务分为两种 一种为同步任务,另一种为异步任务,同步任务就是在主线程上排队执行任务,只有当同步任务执行完成后才能将满足条件的异步任务放到主线程中执行
深拷贝浅拷贝
- 浅拷贝:复杂一份相同的复杂数据时,有着相同的内存地址,当原数据改变,新数据也会发生改变
- 深拷贝:拷贝的复杂数据和原数据的地址值不同
- 浅拷贝实现:简单方法 直接赋值,然后是Object.assign()还有for in
- 深拷贝实现:2种 第一种JSON.stringfy JSON.parse 第二种通过递归来实现
js作用域与作用域链
作用域规定了如歌设置变量,也就是确定当前执行代码对变量的访问权限
作用域链的作用是保证执行环境里有权访问的变量的函数是有序的,作用域链的变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的
判断是一个变量是不是空对象
1.JOSN.stringfy方式 用JSON.stringfy将对象转换为json格式,与 '{}' 做比较 2.Object.keys 用Object.keys获取对象中的key值,如果对象中有key值,将返回一个key值的数组,如果数组为空,对数组的长度进行判断就可以
创建对象的几种方式
1.new object 创建 2.字面量创建 3.工厂函数创建
BOM与DOM讲解
- DOM 是 W3C 的标准,文档对象模型
- BOM 是 各个浏览器厂商根据 DOM在各自浏览器上的实现,浏览器对象模型
- window 是 BOM 对象,而非 js 对象;JavaScript 是通过访问BOM 对象来进行访问、控制、修改客户端
什么是原型链
每个实例对象上有一个__proto__ 属性指向构造函数的原型对象 他也是对象,也有__proto__ 属性 这样一层一层的查找就形成了原型链
什么是闭包
一个作用域可以使用另一个函数内部的局部变量 延长作用域,容易造成内存泄漏
什么是递归,有哪些缺点优点
如果一个函数在内部调用自身,那么这个函数就是递归函数
- 优点:因为可以反复调用自己来实现功能所以结构会比较少,可读性比较强
- 缺点:效率低 调用栈可能会溢出,比较浪费性能
bind apply call 有什么区别
都是改变this指向,但是apply 和 call 会调用函数,bind不会调用,apply的参数是数组,call的参数是可以放多个数组的
bind不会调用函数,可以用来改变定时器内部的this指向
模块化
AMD规范 CMD规范 COMMOBJS 规范 ES6规范
观察者模式与发表订阅者模式
观察者模式是一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新。观察者模式属于行为模式,行为模式关注的是对象之间的通讯,观察者模式就是观察者和被观察者之间的通讯
ES6的常用语法有哪些
let const
let const 具有块级作用域,不存在变量提升的went。
新增了箭头函数,简化了定义函数的写法,同时可以巧用箭头函数的this(箭头函数本身是没有this的,它的this取决于外部的环境)
新增了promise解决了回调地狱的问题
新增了模块化规范、利用import 和 export 来实现导入 导出
新增了解构赋值,ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值
新增了calss类,它类似于对象
箭头函数于普通函数的区别
首先是this
普通函数的this是指向window
箭头函数没有this this指向取决于外部环境
箭头函数没有arguments...
调用call/apply/bind 也无法改变箭头函数的this
this 指向问题
普通函数指向window
定时器中的this指向window
事件中指向事件的调用者
构造函数中指向实例对象
箭头函数指向取决于外部环境
call 无法改变箭头函数的this指向
async await 是什么
是 es7 中关于 promise的语法糖
async是声明一个函数是异步的,而await 是等待一个异步方法执行完成,它可以很好的替代promise中的.the
伪数组转真数组
es6中可以使用解构赋值
es6 后可以使用Array.from()
Array.prototype.slice.call() 常用
set map 是什么
set 是es6 提供的一种新的数据结构,它类似于数组,它的值是唯一值
map 是 es6 提供的一种数据结构,、它类似于对象,也是键值对的形式,但是键的范围不仅限于字符串,各种类型的值都可以当作键。
promise 是什么 有什么用
是什么 是一种解决异步编程的一种解决方案 他解决了ajax的回调地狱的问题
怎么用 使用new 创建一个promise 传入两个参数 resove reject分别表示成功后的回调函数和失败后的回调函数
使用.then()方法与其交互,返回一个promise 对象
peomise平时是用来干嘛的 里面有什么方法
平时用来解决ajax的回调地狱 return 一个new promise 参数放 reject 和 resovle 回调
然后再ajax 成功的回调中执行 reject 或者 resovle 回调,后面的.then拿到值并执行
- catch() :用于统一处理错误信息
- all() : 将多个promise对象合并为一个promise ,只有所有的promise完成后才会执行.then() ,.then()执行的结果也是个对象,依次存储每一个promise的结果
- race() :将多个promise对象合并为一个promise,只要有任何一个promise完成就会执行then , 且其他 promise 停止执行
垃圾回收机制
对不再使用的内存回收
内存泄漏:全局变量/闭包/DOM引用后为及时销毁造成的,需要手动删除
标记清除法:将【不再使用的对象】定义为【无法触及的对象】
引用计算法:一个对象,没有任何变量指向它,就说明不再需要了,但是引用技术有个致命的缺陷-循环引用造成的内存泄漏无法清除
(循环引用:两个对象通过内部属性指向对方,导致别的变量访问不到他们,也无法释放)
new的执行过程
new关键词是用来实例化一个对象的。new出来的对象,也就是实例化的对象,继承了构造函数的属性和方法,也就是new出来的对象,一出生就继承了父级对象(构造函数)的某些特征。那问题来了。为啥?它是怎么做到的?
这就不得不提到js中的原型和原型链。
js中每一个对象,都会隐式有一个__proto__对象,而对于每个函数,都会有叫prototype的对象,我们通过new 实例化的对象,它的__proto__就默认指向了它父级(构造函数)的prototype,而它父级本身的prototype,因为也是一个对象,所以它的__proto__也指向了它的父级(构造函数)的prototype
VUE
v-if 和 v-show 的区别
v-if 和 v-show 的话都是切换元素显示隐藏的
v-show是样式上的隐藏和显示 它是通过display:none/block 属性
v-if 是dom元素的创建和销毁
大量切换时会使用v-show ,一般则使用v-if因为还可以配合 v-else
vue的双向绑定原理
vue2是采用数据劫持结合发布者-订阅者模式的方法 通过Object.defineProperty()来劫持各个属性的setter,getter 在数据变动时发布消息给订阅者,触发相应的监听回调
v-model 与 .sync 的区别
v-model: v-model="num" @input="val=>num=val" 后面是回调函数 通过@emit
.sync::b.sync="num" @update:b="val=>num2=val"
注意: v-model 只能用一次,.sync可以有多个
v-for 循环为什么一定要绑定key
相当于给虚拟DOM添加了一个标识,当数据发生改变时利用key来对比新旧数据的虚拟DOM,找出不同的部分
VUE 的生命周期
初始化阶段
beforeCreate 获取到data 和 methods 初始化前
created 获取到data 和 methods 初始化后
挂载阶段
beforeMount 生命周期钩子 真实DOM挂载之前
Mountd 真实DOM渲染完毕
更新阶段
beforeUpdate 拿到更新之前的数据
updated 拿到更新之后的数据
销毁阶段
beforeDestory 组件被销毁之前
destory 组件被销毁
激活和非激活
actived 激活时触发
deactivated 失去激活状态触发
Vue中请求一般放在哪些生命周期中
可以放在 created、beforeMounted、mounted 中、因为在这三个钩子函数中 data 已经被创建,但是推荐放在 created 钩子函数中调用异步请求, 因为1.能更快的拿到服务器放回的数据,减少页面的loading 时间
ssr不支持 beforeMounted、moutend 钩子函数,所以放在 created 有助于一致性
computed 和 watch 的区别
计算属性和监听属性
computed计算属性支持缓存,不支持异步,通常是多个数据影响一个数据使用,比如购物车的商品总价
watch不支持缓存,数据变动立刻触发操作,支持异步,一个数据可以影响多个数据,有两个参数
deep深度监听 immediate 组件立即触发执行
$nextTick是生命,通常用在哪些地方
nextTick来实现。它会在dom更新完后才会执行
VUE的性能优化
- 在写v-for 加一个:key 这样就触发了diff算法,支持虚拟DOM。
- v-for 和 v-if 不要一起使用 v-for比v-if 的优先级更高 会先循环区别后再进行DOM的删除 浪费性能
- 路由懒加载
- keep-alive
- computed 和 方法区分使用场景,优先 computed
- watch 监听数据变化发请求,防抖/节流
- v-show/v-if
- 异步组件
VUEX
VUEX是什么
vuex是一个状态管理仓库 它是为了解决组件开发中,各个组件之间来回进行组件传值的
将多个组件需要使用的数据放到store中的state中
改变state中的数据需要外部调用dispatch方法来触发action中的方法然后通过commit方法来将修改的数据传递给mutation追后mutation使用state.xxx来修改数据
改变里面的数据使用mutation改变 mutation是同步的,异步操作需要放在action中
调用其他某块的方法
commit:调用本模块的mutation方法:commit('本模块mutation方法',实参)
调用其他模块的mutation方法:commit('模块名/方法名',实参值,{root:true})
dispatch:调用本模块的action方法:dispatch('本模块action方法',实参)
调用其他模块的action方法:dispatch('模块名/方法名',实参, {root:true})
getters:调用本模块的getters方法:getters.本模块的getters方法
rootGetters:调用其他模块的getters:rootGeeters['模块名/其他模块的getters方法']
VUEX的基本使用
定义:state:{
xxxx:zs
}
使用:this.$store.state.xxx
mapState使用
1.导入 import {mapState} from 'vuex
2.定义:
computed:{
...mapState(['xxx'])
...mapState({新名字:'satate的属性名'})
}
3.使用:
{{xxx}}
{{xxx,新名字:'xxxx'}}
定义
mutation:{
方法名(state,value){
state.属性名=value
}
}
使用:this.$store.commit('方法名',实参)
mapMutation使用
1.导入 import {mapMutation} from 'vuex'
2.定义
methods:{
...mapMutation('模块名',['方法名'])
...mapMutation('模块名',{'新名字','mutation'})
}
3.使用 this.方法名(实参)
定义:
getters:{
方法名(state.getters,rootState,rootGeeters){
return 新的值
}
}
使用:tihs.$store.getters.方法名
mapGeeters
导入 import {mapGeeters} from 'vuex'
定义
computed:{
...mapGeeters('模块名',['方法名'])
...mapGeeters('模块名',{'新名字':'xxx'})
}
Vue-router
Vue-router 是什么
Vue-Router是Vue中的官方插件,它适用于单页面应用,vue的单页面应用是基于路由和组件的 它的本质就是建立url和页面组件的映射关系
vue-router 的路由模式有哪些,是怎么用的
hash 和 history(上线需要服务器支持)
vue-router路由钩子函数
全局钩子:
- beforeEach:每次每一个路由改变都需要经过一次
- afterEach:后置守卫
- beforeResolve 解析钩子
组件对应的钩子
- beforeRouteEnter :进入前,进入路由所对应组件前,在beforeCreate之前产生的,它不能实例化对象this
- beforeRouteUpdate:更新前,路由更新了,但是路由所对应的组件不变,它是更新前触发,更新没有完成,如果需要获取更新完后的数据,要加$nextTick
- beforeRouteLeave:离开前,切换页面离开前就会触发,他在beforeDestory前执行
路由配置所对应的钩子
- beforeEnter:读取路由配置前会执行该钩子
进入一个页面时钩子的执行先后
beforeEach=>beforeEnter=>beforeRouteEnter=>beforeResove=>afterEach
路由更新执行先后
beforeEach=>beforeRouteUpdate=>afterEach
父子组件的钩子
beforeCreate父=>mounted父=>beforeMounted父=>beforeCreate子=>created子=>beforeMounted子=>mounted子=>mounted父
路由传值
传
- this.$router.push('/path地址?'参数名=值)
this.$router.push({
path:'/path地址'
query:{
参数名:值
}
})
收
动态路由匹配
{
path:'/xxx/:参数名?',
component...
}
传 this.$router.push('/xxx/123')
收 this.$route.push.参数名
name传参 路由配置
{
path:'/',
name:'home'
}
传 this.$router.push({ name:'home', params:{参数名:参数值} })
收 this.$route.params.参数名
路由钩子的执行先后
- beforeEach 每一个路由最先执行
- beforeEnter 读取路由的配置
- beforeRouterEnter 解析
- beforeResolve 完成解析
- afterEch
组件传值
父传子 子传父 兄弟传值 跨组件传值 provide inject mixin ref vuex locaStorage sessionStorage listeners
vue高级理解
data为什么不是对象是函数
每个组件Vue实例。组件共享 data 属性 ,当data 是一个值同一个引用类型的值发生改变时,改变其中一个影响其他的data
keep-alive的作用
避免组件重新渲染,再次调用组件时,可以从缓存中快输渲染,而不是重新渲染
include:匹配的 路由/组件 会被缓存
exclude : 匹配的 路由/组件 不会被缓存
盒子居中
定位加 margin-top :-50 margin-left:-50
定位加 tarnsform
flex
实现跨域
jsonp:利用script标签的src属性实现的跨域。需要服务器支持 只能发get请求
cors:这一般都是后端配置的
proxy代理
vue和react的区别
Vue:
- 语法简单
- 体积更小 React:
- 适合做一些大型的项目
- 更支持TS和原数的js
- 需要下载很多的依赖包
相同点: vue:
- 利用虚拟DOM实现更快的渲染
- 轻量级
- 响应式组件
- 易于集成路由工具,打包工具以及状态管理工具
slot插槽的使用
将父组件的内容放道子组件指定的位置叫做内容分发
地址相关问题
http缓存是什么
将已经请求的内容通过一个就近的仓库存放起来,下次在用就可以直接从仓库中获取
使用缓存控制 请求时发生不同的一些请求头来定义不同的缓存策略,
可以显著提高网站和应用程序的性能减少加载资源所需时间变得更加具有响应性
post和get的区别
get 一般用于数据的获取 一般不允许发送比较大的数据
post 一般用于修改服务器中的资源,对数据的大小没有限制
什么是同源策略
同源策略是浏览器的一种安全机制,来限制不同的网站不能通讯。必须协议,域名,端口号相同
token是什么
token可以说是令牌,用户在登录时生成的一个标识
当你登录完后再网站的每个请求都会带上token来辨别这个用户
一般存储在loaclStorage,cookie,或者sessionStorage中,在服务器一般存放在数据库中
一个页面从输入 url 到页面加载显示完成做了哪些
- 解析你输入的url
- http链接
- 进行三次握手和四次挥手
- 如果有需要重定向的需要重定向
- 通过js解析器解析js代码
- 构建dom树和cssom树 结合成渲染树
CSRF 和 XSS的区别
CSRF是利用网站本身的漏洞 去请求它的API
XSS是将网站注入js代码 然后执行里面的代码
cookie 和 localStorage 和 sessionStorage区别
每个请求头都会自动携带cookie,而其他必须手动设置
cookie的大小一般不会超过4k 其他2个最多5m 主要是根据浏览器的不同大小也不同
有效期间,cookie过期只设置的过期时间有关,跟浏览器是否关闭无关,localStorage必须手动删除,sessionStorage是浏览器关闭自动删除
http状态码
200 成功
301 永久重定向
302 临时重定向
304 资源已缓存在本地为修改
400 客户端语法错误
401 token失效
403 权限不够
404 服务器找不到这个网页
405 请求的方式错误
500 服务器错误
501 请求方式错误
405和501的区别:都是请求的方式错误,但是405是服务器支持你的请求方式但是你的请求方式错误,501请求的方式错误服务器没有你请求的方式
http中的contentType的作用
判断响应体的资源类型,根据不同的文件做出不同的展示,比如一个图片,有content-Type浏览器就展示图片,没有就展示文本
hash路由和history的区别
hash访问的是地址,history访问的是文件路径,history无#号且需要后端设置,不然刷新页面会404,hash是通过浏览器回退,history是通访问的页面记录来回退
hash不需要配置服务器,history需要后端进行配置
history才能真正做到前后端分离
vue-router和window.location区别:router是单页面操作,不会刷新页面
Vue3
vue2和vue3的区别
- 性能提升 首次渲染更快,diff算法更快,内存占用更少,打包体积更小
- 更好的Ts支持
- 提供新的写代码的方式(组合式API)
- vue3删除了$on的方法
- 移除过滤器
- 将.sync与v-model结合可以使用多个v-model
setup
- setup函数是一个新的组件选项,作为组件中的组合式api的起点
- setup中不能使用this,this指向undefined
- setup函数只会在组件初始化的时候执行一次
- setup 函数在beforeCreate生命周期钩子执行之前执行
vue3的生命周期
- setup 创建实例之前
- onBeforeMount 挂载DOM前
- onMounted 挂载DOM后
- onBeforeUpdate 更新组件前
- onUpdated更新组件后
- onBeforeUnmount 卸载销毁前
- onUnmount 卸载销毁后
ref响应式数据
因为setup不是响应式的,需要使用ref来定义响应式数据,使用ref需要加上.value来获取数据