前端面试题2021.4.26
第一:说一下vue的生命周期:
答:**beforeCreate(创建前),在数据观测和初始化事件还未开始
created(创建后),完成数据观测,属性和方法的运算,初始化事件,el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。
beforeUpdate(更新前),在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
updated(更新后),在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
beforeDestroy(销毁前),在实例销毁之前调用。实例仍然完全可用。
destroyed(销毁后),在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。**
第二:vue加载第一次页面的时候会触发哪几个周期函数?
答:第一次页面加载会触发beforeCreate、created、beforeMount、mounted, mounted说明dom渲染完毕
第三:为什么vue中data必须是一个函数 ?
答:类别引用数据类型
Object是引用数据类型,如果不用function返回,每个组件的data都是内存的同一个地址,一个数据改变了其他也改变了;
JavaScript只有函数构成作用域(注意理解作用域,只有函数{}构成作用域,对象的{}以及if(){}都不构成作用域),data是一个函数时,每个组件实例都有自己的作用域,每个实例相互独立,不会相互影响。
第四:VUE中hash模式和history模式的区别?
答:hash模式和history模式的不同
对于vue这类渐进式前端开发框架,为了构建 SPA(单页面应用),需要引入前端路由系统,这也就是 Vue-Router 存在的意义。前端路由的核心,就在于 —— 改变视图的同时不会向后端发出请求。
为了达到这一目的,浏览器当前提供了以下两种支持:
hash —— 即地址栏 URL 中的 # 符号(此 hash 不是密码学里的散列运算)。比如这个 URL:www.abc.com/#/hello,has… 的值为 #/hello。它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。
history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。
第五:谈谈你对对vuex的理解?
围绕着这三点来说:
vuex是什么?
2.vuex的核心概念;
vuex的属性;
vuex的数据传递流程;
3.为什么要用vuex?
答:
对于问题一,我们按官网的描述即可。vuex是一个专为vue.js应用程序开发的状态管理模式(它采用集中式存贮管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化)。
对于问题二,vuex五大核心属性:state,getter,mutation,action,module
state:存储数据,存储状态;在根实例中注册了store 后,用 this.$store.state 来访问;对应vue里面的data;存放数据方式为响应式,vue组件从store中读取数据,如数据发生变化,组件也会对应的更新。
getter:可以认为是 store 的计算属性,它的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
mutation:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
action:包含任意异步操作,通过提交 mutation 间接更变状态。
module:将 store 分割成模块,每个模块都具有state、mutation、action、getter、甚至是嵌套子模块
当组件进行数据修改的时候我们需要调用dispatch来触发actions里面的方法。actions里面的每个方法中都会有一个commit方法,当方法执行的时候会通过commit来触发mutations里面的方法进行数据的修改。mutations里面的每个函数都会有一个state参数,这样就可以在mutations里面进行state的数据修改,当数据修改完毕后,会传导给页面。页面的数据也会发生改变。
对于问题三,由于传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致代码无法维护。所以我们需要把组件的共享状态抽取出来,以一个全局单例模式管理。在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!另外,通过定义和隔离状态管理中的各种概念并强制遵守一定的规则,我们的代码将会变得更结构化且易维护
第六:vue中v-show和v-if的异同:
答:官方的理解:v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
二、个人理解:
相同点:v-show和v-if都能控制元素的显示和隐藏。
不同点:
实现本质方法不同
v-show本质就是通过设置css中的display设置为none,控制隐藏
v-if是动态的向DOM树内添加或者删除DOM元素
第七:如何解决vuex页面刷新数据丢失问题?
答:、问题描述:
一般在登录成功的时候需要把用户信息,菜单信息放置vuex中,作为全局的共享数据。但是在页面刷新的时候vuex里的数据会重新初始化,导致数据丢失。因为vuex里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,vuex里面的数据就会被重新赋值。
2、解决思路:
办法一:将vuex中的数据直接保存到浏览器缓存中(sessionStorage、localStorage、cookie)
办法二:在页面刷新的时候再次请求远程数据,使之动态更新vuex数据
办法三:在父页面向后台请求远程数据,并且在页面刷新前将vuex的数据先保存至sessionStorage(以防请求数据量过大页面加载时拿不到返回的数据)
分析:
办法一的缺点是不安全,不适用大数据量的存储;
办法二适用于少量的数据,并且不会出现网络延迟;
办法三是要讲的重点,办法二和办法一一起使用。
3、解决过程:
3.1、选择合适的浏览器存储
localStorage -- 是永久存储在本地,除非你主动去删除;
sessionStorage -- 是存储到当前页面关闭为止,和其他tab页没关联;
cookie -- 则根据你设置的有效时间来存储,但缺点是不能储存大数据且不易读取,会和后台进行交互。
本方法选择的是sessionStorage,选择的原因是由于vue是单页面应用,操作都是在一个页面跳转路由,另一个原因是sessionStorage可以保证打开页面时sessionStorage的数据为空,而如果是localStorage则会读取上一次打开页面的数据。
3.2、解决方案
由于state里的数据是响应式,所以sessionStorage存储也要跟随变化,而且只能通过mutations来改变state中的值。
首先在用户登录成功之后,然后把用户信息,菜单信息通过actions分发保存至vuex中。然后在菜单页面计算vuex中state的菜单数据,将数据解析组装成前端组件所需的格式,然后渲染组件,生成菜单树。如果页面没有刷新,则一切正常。
登录成功后将用户和菜单数据同步至vuex
登录成功后将数据同步至vuex
在菜单页面监听vuex中菜单数据
监听菜单数据
页面刷新的解决方案:
页面刷新的时候异步请求后台数据,然后动态更新vuex中的数据,其中会有一种情况就是,网络延迟、数据量大的问题。此时还没等vuex获取到后台返回的数据,页面就已经加载完成了,这样就会造成数据丢失。所以该解决方案就是,监听浏览器刷新前事件,在浏览器刷新之前就把vuex里的数据保存至sessionStorage中,刷新成功后如果异步请求的数据还没返回则直接获取sessionStorage里的数据,否则获取vuex里的数据。(只有刷新后还没取到后台数据,才会从sessionStorage里取。确保数据的安全性,就算获取sessionStorage里的数据也是安全的,因为每次刷新都会重新赋值,不必担心数据被篡改问题,其次就是对sessionStorage里的数据做了加密操作)
在父页面向后台请求数据,并且监听浏览器刷新前事件,将vuex数据保存至sessionStorage
在父页面向后台请求数据,将返回的数据分发至vuex
------------------------------------------------------------
第八:localStorage,sessionStorage和cooke的区别?
答:
三者区别
1)存储大小
cookie:一般不超过4K(因为每次http请求都会携带cookie、所以cookie只适合保存很小的数据,如会话标识)
sessionStorage:5M或者更大
localStorage:5M或者更大
2)数据有效期
cookie:一般由服务器生成,可以设置失效时间;若没有设置时间,关闭浏览器cookie失效,若设置了时间,cookie就会存放在硬盘里,过期才失效
sessionStorage:仅在当前浏览器窗口关闭之前有效,关闭页面或者浏览器会被清除
localStorage:永久有效,窗口或者浏览器关闭也会一直保存,除非手动永久清除,因此用作持久数据
3)作用域
cookie:在所有同源窗口中都是共享的
sessionStorage:在同一个浏览器窗口是共享的(不同浏览器、同一个页面也是不共享的)
localStorage:在所有同源窗口中都是共享的
4)通信
ccokie:十种携带在同源的http请求中,即使不需要,故cookie在浏览器和服务器之间来回传递;如果使用cookie保存过多数据会造成性能问题
sessionStorage:仅在客户端(即浏览器)中保存,不参与和服务器的通信;不会自动把数据发送给服务器,仅在本地保存
localStorage:仅在客户端(即浏览器)中保存,不参与和服务器的通信;不会自动把数据发送给服务器,仅在本地保存
5)易用性
cookie:需要自己进行封装,原生的cookie接口不够友好
sessionStorage:原生接口可以接受,可以封装来对Object和Array有更好的支持
localStorage:原生接口可以接受,可以封装来对Object和Array有更好的支持
应用场景
cookie:判断用户是否登录过网站,以便实现下次自动登录或记住密码;保存事件信息等
sessionStorage:敏感账号一次性登录;单页面用的较多(sessionStorage 可以保证打开页面时 sessionStorage 的数据为空)
localStorage:常用于长期登录(判断用户是否已登录),适合长期保存在本地的数据
第九:小程序的生命周期?
答:
Load 监听页面加载,一个页面只会调用一次
onShow 监听页面显示,每次打开页面都会调用
onReady 监听页面初次渲染完成,一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互
onHide 监听页面隐藏
onUnload 监听页面卸载
第十:小程序的兼容性问题(部分)
答:
条兼容问题处理方案
在做页面时遇到的一些关于兼容的问题处理方案:
1、background进行背景设置在IE浏览器下失效的原因是IE对空格非常的敏感,如果用background复写形式必须要注意!
2、img在IE下会有所差异,如需可设置outline:none;或者border:none进行调试
3、导航列表只需设定一个宽度,分别对li进行float:left和float:right;
4、如让二级下来菜单不影响一级的可使用绝对定位
5、在图片设置position属性时要注意relative和absolute的区别,一个在标准文档流中而另一个则脱离了标准文档流,在IE浏览器下要特别注意位置的变化!
6、在非a标签的hover属性在IE浏览器下调试可以使用组件hover.htc进行兼容
7、在IE浏览器下对PNG的兼容可以引进
8、在IE下可以使用组件ie-css3.htc进行兼容
9、在JS或JQ中如果要给背景图片设置位置必须要使用,完整的background-position: x y;单独设置的在火狐下无效
10、单独针对IE除了【if IE】设置可使用_color:red;
11、zoom:1;属性是IE浏览器的专有属性,Firefox等其它浏览器不支持。它可以设置或检索对象的缩放比例。除此之外,它还有其他一些小作用,比如触发ie的hasLayout属性,清除浮动、清除margin的重叠等。
12、清除浮动,最优方案为直接使用.clearfix::after { clear:both;display:block;content:' ' ;}
13、JQ下设置滚屏距离时,需在body后添加一个html否则IE和火狐不吃;如:$('body,html').animate({"scrollTop":wH},1000);