Vue⾯试经常会被问到的⾯试题
⼀、对于MVVM的理解
MVVM 是 Model-View-ViewModel 的缩写。
Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。
View 代表视图模型,它负责将数据模型转化成UI 展现出来。View 层不负责处理状态,View 层做的是数据绑定的声明、指令的声明、事件绑定的声明。
ViewModel监听数据的改变和控制视图⾏为、处理⽤户交互,它就是⼀个同步View 和 Model的对象,连接Model和View。
在MVVM架构下,View 和 Model 之间并没有直接的联系,⽽是通过ViewModel进⾏交互,Model 和 View 之间的交互是双向的,因此View 数据的变化会同步到Model中,⽽Model 数据的变化也会⽴即反应到View 上。
ViewModel通过双向数据绑定把View层和Model层连接起来,⽽View和Model之间的同步⼯作完全是⾃动的,⽆需⼈为⼲涉,因此开发者只需要关注业务逻辑,不需要⼿动操作DOM,不需要关注数据状态的同步问题,复杂的数据状态维护完全由MVVM来统⼀管理
MVVM优缺点
优点:
1)分离视图(View)和模型(Model),降低代码耦合,提⾼视图或者逻辑的重⽤性
2)提⾼可测试性: ViewModel的存在可以帮助开发者更好地编写测试代码
3)⾃动更新dom: 利⽤双向绑定,数据更新后视图⾃动更新,让开发者从繁琐的dom操作中解放
缺点:
1)Bug很难被调试:数据绑定使得⼀个位置的Bug被快速传递到别的位置,要定位原始出问题的地⽅就变得不那么容易了。另外,数据绑定的声明是指令式地写在View的模版当中的,这些内容是没办法去打断点debug的
2)⼀个⼤的模块中model也会很⼤,虽然使⽤⽅便也并保证了数据的⼀致性,当时长期持有,不释放内存就造成了花费更多的内存
3)对于⼤型的图形应⽤程序,视图状态较多,ViewModel的构建和维护的成本都会⽐较⾼
jquery框架面试题
vue对css的操作可以通过绑定class或者绑定style。
⼆、vue框架与jQuery类库的区别
Vue直接操作视图层,它通过Vue对象将数据和View完全分离开来了。对数据进⾏操作不需要引⽤相应的DOM节点,只需要关注逻辑,完全实现了视图层和逻辑层的解耦;
Jquery的操作是基于DOM节点的操作,jQuery是使⽤选择器($)选取DOM对象,对其进⾏赋值、取值、事件绑定等操作,其实和原⽣的js的区别只在于可以更⽅便的选取和操作DOM对象,⽽数据和界⾯是在⼀起的。它的优势在于良好的封装和兼容,使调⽤简单⽅便。
三、vue的⽣命周期
Vue 实例从创建到销毁的过程,就是⽣命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等⼀系列过程,称之为 Vue 的⽣命周期。
vue的⽣命周期中有多个事件钩⼦,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。它可以总共分为8个阶段:创建前/后, 载⼊前/后,更新前/后,销毁前/销毁后。
第⼀次页⾯加载会触发 beforeCreate, created, beforeMount, mounted 这⼏个钩⼦函数;DOM 渲染在
mounted 中就已经完成了。官⽅实例的异步请求是在mounted⽣命周期中调⽤的,⽽实际上也可以在created⽣命周期中调⽤。
beforeCreate(创建前) :数据观测和初始化事件还未开始
created(创建后):完成数据观测,属性和⽅法的运算,初始化事件,el属性还没有显⽰出来。
beforeMount(挂载前) :在挂载开始之前被调⽤,相关render函数⾸次被调⽤。实例完成以下配置:编译模板,把data⾥⾯的数据和模板⽣成html,但是没有挂载html到页⾯中。mounted(挂载后):挂载到实例之后被调⽤,实例完成以下配置:⽤上⾯编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页⾯中。此过程中进⾏ajax 交互。
beforeUpdate(更新前):在数据更新之前调⽤,发⽣在虚拟DOM重新渲染和打补丁之前。可以在该钩⼦中进⼀步地更改状态,不会触发附加的重渲染过程。
updated(更新后):在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调⽤。调⽤时,组件DOM已经更新,所以可以执⾏依赖于DOM的操作。然⽽在⼤多数情况下,应该避免在此期间更改状态,因为这可能会导致更新⽆限循环。该钩⼦在服务器端渲染期间不被调⽤。
beforeDestroy(销毁前):在实例销毁之前调⽤。实例仍然完全可⽤。
destroyed(销毁后):在实例销毁之后调⽤。调⽤后,所有的事件会被移除,所有的⼦实例也会被销毁。该钩⼦在服务器端渲染期间不被调⽤。
activited:keep-alive专属,组件被激活时调⽤
deactivated:keep-alive专属,组件被激活时调⽤
四、Vue实现数据双向绑定的原理:Object.defineProperty()
vue实现数据双向绑定主要是:采⽤数据劫持结合发布者-订阅者模式的⽅式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。
要想实现mvvm,主要包含两个⽅⾯,视图变化更新数据,数据变化更新视图.
1)view变化更新data:可以通过事件监听实现
2)data变化更新view:通过Object.defineProperty( )对属性设置⼀个set函数,当属性变化时就会触发这个函数,所以我们只需要将⼀些更新的⽅法放在set函数中就可以实现data变化更新view了.
3)具体过程:
⾸先要对数据进⾏劫持监听,所以要设置⼀个Observer,⽤来监听所有的属性,当属性变化时,就通知订阅者Watcher,看是否需要更新。属性可能是多个,所以会有多个订阅者,故需要⼀个消息订阅器Dep来专门收集这些订阅者,并在Observer和订阅者Watcher之间进⾏统⼀的管理。
因为在节点元素上可能存在⼀些指令,所以还需要⼀个指令解析器Compile,对每个节点元素进⾏扫描和解析,将相关指令初始化成⼀个订阅者Watcher,并替换模板数据并绑定相应的函数,这时候当订阅者Watcher接受到相应属性的变化,就会执⾏相对应的更新函数,从⽽更新视图.
总结:
1.实现⼀个Observer,⽤来劫持并监听所有属性,如果有变动的,就通知订阅者。
2.实现⼀个订阅者Watcher,可以收到属性的变化通知并执⾏相应的函数,从⽽更新视图。
3.实现⼀个解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。
详情请读:
五、vue-cli是什么?
Vue.js提供⼀个官⽅命令⾏⼯具,可⽤于快速搭建⼤型单页应⽤(在⼀个完成的应⽤或者站点中,只有⼀个完整的HTML页⾯,这个页⾯有⼀个容器,可以把需要加载的代码(以组件的⽅式)插⼊到该容器中)。
该⼯具提供开箱即⽤的构建⼯具配置,带来现代化的前端开发流程。只需⼏分钟即可创建并启动⼀个带热重载、保存时静态检查以及可⽤于⽣产环境的构建配置的项⽬。
assets⽂件夹是放静态资源;components是放组件;router是定义路由相关的配置;view视图;app.vue是⼀个应⽤主组件;main.js是⼊⼝⽂件等等
六、Vue组件如何通信
props/$emit+v-on: 通过props将数据⾃上⽽下传递,⽽通过$emit和v-on来向上传递信息。
中央事件总线EventBus: 通过EventBus进⾏信息的发布与订阅,实现⾮⽗⼦组件之间的通信
vuex: 是全局数据管理库,可以通过vuex管理全局的数据流
v-model⽅式:直接绑定⽗组件变量,把数据从⼦组件传回⽗组件
七、vuex是什么?
Vuex 类似 Redux 的状态管理器,⽤来管理Vue的所有组件状态。
⼋、vue组件中的data为什么是⼀个函数?
组件是可复⽤的vue实例,⼀个组件被创建好之后,就可能被⽤在各个地⽅,⽽组件不管被复⽤了多少次,组件中的data数据都应该是相互隔离,互不影响的,基于这⼀理念,组件每复⽤⼀次,data数据就应该被复制⼀次,之后,当某⼀处复⽤的地⽅组件内data数据被改变时,其他复⽤地⽅组件的data数据不受影响。
类似于给每个组件实例创建⼀个私有的数据空间,让各个组件实例维护各⾃的数据。⽽单纯的写成对象形式,就使得所有组件实例共⽤了⼀份data,就会造成⼀个变了全都会变的结果。
九、computed和watch有什么区别?
computed:
1、computed是计算属性,也就是计算值
2、computed具有缓存性,computed的值在getter执⾏后是会缓存的,只有在它依赖的属性值改变之后,下⼀次获取computed的值时才会重新调⽤对应的getter来计算
3、computed适⽤于计算⽐较消耗性能的计算场景
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
ssage.split('').reverse().join('')
}
}
** watch**
1、Vue 提供了⼀种更通⽤的⽅式来观察和响应 Vue 实例上的数据变动:侦听属性。
2、⽆缓存性,页⾯重新渲染时值不变化也会执⾏
watch: {
// 如果 `question` 发⽣改变,这个函数就会运⾏
question: function (newQuestion, oldQuestion) {
this.answer = 'Waiting for you to '
this.debouncedGetAnswer()
}
},

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。