Vue面试易问问题总结
1.计算属性和监听的区别
模板内使用计算属性是很方便的,设计的目的只是为了简单运算。在模板中放入太多的逻辑会让模板过重且难以维护。所以,对于任何复杂逻辑,你都应当使用计算属性。
计算属性是有一个缓存的,即便你重新渲染组件,但是计算属性的值没有发生改变时,就不会去执行
这个改变基于计算属性中的被计算值最后是否发生
watch是观察某一个属性的变化,重新计算属性值。computed是通过所依赖的属性的变化重新计算属性值。
大部分情况下watch和computed几乎没有差别。但如果要在数据变化的同时进行异步操作或者是比较大的开销,那么watch为最佳选择。
2.vue兄弟组件之间传值
原理:vue一个新的实例,类似于一个站,连接着两个组件,也就是一个中央事件总线
1,首先创建一个事件总线,例如bus,作为一个通讯的桥梁;
2,在需要传值的组件中,通过emit触发一个自定义事件,并传递参数;
3,在接收数据的组件中,通过on监听自定义事件,并处理传递过来的参数;
总结:
1.兄弟组件之间与父子组件之间的数据交互,两者相比较,兄弟组件之间的通信其实和子组件向父组件传值有些类似,其实他们的通信原理都是相同的,例如子向父传值也是emit和emit和emit和on的形式,只是没有eventBus,但若我们仔细想想,此时父组件其实就充当了bus这个事件总线的角色。
2.这种用一个Vue实例来作为中央事件总线来管理组件通信的方法只适用于通信需求简单一点的项目,对于更复杂的情况,Vue也有提供更复杂的状态管理模式Vuex来进行处理。
3.vue组件封装过程
首先,使用Vue.extend()创建一个组件----》然后,使用Vue.component()方法注册组件
//全局注册 var myCom = Vue.extend({ template: '<div>这是我的组件</div>' }) Vue.component('my-com',myCom) //或者 Vue.component('my-com',{ 'template':'<div>这是我的组件</div>' }) //<script type='text/x-template' id='myCom'>,需加id属性,同时还得加type="text/x-template",加这个是为了告诉浏览器不执行编译里面的代码 <script type="text/x-template" id="myCom1"> <div>这是script标签构建的组件</div> </script> //局部注册 var app = new Vue({ el: '#app', components: { 'my-com': myCom } }) //或者 var app = new Vue({ el: '#app', components: { 'my-com': { template: '<div>这是我的组件</div>' } } }) //或者 var app = new Vue({ el: '#app', components: { 'my-com': { template: '#myCom' } }
4.vue属性改变未渲染的解决方案
1、this.$set(this.array[i],'child',true);使用set属性
2、居然也有使用$set不好使的情况;直接加上强制渲染 this.$forceUpdate();
5.vue中数据的持久化
1.使用 localStorage 存储数据
2.通过vuex-persistedstate插件,实现将数据存储到本地
npm install vuex-persistedstate --save import createPersistedState from 'vuex-persistedstate' export default new Vuex.Store({ state:{}, getters:{}, actions:{}, mutations:{}, modules:{}, plugins: [createPersistedState()] //加上这个就可以了 //里面设置需要缓存的内容 }) //如果你不小心关掉了一个标签,他们可以重新打开并回到之前页面的状态。
3.使用vue-cookie插件
npm install vue-cookie --save import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex) var VueCookie = require('vue-cookie'); export default new Vuex.Store({ state: { token: VueCookie.get('token') }, mutations: { saveToken(state, token) { state.token = token; // 设置存储 VueCookie.set('token', token, { expires: '30s' }); } }, actions: { } }) //在登录页设置存储 import { mapMutations } from 'vuex'; export default { methods: { login() { this.saveToken('123') }, ...mapMutations(['saveToken']) } };
6.虚拟DOM为什么效率高(virtual dom)
对于开发者而言,操作DOM结构是非常昂贵的,它改动后,整个容器中的内容中的内容都要重新渲染一遍,就相当于“推倒重来”,如果项目相对来说比较复杂的话,是非常影响性能的。vdom就可以很好地解决这个问题。
虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存,利用 dom diff 算法避免了没有必要的 dom 操作,从而提高性能。
用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异把 2 所记录的差异应用到步骤 1 所构建的真正的 DOM 树上,视图就更新了。
优点:
1、最终表现在DOM上的修改只是变更的部分,可以保证非常高效的渲染。
2、提升了性能(JavaScript对象比DOM对象性能高),抽象了DOM的具体实现(对DOM进行了一层抽象)
缺点:
首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHTML插入慢。也就是效率很高但是速度会降低一点
7.vue------>$nextTick原理
Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新,是异步执行 DOM 更新
简单来说,Vue 在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新。
应用场景:需要在视图更新之后,基于新的视图进行操作。
在 created 和 mounted 阶段,如果需要操作渲染后的试图,也要使用 nextTick 方法
尽管MVVM框架并不推荐访问DOM,但有时候确实会有这样的需求,尤其是和第三方插件进行配合的时候,免不了要进行DOM操作。而nextTick就提供了一个桥梁,确保我们操作的是更新后的DOM
补充:MutationObserver是HTML5新增的属性,用于监听DOM修改事件,能够监听到节点的属性、文本内容、子节点等的改动,是一个功能强大的利器
8.v-if和v-show的区别
相同点:v-if与v-show都可以动态控制dom元素显示隐藏
不同点:v-if显示隐藏是将dom元素整个添加或删除,而v-show隐藏则是为该元素添加css--display:none,dom元素还在。
1.手段:v-if是通过控制dom节点的存在与否来控制元素的显隐;v-show是通过设置DOM元素的display样式,block为显示,none为隐藏;
2.编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换;
3.编译条件:v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译(编译被缓存?编译被缓存后,然后再切换的时候进行局部卸载);
v-show是在任何条件下(首次条件是否为真)都被编译,然后被缓存,而且DOM元素保留;
4.性能消耗:v-if有更高的切换消耗;v-show有更高的初始渲染消耗;
应用场景:基于以上区别,因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
总结:v-if判断是否加载,可以减轻服务器的压力,在需要时加载,但有更高的切换开销;v-show调整DOM元素的CSS的dispaly属性,可以使客户端操作更加流畅,但有更高的初始渲染开销。如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
display:none;
使用该属性后,HTML元素(对象)的宽度、高度等各种属性值都将“丢失”;释放该元素在文档中所占的物理空间
visibility:hidden;
使用该属性后,HTML元素(对象)仅仅是在视觉上看不见(完全透明),而它所占据的空间位置仍然存在,也即是说它仍具有高度、宽度等属性值
9.vue样式渲染解决屏幕闪动
可以使用 v-cloak 指令设置样式,这些样式会在 Vue 实例编译结束时,从绑定的 HTML 元素上被移除。
当网络较慢,网页还在加载 Vue.js ,而导致 Vue 来不及渲染,这时页面就会显示出 Vue 源代码。我们可以使用 v-cloak 指令来解决这一问题。
<div id="app" v-cloak> {{context}} </div>