VUE高频面试题

题目


1、比较一下vue和react
2、vue组件之间的通信种类,通信实现方式
3、说说对vuex的理解
4、说说Vue的MVVM实现原理
5、说说对spa单页面的理解,它的优缺点
6、v-show和v-if的区别
7、怎么理解vue的单向数据流
8、computed和watch的区别
9、数据双向绑定原理
10、说说v-router的理解


答案
1、比较一下vue和react
相同点:

都是组件化开发,都有虚拟dom
都支持props进行父子组件之间数据通信
都支持数据驱动视图,不直接操作dom
都支持服务器端渲染
不同点:

数据绑定:vue实现了数据的双向绑定,react数据流动是单向的
组件写法不一样,react推荐把html和css都写进javaScript中,vue推荐html,css和js分开
React严格上只针对MVC的view层,Vue则是MVVM模式


2、 vue组件之间的通信种类,通信实现方式
通信种类:

父组件向子组件通信
子组件向父组件通信
隔代组件之间通信
兄弟组件之间通信
props(父传子):
1子组件通过 props方法获取父组件传递过来的值。props中可以定义能接收的数据类型,如果不符合会报错.
2父组件通过属性将值传递给子组件

Vue.component('menu-item',{
 props:['title'] // props后面跟一个数组,数组中的内容为字符串,这个字符串可以当做属性类使用。
 template:'<div>{{title}}</div>'   
})
<menu-item title="向子组件传递数据"> </menu-item>
<menu-item :title="title"></menu-item> <!--可以使用动态绑定的方式来传值-->

vue自定义事件(子传父):
$emit用来触发事件,$on用来监听事件

<button v-on:click='$emit("countSum")'> 计算</button>
<menu-item v-on:countSum='sum+=1'></menu-item>

eventbus(兄弟组件传值)

  1. 创建事件总线
  2. 通过事件总线发射一个事件名称和需要传递的数据
  3. 通过eventbus的$on()方法去监听兄弟节点发射过来的事件
     // 创建一个空的vue实例,作为事件总线
        var eventbus = new Vue()
        Vue.component('father', {
            template: '<div><son></son><daughter></daughter></div>',
            components: {
                son: {
                    data() {
                        return {
                            mySisterName: ''
                        }
                    },
                    template: '<div>{{mySisterName}}</div>',
                    mounted() {
                        // 通过eventbus的$on()方法去监听兄弟节点发射过来的事件
                        // $on有两个参数,一个是事件名称,一个是函数,该函数的默认值就是传递过来的数据
                        eventbus.$on('tellBroMyName', data => {
                            this.mySisterName = data
                        })
                    }
                },
                daughter: {
                    data() {
                        return {
                            myName: '小雪'
                        }
                    },
                    template: '<button @click="emitMyName">{{myName}}</button>',
                    methods: {
                        emitMyName() {
                            // 通过事件总线发射一个事件名称和需要传递的数据
                            eventbus.$emit('tellBroMyName', this.myName)
                        }
                    }
                }
            }
        })

ref(用于父子组件通信)

ref被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 r e f s 对 象 上 。 如 果 在 普 通 的 D O M 元 素 上 使 用 , 引 用 指 向 的 就 是 D O M 元 素 ; 如 果 用 在 子 组 件 上 , 引 用 就 指 向 该 子 组 件 实 例 通 俗 的 讲 , r e f 特 性 就 是 为 元 素 或 子 组 件 赋 予 一 个 I D 引 用 , 通 过 t h i s . refs对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向该子组件实例 通俗的讲,ref特性就是为元素或子组件赋予一个ID引用,通过this.refs对象上。如果在普通的DOM元素上使用,引用指向的就是DOM元素;如果用在子组件上,引用就指向该子组件实例通俗的讲,ref特性就是为元素或子组件赋予一个ID引用,通过this.refs来访问元素或子组件的实例

attrs/listeners

a t t r s 可 以 获 取 父 作 用 域 传 入 的 值 ( 不 包 括 p r o p s 中 的 ) , attrs可以获取父作用域传入的值(不包括props中的),attrs可以获取父作用域传入的值(不包括props中的),listeners相当于父作用域的事件监听器,那我们就可以用这两个属性实现祖孙之间的数据通信,主要是给中间的父组件绑定两个属性v-bind=“a t t r s " v − o n = " attrs" v-on="attrs"v−on="listeners”,并且不能在props中声明传入的值,"a t t r s " 用 于 接 受 f a t h e r . v u e 传 入 的 值 , attrs"用于接受father.vue传入的值,attrs"用于接受father.vue传入的值,listeners用于监听触发事件传值给father.vue.
(当组件B声明了传向C组件的值时,C组件则通过$attrs得不到该值,相当于被拦截了,要传给C,则不能在此声明)

provide和inject
这对选项是一起使用的。以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。
通俗的说就是:组件得引入层次过多,我们的子孙组件想要获取祖先组件得资源,这个就是这对选项要干的事情。
provide:是一个对象,或者是一个返回对象的函数。里面呢就包含要给子孙后代的东西,也就是属性和属性值。
inject:一个字符串数组,或者是一个对象。属性值可以是一个对象,包含from和default默认值

3、说说对vuex的理解

vuex是一个专为 Vue.js 应用程序开发的状态管理模式
作用: 集中式管理vue多个组件共享的状态和从后台获取的数据
State:state为单一状态树,在state中需要定义我们所需要管理的数组、对象、字符串等等
Getter:类似于组件中computed的作用 根据当前数据算出一些新的数据,可以避免数据的冗余
Mutation:唯一改变store状态的方法,且必须是同步函数
Action: 用于提交mutation,常用来编写异步方法
Module:将复杂的模块拆分成多个store,,方便后期维护

4、 说说Vue的MVVM实现原理
MVVM是有一种软件架构设计模式,核心是ViewModel层,它就像是一个中转站,负责转换Model中的数据对象,来让数据变得更容易管理和使用,该层向上与视图层view进行双向的数据绑定,向下与Model层通过接口请求进行数据交互。
view是视图层,也就是所谓的用户界面。
model层是指数据模型层,存放着后端人员各种业务逻辑和数据操作。
viewModel层指的是由前端人员组织生成和维护的视图数据层,在这一层,前端开发者对后端获取的Model数据进行处理,做二次封装,以生成符合 View 层的数据模型

这样开发者就只需要处理和维护ViewModel层,更新数据视图就会得到相应的更新,view层展现的数据不是model层的数据,而是viewModel层的数据。由viewModel层负责与model层进行交互,就可以实现view层和model层的解耦合。

5、 说说对spa单页面的理解,它的优缺
spa是单页面,就是所有的html,css,js都只在web页面首次加载时进行,当加载一次完成后就不再因为用户的操作而进行重新加载,而是利用路由机制来实现页面的变换。
优点:用户体验比较好,浏览网页速度快。对服务器压力比较小
缺点:页面首次加载会比较慢。由于所有的内容都只在一个页面中动态替换显示,所以seo难度较大

6、v-show和v-if的区别
都能控制元素的隐藏与显示,本质上是实现方式的不同,v-show是针对css元素中的display属性进行切换,当隐藏时直接切换成none,并不是实现真正的渲染,而v-if是真正的实现条件渲染,针对dom树添加或删除元素。
其次的区别v-show不管初始条件是什么,都会进行渲染,而v-if是懒加载,只有条件为真时,才会开始渲染块
因此v-if由于需要不断的销毁创建元素,所以消耗比较大,适用于切换比较少的场景,v-show适用于切换比较频繁的场景。

7、怎么理解vue的单向数据流
所有的props都使得父子之间形成了一个单向下行绑定:父级prop的更新会向下流动到子组件中,但是反过来不行,这样可以防止子组件意外改变父组件的状态,从而导致应用数据流难以理解
并且每次父组件更新数据流就会把子组件中所有的prop刷新为最新的值子组件想修改时,可以通过$emit派发自定义事件,父组件接收到后,由父组件进行修改

8、computed和watch的区别
computed属性
计算属性,依赖于其他属性值,并且computed的值有缓存,只有他依赖的属性值发生变化;并且computed的值有缓存,只有它依赖的属性发生改变时,下一次获取computed的值时才会重新计算computed的值。计算数值时,可以利用computed的缓存特性
watch属性
更多的是观察的作用,监听的数据发生变化时执行回调进行后续操作。执行异步或者开销较大的操作时也可以使用

9、数据双向绑定原理
 

VUE高频面试题

vue通过数据劫持和发布订阅模式相结合的方式来进行数据的双向绑定,
监听器observer利用object.defineProperty来劫持各个属性的setter和getter,当数据发生变化时,就会触发setter,监听器就可以监听到变化。
解析器compile先进行模板的编译,将模板中的变量转换为数据;然后开始初始化渲染页面,同时添加监听数据的相关订阅者,指定更新的回调函数
订阅者watcher订阅监听器中的属性变化,当属性变化时订阅者便调用解析器中绑定的更新函数来进行数据的更新,所以订阅者相当于解析器和监听器之间沟通的桥梁

最后一个是dep订阅器,相当于一个订阅者的容器,用来集中管理订阅者

10、说说对v-router的理解
vue-router是vue中的前端路由管理器,那么什么是路由呢,路由就是负责页面的跳转,在url中输入访问地址后
,浏览器去请求这个url地址所对应的资源。有三种路由模式:hash,history,abstract。
hash使用URL hash值来作路由,URL上有#,这是最安全的模式,兼容所有的浏览器和服务器
history依赖HTML5 history API
abstract适用于所有的js环境

 

上一篇:vue3.x computed语法


下一篇:vuex使用