当前位置:   article > 正文

2022前端面试_前端面试 您的核心竞争力和劣势分别是什么

前端面试 您的核心竞争力和劣势分别是什么

1. Vue的优点?Vue的缺点?

优点:1.组件化开发能大幅提高开发效率、测试性,复用性。轻量级,虚拟dom,响应式,单页面路由,数据与视图分开。

缺点:单页面不利于SEO,不支持IE8一下,首屏加载时间长。

不支持 ie8 及以下,部分兼容 ie9 ,完全兼容 10 以上,因为 vue 的响应式原理是基于 es5
的 Object.defineProperty(),而这个方法不支持 ie8 及以下

2. vue 和 react 的异同点?

相同点:

  • 都使用了虚拟dom
  • 组件化开发
  • 都是单项数据流(父子组件之间,不建议子组件直接修改父组件的数据)
  • 都支持服务端渲染

不同点:

  • React的JSX,Vue的 template
  • 数据变化,React手动(setState),Vue自动(初始化已响应式处理,Object.defineProperty)
  • React单项绑定,Vue双向绑定
  • React用Redux,Vue用Vuex状态管理工具
  1. // react
  2. const [dataList, setData] = useState([]);
  3. const { package_list, update_tip, download_package_id } = res.data.data;
  4. setData(package_list);
  5. // 初始化列表和版本状态
  6. useEffect(() => {
  7. getInit();
  8. }, []);


3.MVVM是什么?和MVC有和区别?

MVC

  • Model(模型):负责从数据中取数据
  • View(视图):负责展示数据的地方
  • Controller(控制器):用户交互的地方,例如事件点击等
  • 思想:Controller将Model的数据展示在View上。

MVVM

  • VM:也就是ViewModel,做了两件事达到了数据的双向绑定,一是将【模型】转换成【视图】,即将后端的数据转换成所看到的页面。实现的方式是:数据绑定。二是将【视图】转换成【模型】,即将所看到的页面转换成后端的数据。实现的方式是:DOM事件监听 。
  • 思想:实现了View和Model的自动同步,也就是当Model的属性改变时,我们不用再自己手动操作dom,来改变view的显示,而是改变属性后该属性对应的View层显示会自动改变。它是一种双向数据绑定的模式,用viewModel来建立起model数据层和view视图层的连接,数据改变会影响视图,视图改变会影响数据 

4、vue双向数据绑定的原理?

vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式 的方式来实现的, 通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调

具体步骤:

第一步:需要observe的数据对象进行递归遍历,包括子属性身上的属性也都加上setter和getter,这样的话,给这个对象的某个值赋值,就会触发setter,那么就监听到了数据的变化。

第二步:compile解析模板指令,将模板中的变量转化为数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图。

第三步:watcher订阅者是observe和compile之间通信的桥梁,主要做的事情是:

1、在自身实例化时往属性订阅器(dep)里面添加自己

2、自身必须有一个update()方法

3、待属性变动dep.notice()通知时,能调用自身的update()方法,并触发compile中绑定的回调,则功成身退。

第四步:MVVM作为数据绑定的入口,整合observe、compile和watcher三者,通过observe来监听自己的model数据变化,通过compile来解析编译模板指令,最终利用watch搭起observe和compile之间的通信桥梁,达到数据变化-->视图更新,视图交互变化(input)-->数据model变更的双向绑定效果

5、$nextTick

比如点击按钮修改名字,这时候直接打印 this.ref.refContent.innerText 还是原来的名字

dom更新完毕后执行回调,确保操作更新后的dom

  • ref 需要在dom渲染完成后才会有,在使用的时候确保dom已经渲染完成。比如在生命周期 mounted(){} 钩子中调用,或者在 this.$nextTick(()=>{}) 中调用。
  • 如果ref 是循环出来的,有多个重名,那么ref的值会是一个数组 ,此时要拿到单个的ref 只需要循环就可以了。

6. 递归

递归就是函数内部自己调用自己

  1. function sum(n) {
  2. if(n === 1) {
  3. return 1;
  4. }
  5. return n + sum(n - 1)
  6. }
  7. console.log(sum(10)) //55

7、Vue的生命周期有哪些?

实例创建 —— dom挂载 —— 数据更新 —— 销毁

vue的生命周期常见的主要分为4大阶段8大钩子函数

1. 创建前后

  • 在beforeCreate生命周期执行的时候,data和method还没有初始化。
  • 在created的时候,data和method已经初始化完成

2. dom 挂载前后

  • 在beforeMounte的生命周期执行的时候,已经编译好了模板字符串,但是还没有真正渲染到页面中去
  • 在mounted的时候,已经渲染完成,可以拿到dom

3. 数据更新前后

  • beforeUpdate生命周期执行的时候,已经可以拿到最新的数据,但还没有渲染到视图中去
  • updated函数执行的时候,已经把更新后的数据渲染到视图中去了

4. 销毁前后

  • beforeDestroy实例正准备销毁阶段,此时data,method,指令还是可用状态。
  • 在destroyed的生命周期函数执行的时候,实例已经完全销毁,此时data,method,指令都不可用

另外还有两个生命周期不常用:

  1. keep-alive主要用于保留组件状态或避免重复渲染。
  2. activated只有在keep-alive组件激活时调用。
  3. deactivated只有在keep-alive 组件停用时调用。

8、v-if和V-show的区别? 

  • v-if是真正的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当的被销毁和重建,操作的实际上是dom元素的创建和销毁。
  • v-show就简单地多,不管初始条件是什么,元素总是会被渲染,并且只是简单的基于css进行切换,它操作的是display:none/block属性。
  • 总结:v-if有更高的切换开销,v-show有更高的初始渲染开销,如果要非常频繁的切换,则使用v-show,如果运行时条件很少改变则使用v-if。

9、v-model语法糖的原理? 

Vue内部的v-model是完成属性绑定 和事件监听 的语法糖。v-model用于表单数据的双向绑定,其实它就是一个语法糖,这个背后就做了两个操作:

  • v-bind绑定一个value属性
  • v-on指令给当前元素绑定input事件
  1. <input type='text' v-model='name'/>
  2. <input type='text' :value='name' @input='name=$event.target.value' />

10、为什么data是个函数,并且返回一个对象呢?

  • 因为一个组件是可以共享的,但他们的data是私有的,所以每个组件都要return一个新的对象,返回一个唯一的对象组件 ,不要和其他组件共用一个对象.
  • vue 组件可能存在多个实例,如果要用对象的形式定义data ,则会导致他们共用一个 data 对象,那么状态变更将会影响所有组件,这是不合理的;采用函数形式定义,在innitData时将其作为工厂函数返回全新data对象,有效规避多个实例之间的状态污染问题。
  • 使用return包裹后数据中变量只在当前组件中生效,不会影响其他组件

11、v-if 和 v-for 哪个优先级更高

  1. vue2中v-for的优先级高于v-if,可以放在一起使用,但是不建议这么做,会带来性能上的浪费
  2. vue3中v-if的优先级高于v-for,一起使用会报错。可以通过在外部添加一个标签,将v-for移到外层
  • 如果同时出现,每次渲染先会执行循环循环再判断条件,无论如何循环都不可避免,这样浪费了性能
  • 要避免出现这种情况,则在外层嵌套template,在这一层进行v-if 判断,然后在内部进行v-for循环

 14、使用过哪些Vue的修饰符呢?

  • lazy: 作用是改变输入框的值时value不会改变,当光标离开输入时,v-model绑定的值value才会改变。
  • .trim:作用类似于JS中的trim()方法,把v-model绑定的值的首位空格去掉
  • .number:作用是将值转换为数字
  • .stop:作用是阻止冒泡
  • .capture:事件默认由里往外冒泡,capture修饰符作用是反过来,由外往里
  • .self:作用是,只有点击事件绑定本身才会触发事件
  • .once:作用是事件只执行一次
  • .prevent:作用是阻止默认事件(如a标签的跳转)
  • .native:加在自定义组件事件上,保证事件能执行

 15、组件之间的传值方式有哪些?

vue2

vue组件通讯大致有三种:父传子,子传父,还有兄弟之间通讯

第一种:父传子:主要通过props来实现

具体实现:父组件通过import引入子组件,并注册,在子组件标签上添加要传递的属性,子组件通过props接收,接收有两种形式一是通过数组形式[‘要接收的属性’ ],二是通过对象形式{  }来接收,对象形式可以设置要传递的数据类型和默认值,而数组只是简单的接收

  1. props: {
  2. areaId: {
  3. type: String,
  4. default: "2"
  5. },
  6. isFullScreen: {
  7. type: Boolean,
  8. default: ""
  9. }
  10. }

第二种:子传父:主要通过$emit来实现

具体实现:子组件通过通过绑定事件触发函数,在其中设置this.$emit(‘要派发的自定义事件’,要传递的值),$emit中有两个参数一是要派发的自定义事件,第二个参数是要传递的值然后父组件中,在这个子组件身上@派发的自定义事件,绑定事件触发的methods中的方法接受的默认值,就是传递过来的参数

  1. // 子组件部分
  2. this.$emit("closeDia",false);
  3. // 父组件引入
  4. <InspectionDialog
  5. v-if="dialogVisible"
  6. @closeDialog="closeDialog"
  7. ></InspectionDialog>
  8. closeDialog() {
  9. this.dialogVisible = false;
  10. }

 第三种:兄弟之间传值有两种方法:

方法一:通过event bus实现

具体实现:创建一个空的vue并暴露出去,这个作为公共的bus,即当作两个组件的桥梁,在两个兄弟组件中分别引入刚才创建的bus,在组件A中通过bus.$emit(’自定义事件名’,要发送的值)发送数据,在组件B中通过bus.$on(‘自定义事件名‘,function(v) { //v即为要接收的值 })接收数据

  1. //组件A
  2. methods:{
  3. addList:function(){
  4. //重点: $emit自定义事件
  5. eventBus.$emit('add',this.todoList)
  6. }
  7. }
  8. //组件B
  9. methods:{
  10. acceptList:function(){
  11. // 重点:$on接收事件
  12. eventBus.$on('add',(message)=>{
  13. this.lists.push({ name:message,isFinish:false })
  14. })
  15. }
  16. }

 方法二:通过vuex实现

具体实现:vuex是一个状态管理工具,主要解决大中型复杂项目的数据共享问题,主要包括state,actions,mutations,getters和modules 5个要素,主要流程:组件通过dispatch到 actions,actions是异步操作,再actions中通过commit到mutations,mutations再通过逻辑操作改变state,从而同步到组件,更新其数据状态

Vue2和Vue3的组件传值 - 掘金

16、Vue中key的作用

  • key 的作用是唯一,其原理是 vue在patch 过程中通过key 可以精准判断;两个节点是否是同一个,从而避免频繁的更新不同元素,使得这个patch 过程中更加高效,减少dom 操作,提高性能
  • 另外,若不设置key 还可能在列表更新是引发一些隐蔽的bug
  1. Vue是通过虚拟dom来表示真是dom的,在去更新视图之前,要对前后两个虚拟dom树进行分析,以得出它们的区别。如果不设置key,vue会使用一种最大限度减少动态元素并且尽可能的尝试就地修改、复用相同类型元素的算法。而使用key时,它会基于key的变化重新排列元素顺序,并且会移出key不存在的元素。
  2. key的作用主要是为了更高效的对比虚拟dom中的某个节点是不是相同节点,是用来提高diff算法的性能表现。更具体一点,vue在patch(执行diff的算法,可翻译为打补丁算法)过程中判断两个节点是否是相同节点,key值相同是一个必要条件。
  3. key会提升效率某些特殊情况下,不写key会出错,在使用v-for循环时,尽量避免直接使用数组的下标为key,因为它们在删除操作时可能会导致渲染异常。最好是将key设成数据中的主键:可以把一项与另一项区别开的值。

17、vue中computed 和watch 的区别是什么?

共同点: 都是观察页面数据变化的

  1. computed 有 缓存,计算属性。数据在调用时,如果不发生变化,直接在缓存里面取值,适合读取数据,一定要有return 返回值。
  2. watch 没有缓存,事件监听,有异步请求就用 watch,深度监听对象 handler,deep:true,immediate: true(立即执行)
  3. watch 用于监听data中定义的数据的变化,只要被监听的数据发生了变化,就会执行对应的处理函数,监听路由的变化
  • 如果一个功能既能用watch,又能用 computed 实现,就使用 computed(简洁)
  • 如果一个功能既能用computed 和 methods 结合,就使用computed(缓存)

18、new 构造器创建对象的本质

  1. 首先执行 new 运算符. 即创建对象. 可以简单看做为 {} 的简写var p = new ...   '相当于'   var p = {}
  2. 调用构造器. 并隐含一个参数, 即刚刚创建的对象.
  3. 在构造器中使用 this 引用刚刚创建出来的对象.
  4. 构造器结束是 默认返回 this

19、 清除浮动的方法有哪些?

为什么要清除浮动,因为浮动的盒子脱离标准流,如果父盒子没有设置高度的话,下面的盒子就会上来 解决的方法有很多,主要目的是让父级元素有高度

  1. 给父级元素设置绝对定位:position:absolute(不推荐)
  2. 父级添加overflow属性(父元素添加overflow:hidden)(不推荐)
  3. 使用after伪元素清除浮动(推荐使用)
  1. .clearfix:after{
  2. content:".";/*加一段内容*/
  3. display:block;/*让生成的元素以块级元素显示,占满剩余空间*/
  4. height:0;/*避免生成的内容破坏原有布局高度*/
  5. clear:both;/*清除浮动*/
  6. visibility:hidden;/*让生成的内容不可见*/
  7. }
  8. .clearfix{zoom:1;/*为IE6,7的兼容性设置*/}

20、数据类型的判断有哪些方法?他们的优缺点及区别是什么?

  1. typeof:只能检测简单数据类型
  2. instanceof:能检测出复杂数据类型,不能检测简单数据类型,且不能跨iframe
  3. constructor:基本能检测所有的类型(除了null和undefined),constructor易被修改,也不能跨iframe
  4. Object.prototype.toString.call:检测出所有数据类型。

21、 项目中如何解决跨域

跨域前端和后端都可以实现,如果只针对vue,vue本身可以通过代理的方式可以实现,具体实现:在config中的index.js中配置proxy来实现:

22.浏览器如何显示12px以下的字号
 

  1. font-size: 12px;
  2. transform : scale(.833);
  3. -ms-transform: scale(.833);
  4. -moz-transform: scale(.833);
  5. -webkit-transform: scale(.833);
  6. -o-transform: scale(.833);

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/610428
推荐阅读
相关标签
  

闽ICP备14008679号