1、谈谈你对VUE的理解
vue就是一个用于创建用户界面的渐进式的JavaScript框架
vue有三个好处:
1、采用了组件化的模式,把HTML封装和组件好,这样可以重复使用代码,提高代码利用率。
2、声明式编码,不用再手写DOM,直接在页面上渲染,提高开发效率。
3、采用了虚拟DOM,比较前后DOM的更新变化,尽可能复用DOM,减少内存消耗,优化性能。
2、谈谈你对MVVM的理解
MVVM是Model-View-ViewModel的简写,Model就是模型,对应Vue中的Data中的属性,View就是视图,对应template模板,ViewModel就是Vue实例,它有两个方向,一个是把Model中的数据挂载到ViewModel上,自动渲染到View中。一个View数据变化时,Model也会跟着更新,这样就实现了数据双向绑定的过程。
MVVM的好处就是:
1、实现数据双向绑定,减少View和Model的耦合性
2、不用再手写DOM,让程序员更加关注数据的变化
3、数据频繁更新时,复用DOM,优化性能。
3、MVC和MVVM的区别
MVC是Model-View-Controller的简写,Model对后端数据,View对应视图,Controller对应控制器,MVC的工作原理就是:用户在视图页面发出请求时,就会通知路由,路由就找到对应的控制器,控制器就会把后端的数据传给前端,响应用户。
MVC和MVVM中的M和V是一样的,只不过把C中的页面逻辑视图抽离出来给了前端,变成VM,这样实现了数据双向绑定,所以说,MVVM是MVC的改进版,
最大的区别就是:
1、MVC是单向的,MVVM是双向的。
2、MVVM解决了MVC中产生的大量的DOM操作,提高了开发效率
3、在数据频繁更新的时候,采用了虚拟DOM,减少过度渲染,提高性能。
4、VUE的响应式原理
响应式:当渲染视图时使用到了一个数据,当这个数据变化时,视图就会响应是否更新,这就叫做响应式。
VUE的响应式原理的核心是Obejct.defineProperty
简单来说,Vue会通过Observe对data中的所有属性进行检测,然后通过Obejct.defineProperty对data的所有属性进行一个数据劫持,当获取数据时,对数据进行一个依赖的收集,当更新数据时,就会通知对应的依赖进行视图更新。
如果数据类型是对象的话,就会调用this,walk()这个方法,内部就会通过DefineReactive对数据循环,定义响应式,核心就是通过Obejct.defineProperty对数据进行劫持并监听。
如果数据类型是数组的话,就要用到函数劫持的方法,先定义好原型方法,改变数组的方法有7种,分别是pop、push、shift、unshift、splice、sort、reverse。然后数组通过原型链调用我们自己定义的方法,实现数组更新,通知更新视图。如果数组里面有对象的话,就用Obeserve进行检测。
Vue3.0就不用Obejct.defineProperty来实现响应式,而是通过Proxy来实现,直接检测数组,不用再用到函数劫持。
5、VUE数据双向绑定原理
vue通过数据劫持结合订阅者-发布者实现的数据双向绑定原理。
简单来说,就是vue会利用Obsever对数据进行检测,然后利用Object.defineProerty对data中的所有属性进行一个重新定义,对数据的获取和设置进行数据劫持,获取数据时,对数据进行一个依赖收集,就叫做订阅者(Watcher),数据更新后,就会通知订阅者更新视图。最后通过Complie解析器,来解析模板命令,把属性转为数据,绑定更新函数,添加到绑定数据的订阅者,一旦数据变化,就通知订阅者,更新视图。
简单来说就三个步骤:
1、实现一个监听器(Obsever),对数据进行劫持和监听,数据变化时,通知订阅者
2、实现一个订阅者(Watcher),收集通知并调用对应的函数,进行视图更新
3、实现一个解析器(Complie),解析命令,把属性转为数据,并初始化视图模板
6、computed和watch的区别
computed是计算属性,watch是监听属性
相同点:它们都是用来监听数据变化的
它们的不同点:
1、computed有缓存功能,只有它依赖的属性值发生改变的时候,它才会重新计算。而watch没有缓存功能,只要它监听的数据有变化,它就是监听执行。
2、computed不能监听异步操作,它依赖的属性值有异步操作的话,它是监听不出来的,也就不会计算。而watch可以监听异步操作。
应用场景:computed适合依赖多个属性值进行计算,watch适合监听多次变化的属性值和异步操作,例如监听计时器和路由。
7、vue的生命周期函数
一个vue实例从开始创建到销毁的过程,就叫做vue的生命周期。
vue的生命周期的关键阶段有8个vue生命周期函数,可以分为3类:
第一类是创建期间的生命周期函数:
1、beforeCreate:这个时期,已经初始化好了vue实例,但是数据和方法还没有被初始化,还没有够被调用。
2、created:这个时期,vue中的数据和方法已经初始化好了,这是第一个可以调用数据和方法的函数
3、BeforeMoute:这个时期,vue中的数据已经预编译好了,但是还没有渲染到模板中。
4、Mouted:这个时期,数据已经渲染到了模板中,可以获取页面中的数据,这里Vue实例已经创建完成。
第二类是运行期间的生命周期函数:
1、beforeUpdate:这个时期,Vue中的数据改变时,视图还没有更新。
2、Updated:这个时期,视图已经更新完毕。
第三类是销毁期间的生命周期函数:
1、beforeDestroy:这是最后一个可以调用Vue中的数据和方法
2、Destroyed:Vue组件销毁,生命周期结束。
8、nextTick
vue的数据更新是异步的,所以数据更新的时候,视图不会立即更新,而是会把更新的数据放到异步队列中,等到里面所有的数据更新之后,才会进行视图更新。视图更新之后,就会调用nextTick方法获取DOM内容,删除之前的异步队列,等待下一次的数据更新。
nextTick的使用场景:当你数据更新之后想立即获取DOM数据来进行操作的时候,你就可以使用this.$nextTick。
nextTick的原理:它会把回调函数放到一个callback队列中,判断pending是否为false,pending表示当前是否有异步任务正在执行,如果pending为false时,就调用timerFunc函数,执行callbacks队列中的函数,当timerFunc函数还没有结束时,重复调用nextTick只会触发一次执行。等到执行完毕后,就会清空之前的异步队列,等待下一次数据更新。
9、vue-if和vue-show的区别
相同点:都是显示隐藏元素的
不同点:
1、渲染问题:vue-if如果为false,它是不会渲染到页面上的。而vue-show不管是true或者fase,都会渲染到页面上。
2、显示隐藏问题:vue-if如果为true,它会添加元素节点,如果为false,它会删除节点。而vue-show只是display样式的切换。
3、性能问题:vue-if在显示隐藏上先比较耗性能,而vue-show在初始化渲染的时候比较耗性能,因为它都要渲染。
应用场景:vue-if适合数据不变的情况下使用,vue-show适合数据多次频繁变换的时候使用。
10、vue-if与vue-for为什么不建议一起使用
因为vue-for比vue-if的优先级要高,所以vue-for先执行,但vue-for会浪费性能,所以不建议vue-if与vue-for一起使用。
如果要使用的话,就在外层添加template,先进行vue-if先判断,再执行vue-for
如果vue-for在外面,那就用computed监听,先过滤掉那些不用的,再执行vue-for
11、v-model实现双向数据绑定的原理
- v-model其实就是v-bind绑定属性和v-on绑定函数的语法糖来实现双向数据绑定。
- 当输入数据时,就调用v-bind绑定属性来渲染到页面,当数据改变时,就调用函数更新属性值,达到双向数据绑定。
12、data为什么是一个函数而不是对象
- 因为一个组件可以有多个实例,如果data是一个对象的话,多个实例就会共用一个data对象,造成数据污染,所以data必须是一个函数,初始化的时候,它会新建一个函数,保证数据不被污染。
13、vue常用的组件间通信方式有哪些?
vue组件通信主要有3种,分别是父子传值,兄弟传值,非关系传值。
1、父传子,父组件通过v-bind属性传值子组件,子组件通过props属性来取值。
2、子传父,子组件通过$emit方法来传值给父组件,父组件通过自定义事件绑定函数来取值。
3、兄弟传值,就用EventBus,,创建一个模板JS来作为中间对象,在created生命周期函数中利用v-on定义事件来获取数据,在methods方法中用$emit来修改数据,实现兄弟传值。
4、非关系传值,就要用到vuex全局状态管理来传值,上面三种都是小范围的组件之间的传值,非关系传值如果再用以上三种耦合性就很高,而且后期维持起来很麻烦,所以用到全局状态(数据)来进行传值,方便简单。
14、vuex
vuex就是实现全局组件状态管理的一种机制,作用就是用来实现组件之间的数据共享。
vuex有5个重要的属性:
1、state:用来存放公共数据的地方
2、getter:用来修饰state数据
3、mutation:唯一可以修改store的值
4、action:用来处理异步
5、module:模块化
vuex的好处:
1、实现了组件之间的数据共享,提高开发效率
2、集中管理全局数据,有利于后期管理。
3、vuex是响应式的,数据变化后视图会跟着更新。
15、谈谈你对组件的理解
组件就是一个自定义标签,页面上的内容需要重复使用的时候就要封装组件,这样尽可能地复用组件,提高代码的利用率。
封装组件步骤:
1、引入组件
2、注册组件
3、使用自定义标签
16、对 SPA 单页面的理解,它的优缺点分别是什么?
SPA就是Single-Page-Application,单页面应用,作用就是一次页面渲染后,跳转页面也不会再渲染了,这样减少渲染损耗,避免重复加载。
优点:用户体验快,页面跳转不用重复加载渲染。
缺点:第一次加载渲染慢,而且不利于SEO搜索引擎优化。
17、<keep-alive></keep-alive>
的作用
keep-alive就是一个缓存组件,它的作用就是避免组件内的数据重新渲染。
优点:组件切换跳转之后回来数据不需要重新渲染,而是保存在内存中,减少渲染加载时间,优化性能。
缺点:二级路由不可以缓存,需要通过路由守卫(before-routerleave),把二级路由保存起来。
18、vue为什么使用key且为唯一值
- 这样有利用于Diff算法能够准确地识别节点,高效地更新虚拟DOM。
19、vue-router路由
- vue-routerj就是路由管理器,主要作用就是管理URL,实现URL与组件之间的对应,通过URL与组件之间的切换,实现SPA单页面应用。
- vue-router的原理:单页面应用SPA的核心思想之一,就是更新视图不需要重新更新页面,而是更新某个容器中的某个内容。对于大多数单页面应用,都推荐使用vue-router。
19、路由的两个模式
一个是hash模式(默认),一个history模式。目的是为了实现前端路由,改变视图时不用向后端发出请求。
Hash模式就是URL中的#号,Hash虽然在URL中,但不在HTTP请求中,所以视图更新的时候对后端没有影响。
History模式利用了ES6新添加的pushState()和replaceState()方法,它们提供了修改历史记录的功能,虽然改变了URL,但不会立即向后端发出请求。
区别:
1、Hash有#号,History没有
2、History怕刷新,刷新就要访问后端,URL地址错了会404。