当前位置: 首页 > Web前端 > vue.js

Vue访谈

时间:2023-03-31 20:33:47 vue.js

1Vue.js双向绑定原理Vue.js2.0采用数据劫持(Proxy模式)结合发布订阅者模式(PubSub模式),通过Object.defineProperty()setters,getters,在数据变化时向订阅者发布消息,并触发相应的监听回调。每个组件实例都有一个对应的watcher程序实例,在组件渲染过程中会将该属性记录为一个依赖,然后当依赖的setter被调用时,会通知watcher重新计算,从而导致其关联的组件被更新。Vue.js3.0,摒弃了Object.defineProperty,使用更快的ES6原生Proxy(访问对象拦截器,也称代理)步骤:递归遍历需要观察的数据对象,包括子属性对象的属性,都添加在里面setter和getter的情况,如果你给这个对象赋值,setter就会被触发,然后你就可以监听到数据的变化了。compile解析模板命令,用数据替换模板中的变量,然后初始化渲染页面视图,并且为每个命令对应的节点绑定update函数,添加订阅者监听数据,一旦数据发生变化,收到通知,并更新视图。Watcher订阅者是Observer和Compile之间的沟通桥梁。主要做的事情是:实例化的时候把自己加入到属性订阅者(dep)中②它必须有一个update()方法③当属性变化被dep.notice()通知时,可以调用自己的update()方法并触发Compile中的binding如果回调,则退出。MVVM作为数据绑定的入口,集成了Observer、Compile和Watcher,通过Observer监听自身模型数据变化,通过Compile解析编译模板指令,最后使用Watcher搭建Observer和Compile之间的沟通桥梁,实现Data更改->查看更新;视图交互变化(输入)->数据模型变化的双向绑定效果。2、Vue.js3.0放弃defineProperty,使用ProxyObject.defineProperty的原因缺陷是监听数组下标的变化,开销很大。所以Vue.js放弃了对下标变化的检测;Object.defineProperty只能劫持对象的属性,Proxy是直接代理对象。Object.defineProperty需要遍历对象的每一个属性。如果属性值也是一个对象,就需要深入遍历。而Proxy是直接代理对象,不需要遍历操作。Object.defineProperty需要手动观察新属性。在vue2中,需要使用vm.$set来保证新添加的属性也是响应式的。Proxy支持13种拦截操作。这是defineProperty没有的Proxy。作为一个新的标准,从长远来看,JS引擎会继续优化Proxy,但是getter和setter基本不会作为优化的对象3.Vue2中data中的objectproperty增加了一个新的property会发生什么?怎么解决?视图不会刷新。这是因为在创建Vue实例时,并没有声明新的属性,所以不会被Vue转化为响应式属性,自然不会触发视图的更新。这时候就需要用到Vue的全局api$set():this.$set(this.obj,'new_property','new_value')4.Computed和WatchComputed计算属性的区别:依赖其他属性值,而computed的值是缓存的,只有它依赖的属性的值发生变化,下一次computed的值只有取一次computed的值才会重新计算。watch监听器:更多的是用于观察,没有缓存,类似于一些数据的监听回调,每当监听到的数据发生变化时,就会执行回调进行后续操作。5.为什么数据是函数而不是对象?JavaScript中的对象是引用类型数据。当多个实例引用同一个对象时,只要一个实例对这个对象进行操作,其他实例中的数据也会发生变化。在Vue中,我们希望更多地复用组件,所以每个组件都需要有自己的数据,这样组件之间才不会相互干扰。所以组件的数据不能写成对象的形式,而要写成函数的形式。数据以函数返回值的形式定义,这样我们每复用一个组件,就会返回一个新的数据,也就是说每个组件都有自己私有的数据空间,各自维护自己的数据。会干扰其他部件的正常运行。6、父子组件加载渲染流程的生命周期顺序:parentbeforeCreate->parentcreated->parentbeforeMount->childbeforeCreate->childcreated->childbeforeMount->childmounted->parentmounted子组件更新流程:parentbeforeUpdate->childbeforeUpdate->childupdated->parentupdated父组件更新过程:parentbeforeUpdate->parentupdateddestroy过程:parentbeforeDestroy->childbeforeDestroy->childdestroyed->parentdestroyed7.serverrenderingdestroyed->parentdestroyed8.Vue生命周期方法有哪些?通常在哪一步发起请求,为什么?beforeCreate:新建一个vue实例后,只有一些默认的生命周期钩子和默认事件,其他的还没有创建。beforeCreate生命周期执行时,data和methods中的数据还没有初始化。data中的数据和methods中create的方法在这个阶段是不能使用的:data和methods都已经初始化了。如果想调用methods中的方法或者操作data中的数据,最早可以在这个阶段操作beforeMount:这个hook执行的时候,模板已经编译到内存中,但是还没有挂载到页面上.这个时候页面还是挂载的:当这个钩子执行的时候,就说明Vue实例已经初始化完成了。.此时,组件离开创建阶段,进入运行阶段。如果我们想通过插件来操作页面上的DOM节点,最早可以在这个阶段执行beforeUpdate:执行这个hook时,页面显示的数据还是旧的,更新data中的数据,并且页面还是没有同步最新的数据Updated:页面显示的数据和data中的数据已经同步,都是最新的beforeDestory:Vue实例从运行阶段进入了销毁阶段。这时,所有的数据和方法、指令、过滤器……都处于活动状态。没有真正销毁销毁:此时所有的数据和方法、指令、过滤器……都处于不可用状态。组件已被销毁。补充回答:创建的实例已经被创建了,因为它是最早触发一些数据和资源请求的。(服务端渲染支持created方法)挂载实例已经挂载,可以进行一些DOM操作。beforeUpdate可以进一步改变这个钩子中的状态,这不会触发额外的重新渲染过程。updated可以执行依赖于DOM的操作。然而,在大多数情况下,您应该避免在此期间更改状态,因为这可能会导致更新无限循环。服务器端渲染期间不会调用此挂钩。destroyed可以进行一些优化操作,清除定时器,解除绑定事件9.mixinmixedin10.filterfiltergloballocal11.slot12.vuexstate:存放公共数据的地方;getter:根据业务场景处理获取返回数据;mutations:修改状态的唯一途径,修改过程是同步的;action:异步处理,通过分发操作触发变异;module:splitthestoremodule减少代码臃肿9.params和query的区别Answer:usage:query使用Path导入,params使用name导入,接收参数类似,分别是this.$route.query.name和this.$route.params.name。url地址显示:query更类似于我们ajax中的get参数,params类似于post。简单来说,前者在浏览器地址栏显示参数,后者不显示。注意:queryrefresh不会丢失刷新query中的dataparams会丢失params中的数据。10.vue-router有哪几种导航钩子?全局导航钩子:router.beforeEach(to,from,next)分离路由独占组件beforeEnter:(to,from,next)在组件中钩住beforeRouteEnter(to,from,next)beforeRouteUpdate(to,from,next)beforeRouteLeave(to,从,下一个)10.vue3