1,响应式布局如何实现
1,先从响应式的作用开始,然后再接着回答如何实现的响应式
响应式布局主要是为了让网站适配不同分辨率的手机端和电脑端,给用户更好地体验
实现响应式布局总共有五种方法:
1,百分比布局
利用属性设置百分比来适配不同的屏幕能够设置的属性有width,height,padding,margin 都可以来用百分比来设置而font-size不能用
2,媒体查询方式来实现
利用媒体查询方式底层原理也是用js实现的,用媒体查询的可以实现比百分比更加的细致页面布局但是利用媒体查询的话需要给每个不同分辨率都设置css,
但是IE:6,7,8都不支持媒体查询
3,rem响应式布局
页面中的rem单位的样式都是针对页面中font-size的值来进行计算的,所以有两种方式来适配不同的屏幕(1)利用媒体查询,在不同分辨率下给htm中font-size的值进行动态改变(2)利用js来给html的font-size动态赋值
4,vw响应式布局
根据PSD文件的宽度和高度作为标准,元素单位px转化为vw或vh,现阶段手机端用到的最多的就是这个方法
5,flex弹性布局
利用css样式中的的flex属性适配不同的屏幕
2,rem的布局原理
先回答rem的值是什么来决定的,然后在回答rem在页面中是如何实现的
1,rem的值是由根元素中的font-size的值的倍数,例如:页面中的宽度为750px,httm中font-size的值大小为100px这时候1rem=100px所以标题的大小也就是26/100=0.26rem
2,根据上面rem的计算方法我们得知rem的值是由页面中也就是更元素中的font-size的值进行改变的,我们可以利用rem+js来对,通过js来监视浏览器窗口大小来动态改变html中font-size的值得大小来改变rem,从而达到和设计图的高度相似,
3,数据类型的判断
要分别回答出数据类型的判断方法和他们的不足之处或者判断的范围
1,type0f typeof对于基本的数据类型判断没有问题,但是对于引用的数据类型是不起作用的,
2,instanceof 判断new关键字创建的引用数据类型,不考虑null和undefind以对象字面量创建的基本数据类型
3,constructor 它似乎可以完全应对基本数据类型和引用数据类型,但是如果声明了一个构造函数并把它的原型指向了array的原型,那么它也会显得力不从心
4,object.prototype.tostring.call()完美的解决方案
7,深拷贝和浅拷贝
深拷贝和浅拷贝都是针对复杂的数据类型来说的,深拷贝是层层拷贝,浅拷贝是只拷贝一层,
1,深拷贝,深拷贝的值如果是非基本数据类类型,则递归至基本数据类型后再复制,深拷贝复制的值与原来的值相互隔离互不干扰,
2,浅拷贝,浅拷贝的值如果是引用类型的话,则浅拷贝复制的是引用,复制的值改变,浅拷贝的值也会改变,但是可以用arra.parototype.slice()和array.prototype.contact(),扩展运算符,递归等递归方法来实现深拷贝
8,H5和css3的新特性
h5的新特性:
(1)语义化标签:header、footer、section、nav、aside、article
(2)增强型表单:input 的多个 type
(3)音频视频:audio、video
(4)本地存储:localStorage - 没有时间限制的数据存储;sessionStorage - 针对一个 session 的数据存储,当用户关闭浏览器窗口后,数据会被删除
(5)canvas,地理位置,拖拽
css3的新特性:
(1)选择器
(2)背景和边框
(3)文本效果
(4)2D/3D 转换
(5)动画、过渡
11,sessionStorage,localStorage,cookie的区别
1,localstorafe的生命周期是永久的,除非用户通过页面中的UIl来清理localstorage信息,否则这些信息将在本地进行长久保存,数据大小一般为5MB,不参与服务器通信
2,sessionStorage只在当前页面中有效,关闭页面和浏览器则无效,不参与服务器通信
localstorage和sessionstorage的作用域不同:
不同的浏览器不能共享localstorage和sessionstorage,相同浏览器不同页面不能共享sessionstorage,相同浏览器不同页面可以共享localstorage
3,cookie的优点:具有极高的扩展性和可用性
1,通过编程,控制保存在cookiezhongsession的大小
2,通过加密和安全传输,减少cookie被破解的可能性
3,在cookie中保存不敏感的数据,即使被盗也不会损失太多
4,设置cookie的生命周期,使之不会永远有效
cookie的缺点:
1,限制大小,一个domain只有20个cookie一个cookie只有4kb
2,安全性,cookie被破解session中的数据加密也没用
3,有些状态不能存在于客户端,例如一个防止表单重复添加大计数器,如果放在客户端就没啥作用
localstorag,sessionstorage和cookie都是存在于浏览器端的且同源
14,结构赋值
es6中允许按照一定的方式,从数组和对象中取值,对变量进行赋值,这种方法就叫做解构
解构赋值,左右结构必须一样,利用左边定义得值快速出去右边的值 而且 定义和赋值必须放在一起 不然的话会报错,取不出数据,左边定义的结构必须是js的形式,否则也会报错
15,async/await
async和await是一种同步的写法,也是一种异步的操作,他们两个必须同时去写才有效果,而且await有一个不错的效果就是他可以等待页面加载完成后在执行js文件,await传值主要是pomise来接受的而且pomise接受参数只需要一句话
18,promise是什么?有哪些状态和参数?如何使用?
1,promise主要用于异步操作
2,promise是将异步操作队列化,按照预期的顺序执行,返回预期的结果
3,对象之间传递和操作promise来帮助我们处理队列
resolve作用是将pendding状态变为resolve返回成功的结果
reject作用是将padding状态变为reject返回失败的原因
4,promise函数触发后就会触发.then()
promise有三种状态:pendding待定状态
fulfilled操作成功
reject操作失败
promise状态一经改变就不会再变了
19,for in 和for of有什么区别
1,在遍历属性的时候推荐使用for in 在遍历数组的时候推荐使用fot of
2,for in 循环输出的是key for of循环输出的是value
3,fot of 是弥补修复了es5中for in的不足
4,for of不能循环普通对象,需要object.keys()搭配使用
20,generator(异步编程)
1,generator是一个迭代函数生成器,其返回值是一个迭代函数
例如一个事件有三个状态A-B-C,而这三种状态的变化是A-B-C-A这就是状态机,genetator特别适合这种状态机
21,Ajax是什么
1,ajax并不是一种新的技术,ajax的全称是asynchronous javascript and html可以说是已有技术的组合,主要用来实现页面的局部刷新,早期浏览器并不支持ajax而是靠隐藏帧得方法事业异步操作,后来浏览器提供了ajax的原生支持
2,在使用ajax原生方式发送请求时主要通过XMLHttprequest(标准浏览器)ActiveXobject(IE)对象实现异步效果
3,基本步骤:
创建对象---》初始化请求---》设置http头信息---》指定回调函数---》发送请求
4,js框架(jQuery/EXTJS等)提供的ajaxAPI对原生的ajax进行了封装
22,跨域是什么及jsonp原理
跨域是指域名,端口号,协议三者都相等的是同域,不同的则为跨域
出于安全考虑,不允许浏览器跨域访问数据,但是可以跨域获取数据的文件内容,基于这一点我们可以利用script标签中的src属性访问js文件形式获取js脚本,并把这个脚本作为为函数调用,该函数调用的参数是服务器返回的数据,为了获取这里的数据需要在页面中定义回调函数,在回调函数中处理服务器返回的数据
23,跨域的解决方式
1,jsonp原理:利用动态创建的script标签请求后端地址,然后传递callback参数,后端接收callback参数,后端经过处理返回callback参数调用方式,callback中的参数就是json
优点:浏览器兼容性好
缺点:只支持grt方式
2,代理:在vue中通过config文件中index文件配置,其中有一个poxyTable来配置跨域,vue2.x和vue3.x都是利用这种方法来跨域的
3,CORS:全称为跨资源共享,它是利用后端工程师来实现跨域的,只需要后端工程师来配置即可
优点:无需前端工程师配置
缺点:浏览器支持版本有要求chrome13+ ie11+firfox3.5+
24,说下URL到加载过程中都进行了什么操作
1,解析DNS
2,TCP连接
3,发送http请求
4,向服务器放松请求并返回数据
5,浏览器解析渲染页面
6,连接断开
三握四挥的相关问题
三次握手均是在页面建立连接之前进行的
第一次握手:客户端向服务端发送请文保
第二次握手:服务端收到请求,同意链接就响应
第三次握手:客户端收到来自服务端的响应后再次发送一个确认报文段
四次挥手:
其中两次都是分别断开了不同方向的链接
第一次挥手:A向B发送了连接释放请求
第二次挥手:B收到A的连接释放请求后向各个应用发送已于这个方向释放了链接
第三次挥手:B发送完数据后,向A发送释放请求
第四次挥手:A收到了B的释放请求后向B发送确认应答
27,vue数据双向绑定的原理
1,实现一个数据监听器observer,利用observer对对象中的每个属性进行监听,如有变化拿到最新值并及时通知订阅者
2,实现一个指令解析器complie,对每个元素的节点进行扫描,根据指令模板替换数据,以及绑定到相应的更新函数
3,实现一个watcher,作为连接observer和complie之间的桥,能收到每个属性的变化并且执行指令绑定的相应回调函数,从而更新视图
29,vue生命周期
beforecreate :组件没有实例化,因此无法获取相data和el,所以就咩办法执行methods,computed,data等方法和数据的操作
created : 实例创建之后被调用,在这一步已经完成了以下的操作:数据观测,属性和方法的运算,watch/event事件回调,完成了数据初始化
beforemount : 挂载开始之前调用,相关的render函数首次被调用,实例完成以下配置:编译模板,把data中的数据和模板生成html,完成了el和data的初始化,注意此时还没有挂载html到页面上
mounted : 挂在之后把html渲染到了html页面,此时一般写ajax操作,只执行一次
beforeupdata : 是在数据更新之前进行调用的,发生在虚拟DOM重新渲染和打补丁之前,可以在该函数中进一步更改状态
updataed : 由于数据更新导致了虚拟DOM重新渲染和打补丁,调用时组件已更新,所以执行依赖于DOM操作,在该函数中不能执行更改状态,否则就导致了无限循环
beforedestory : 实在页面销毁之前调用,此时还可会利用this来获取实例,这里可以做一些重置操作,比如清理计时器等
destoryed : 此时在实例销毁后调用,调用后所有事件见会被监听器移除,所有子组件实力也会被销毁
vue路由传参
vue中有两种路由传参的方式
1,query传参:通过router-link或者this.
r
o
u
t
e
r
.
p
i
s
h
(
)
传
递
u
r
l
地
址
并
且
用
问
号
来
传
参
,
在
页
面
用
t
h
i
.
router.pish()传递url地址并且用问号来传参,在页面用thi.
router.pish()传递url地址并且用问号来传参,在页面用thi.route.query.id来接收
优点:通用性比较好,数据不会丢失
2,params传参:通过router-link或this.router.push()传递url地址用/来拼接参数,在页面中用this.$route().params.id
优点:传递数据量在,优雅
缺点:刷新页面数据丢失
31,路由守卫
vue的路由守卫分为全局路由守卫,组件路由守卫,路由独享守卫
全局路由守卫(触发路由就会触发的钩子函数)它们分为前置路由守卫,后置路由守卫
beforeEach(to,from,next)
afterEach(to,from,next)
实现方法:
router.beforeEach((to, from, next) => {
console.log(to) => // 到哪个页面去?
console.log(from) => // 从哪个页面来?
next() => // 一个回调函数
}
组件路由守卫(是指在组件内执行的钩子函数,类似于组件中的methods方法)
beforerouterenter (to,from,next)
beforerouterupdata(to,from,next)
beeforerouterleave(to,from,next)
实现方法:
beforeRouteEnter (to, from, next) {
// 注意,在路由进入之前,组件实例还未渲染,所以无法获取this实例,只能通过vm来访问组件实例
next(vm => {})
}
beforeRouteUpdate (to, from, next) {
// 同一页面,刷新不同数据时调用,
}
beforeRouteLeave (to, from, next) {
// 离开当前路由页面时调用
}
路由独享守卫(在需要配置的路由中放上):
beforeEnter(to,from,index)
实现方法:
export default new VueRouter({
routes: [
{
path: '/',
name: 'home',
component: 'Home',
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
32,vuex中的state,getters,mutatinos,actions,modules,plugings用途和用法
用途:
state 存放状态
mutations 对state成员操作
geeters 加工state成员给外界(计算属性)
actions 异步操作
modules 模块化状态管理
plugings 插件(vuex的一些设定的初始化时期运行的内容)
用法:
state是用来存放一些vuex中的一些数据的
mutstions对state中的数据进行修改,在页面中调用使用this.$store.commit调用
geeters类似于组件中的计算属性,返回的值也会被缓存,在组件中使用$sotre.getters.fun()
actions异步操作,在组件中使用是$store.dispath('')
modulesstore 的子模块,为了开发大型项目,方便状态管理而使用的
plugings是一个函数内容,其中的第一个参数内容是store对象内容,方便插件对于store对象的调用
33,vue中key的作用
key 值:用于管理可复用的元素。
(1)key会使Vue会记住元素们的顺序,并根据这个顺序在适当的位置插入/删除元素来完成更新,这种方法比没有key属性时的就地复用策略效率更高。
(2)使用key属性强制替换元素,因为当key改变时,Vue认为一个新的元素产生了,从而会新插入一个元素来替换掉原有的元素
34,vue自定义指令和使用
vue自定义指令有全局指令,局部指令
全局指令:
使用vue.directive()来进行全局注册
Vue.directive('focus', {
// 当绑定元素插入到 DOM 中。
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
局部指令:
directives: {
// 注册一个局部的自定义指令 v-focus
focus: {
// 指令的定义
inserted: function (el) {
// 聚焦元素
el.focus()
}
}
}
自定义指令有:
bind:当指令第一次绑定到元素时调用
insterted:被绑定元素插入父节点时调用
updata:所在组件的VNode更新时调用
componentUpdata:所在组件的VNode及孩子的VNode更新时调用
unbind:指令于元素解绑时调用
钩子函数还被赋予了以下参数:
el:
指令绑定的元素,可以用来操作DOM
bidding:
一个对象,包含以下属性
name:指令名
value:指令绑定的值
oldValue:指令绑定的前一个值
expression:绑定值的字符串形式
age:传给指令的参数
35,vue常用修饰符
.stop:阻止冒泡事件
.prevent:阻止默认事件
.captrue:触发事件捕获
.self:当事件在元素本身时触发回调
.once:只执行一次
.passive:Vue 还对应 addEventListener 中的 passive 选项提供了 .passive修饰符
36,keep-alive作用
它可以使被包含的组件保留状态,或避免重新渲染,例如;商品详情回退到列表的时候,页面回到顶部,这时候keep-alive就发挥了它的作用了,它有两个参数分别是
include - 字符串或正则表达,只有匹配的组件会被缓存
exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存
用法也很简单只需要给将要缓存的组件进行包裹即可,但在项目中的话需要vue-router使用
<keep-alive>
<router-view>
<!-- 所有路径匹配到的视图组件都会被缓存! -->
</router-view>
</keep-alive>
此时所有视图组件都会被缓存,但是如果想要只缓存单个组件就需要在配置路由页面给每个路由加上一个新的属性
{
path: '/',
name: 'home',
component: Home,
meta: {
keepAlive: true // 需要被缓存
}
},
在App.vue中配置
<keep-alive>
<router-view v-if="$route.meta.keepAlive">
<!-- 这里是会被缓存的视图组件,比如 Home! -->
</router-view>
</keep-alive>
37,Object.defineProperty()方法有何作用
Object.defineProperty()的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性
Object.defineProperty(obj, prop, desc)
1,obj 需要定义属性的当前对象
2,prop 当前需要定义的属性名
3,desc 属性描述符
一般通过为对象的属性赋值的情况下,对象的属性可以修改也可以删除,但是通过Object.defineProperty()定义属性,通过描述符的设置可以进行更精准的控制对象属性
返回值:
返回被操作的对象,即返回 obj 参数
用途:
1) vue 通过 getter-setter 函数来实现双向绑定,get 和 set 叫 存取描述符,有 以下可选键值:
get: 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方 法返回值被用作属性值。默认为 undefined。
set: 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为 undefined。
2) 俗称属性挂载器
3) 专门监听对象数组变化的 Object.observe()(es7)也用到了该方法
38,虚拟DOM和diff算法
1)虚拟 DOM 的最终目标是将虚拟节点渲染到视图上,了避免不必要的DOM 操作,虚拟 DOM 在虚拟节点映射到视图的过程中, 将虚拟节点与上一次渲染视图所使用的旧虚拟节点(oldVnode)做对比,找出真正需要更新的节点来进行 DOM 操作,从而避免操作其他无需改动的 DOM。简而言之:提供与真实DOM 节点所对应的虚拟节点 vnode 将虚拟节点vnode 和旧虚拟节点 oldVnode 进行对比,然后更新视图
2)a. 用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中
b. 当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异
c. 把所记录的差异应用到所构建的真正的 DOM 树上,视图就更新了
39,vue 中数组中的某个对象的属性发生变化,视图不更新如何解决
问题原因:因为 vue 的检查机制在进行视图更新时无法监测 数组中的某个对象的属性值的变化
有三种解决方案:
方案一:利用 this.set(this.obj,key,val)
例:this.set(this.obj,‘k1’,‘v1’)
方案二:就利用 Object.assign({},this.obj)创建新对象
如果是数组就 Object.assign([],this.obj)
如果是对象就 Object.assign({},this.obj)
40, vue3.0 与 vue2.0 的区别
(1)默认进行懒观察(lazy observation)
2.x 版本,不管数据多大,都会在一开始就为其创建观察者。当数据很大时,这可能会在页面载入时造成明显的性能压力。
3.x 版本,只会对「被用于渲染初始可见部分的数据」创建观察者,而且 3.x 的观察者更高效。
(2)更精准的变更通知
比例来说:
2.x 版本中,使用 Vue.set 来给对象新增一个属性时,这个对象的所有 watcher 都会重新运行;
3.x 版本中,只有依赖那个属性的 watcher 才会重新运行。
(3)3.0 新加入了 TypeScript 以及 PWA 的支持
(4)部分命令发生了变化:
下载安装 npm install -g vue@cli
删除了vue list
创建项目 vue create
启动项目 npm run serve
(5)默认项目目录结构也发生了变化
移除了配置文件目录,config 和 build 文件夹
移除了 static 文件夹,新增 public 文件夹,并且 index.html 移动到 public 中
在 src 文件夹中新增了 views 文件夹,用于分类 视图组件 和 公共组件