vue部分总结

106 阅读7分钟

Vue

1.数据双向绑定原理

通过数据劫持结合发布-订阅模式,通过Object.defineProperty()为各个属性定义get、set方法,在数据发生改变时给订阅者发布消息,触发响应的事件回调。

2.Vue生命周期

从创建、初始化数据、编译模板、挂载DOM、渲染-更新-渲染、卸载等一系列过程,称为Vue实例的生命周期。

Vue2.0

beforeCreate创建前、created创建完成、beforeMount挂载前、mounted挂载完成、beforeUpdate更新前、updated更新后、beforeDestroy销毁前、destroyed销毁后

其他:activated:在keep-alive组件激活时调用 deactivated:在keep-alive组件停用时调用

Vue3.0

onBeforeMount、onMounted、onBeforeUpdate、onUpdated、onBeforeUnmount、onUnmounted

3.组件之间如何传值

(1) Vue父子组件之间传值

子组件通过props来接受数据和通过$emit来触发父组件的自定义事件;

(2) 兄弟组件之间的传值

建一个公共组件bus.js。传递方通过事件触发bus.$emit.接收方通过在mounted(){}生命周期里触发   bus.$on

(3) 可以通过VUEX来跨组件传参

(4) 父孙传值

 $attrs(向下)  $listeners(向上)

(5) 祖先和子孙传值

provide、inject

(6) 获取父组件实例

this.$parent

4. Vuex

原理:Vuex是专门为vue.js应用程序设计的状态管理工具。

构成:

  • state : vuex的基本数据,用来存储变量,存放的数据是响应式的。
  • mutations : 提交更改数据,同步更新状态。
  • actions : 提交mutations,可异步操作
  • getters:是store的计算属性
  • modules:模块,每个模块里面有四个属性。

5. 如何解决VUEX页面刷新数据丢失问题?

原因:因为vuex里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,vuex里面的数据就会被清空。

解决方法:将vuex中的数据直接保存到浏览器缓存中。

另一种方法:使用插件vuex-persistedstate

可以将Vuex store的状态持久化存储到浏览器的localStorage或sessionStorage中,是的用户下次打开页面时能够继续使用之前的应用状态。

6. computed和watch的区别?

computed值有缓存,触发条件是依赖值发生改变;watch无缓存支持异步、监听数据变化。

computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值; watch: 更多的是观察的作用,支持异步,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作;

computed应用场景:需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算; watch应用场景:需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许我们执行异步操作 ( 访问一个 API ),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。

7.vue中数据变了但是视图不更新怎么解决?

解决方法:数组长度变化可以用splice来修改,需要监听某个属性的变化用 $set。

8.vue中data为什么是函数而不是对象?

在vue中组件是可以被复用的,而当data是一个函数的时候,每一个实例的data都是独立的,不会相互影响了。

9.vue中父子组件传值,父组件异步请求,子组件不能实时更新怎么解决?(vue中数据不能实时更新怎么解决?)

原因:因为生命周期只会执行一次,数据是要等到异步请求以后才能拿到,那么子组件的mounted钩子执行的时候,还没有拿到父组件传递过来的数据,但是又必须要打印出来结果,那这样的话,就只能去打印props中的默认值空字符串了,使用打印的结果是一个空字符串。

解决方法:

  1. 使用v-if控制组件渲染的时机

    初始还没拿到后端接口的异步数据的时候,不让组件渲染,等拿到的时候再去渲染组件。使用v-if=“变量”去控制,初始让这个变量为false,这样的话,子组件就不会去渲染,等拿到数据的时候,再让这个变量变成true。

  2. 使用watch监听数据的变化

  3. 使用vuex

10.vue路由跳转方式

  • router-link 标签跳转
  • this.$router.push()
  • this.$router.replace()
  • this.$router.go(n) (0:当前页,-1上一页,+1下一页,n代表整数)

11.vue中 $nextTick 作用于原理?

异步渲染、获取DOM、Promise等。

Vue 在更新 DOM 时是异步执行的,在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新。所以修改完数据,立即在方法中获取DOM,获取的仍然是未修改的DOM$nextTick的作用是:该方法中的代码会在当前渲染完成后执行,就解决了异步渲染获取不到更新后DOM的问题了。
$的原理:nextTick 的原理: $nextTick本质是返回一个Promise

应用场景:

在created()里面想要获取操作Dom,把操作DOM的方法放在nextTick中。在data()中的修改后,页面中无法获取data修改后的数据,使用nextTick中。 在data()中的修改后,页面中无法获取data修改后的数据,使用nextTick时,当data中的数据修改后,可以实时的渲染页面

  • 12. vue中for循环为什么加key?

为了性能优化优化diff算法, 因为vue是虚拟DOM,更新DOM时用diff算法对节点进行一一比对,比如有很多li元素,要在某个位置插入一个li元素,但没有给li上加key,那么在进行运算的时候,就会将所有li元素重新渲染一遍,但是如果有key,那么它就会按照key一一比对li元素,只需要创建新的li元素,插入即可,不需要对其他元素进行修改和重新渲染。 key也不能是li元素的index,因为假设我们给数组前插入一个新元素,它的下标是0,那么和原来的第一个元素重复了,整个数组的key都发生了改变,这样就跟没有key的情况一样了。

13.vue2和vue3的区别?

(1) 双向数据绑定原理不同

  • vue2的双向数据绑定是利用Object.defineProperty()对数据进行劫持,结合发布订阅模式的方式来实现的。

  • vue3中使用Proxy API对数据代理。

(2) API类型不同

  • vue2使用选项类型的api。
  • vue3就需要使用一个新的setup()方法。

(3) 生命周期不同

(4) 父子传参不同

(5) 指令与插槽不同

(4) 是否支持碎片

  • vue2不支持碎片
  • vue3支持碎片,可以拥有多个根节点

14.vue路由中的history和hash的区别

  • 地址栏带不带“#”号

hash:http://localhost:8080/#/ history:http://localhost:8080/

  • 都是利用浏览器的两种特性实现前端路由

    history是利用浏览历史记录栈的API实现 hash是监听location对象hash值变化事件来实现

  • 相同的url

    history会触发添加到浏览器历史记录栈中,hash不会触发, history需要后端配合,如果后端不配合刷新页面会出现404,hash不需要

    hashRouter原理:通过window.onhashchange获取url中hash值

    historyRouter原理:通过history.pushState,使用它做页面跳转不会触发页面刷新,使用window.onpopstate监听浏览器的前进和后退

15.Vue Diff算法

Diff算法是指对比两个树形结构的不同,这种算法最早有应用于文本编辑器的对比修改,而在前端领域中,则用于对比真实DOM树和虚拟DOM树,然后将该树与旧的virtual DOM树进行对比,并将差异更新到真实的DOM树上。这个对比的过程就是一个Diff算法。

具体来说,Vue中Diff算法是指对比两个virtual DOM树的差异,并且尽量找出一种最小的变更方式来完成从旧的virtual DOM到新的 virtual DOM的转换。这种方式非常高效,因为不需要每次对真实 DOM 进行重新渲染,而只需要找出变更的部分,更新到真实 DOM 上即可。

在比较两个 virtual DOM 树的差异时,Vue 的 Diff 算法采用的是递归遍历,先比较节点的类型,如果不同,则不再遍历其子节点,直接判断为需要替换当前节点;否则比较节点的属性和子节点,依照节点的属性、子节点排序等,找到最优的更新方式。

Vue 中的优化策略 在 Vue 的 diff 算法中引入了一些优化策略,以减少不必要的 diff 操作,提高 diff 性能,具体来说,有以下几点:

  • 模板编译时静态节点标记

    Vue 在模板编译时,会对那些不需要变更的静态节点做标记,这样在后续渲染时,就可以省略对这些节点进行 diff 操作,减少 diff 的复杂度,提高性能。

  • 列表遍历的 key 值优化

    在 Vue 中,当对一个列表进行遍历时,我们通常会为每个子元素指定一个 key 值来唯一标识它们,以便于后续的 diff 操作。在这个过程中,Vue 会通过记录 key 值来对比新旧节点是否发生了变化,如果没有变化,则会保留该节点对应的状态,避免不必要的重复渲染。

  • 相同节点的合并优化

    在 diff 算法中,如果新旧节点是相同节点(即两个节点都是相同的标签和属性),并且都不需要更新子节点,则认为这两个节点是相同的,可以直接跳过对该节点的 diff 操作,提高 diff 性能。

    Vue 的 diff 算法是一种高效的前端响应式实现方式,能够快速地对比新旧节点间的差异,并快速更新页面视图,提升了用户体验和程序性能。