面试官:vue用三年多了?来说说你是如何理解vue的...
先有问题再有答案
如何理解vue框架
vue架构可以分为哪些部分?
如何理解响应式数据系统?
为什么vue不需要开发者手动处理 性能就很好?
作为前端领域的主流框架之一, Vue.js 的核心任务是将声明式的模板转化为真实的 DOM 并渲染到浏览器上。这一过程由三大部分协作完成: 模板编译处理、数据响应系统和渲染流程
。
模板编译处理将开发者编写的声明式模板转换为高效的渲染函数,这些函数会被传递给渲染流程部分。
渲染流程负责根据这些函数生成虚拟 DOM 树,并最终渲染到浏览器中的真实 DOM 上。
数据响应系统则担当着监测数据变化的重任。一旦数据发生变化,它会通知渲染流程进行必要的更新,确保视图与数据保持同步。
这三个部分环环相扣, 共同构成了 Vue.js 的高性能和灵活性。
一图胜千言
具体步骤如下:
响应式数据系统:
一句话说明本质:当数据变化后运行对应的函数。
如何知道数据变化了
通过proxy代理拦截属性赋值setter操作. 所以我们操作的并不是普通的js对象,是经过响应式api处理的添加了setter拦截器的响应式对象。
要运行哪些函数
vue需要知道当前变化的属性,都被哪些函数wacth了。这就需要依赖dep对象在初始化时做依赖收集。 每个响应式对象的属性都对应一个dep实例,dep存储了对应的watcher列表。
什么时间运行函数合适
当找到对应的watcher列表Vue并不会立即运行,而是会将这些wacther加入到队列中 等待这次事件变化结束 所有响应式数据都改动完成,在异步执行这些任务队列。
当执行watcher过程中 又收集到新的响应式数据发生变化 同样将对应的watcher列表加入队列,依次执行 直到任务队列为空,本次批处理结束 触发渲染流程。
<script setup>
import { ref, watch, computed } from 'vue'
const msg = ref('Hello World!')
watch(()=>msg.value,()=>{
console.log('test watch msg', msg)
})
const msgTo = computed(()=>{
return 'me: ' + msg.value;
})
</script>
<template>
<h1>{{ msg }}</h1>
<input v-model="msg" />
<h1>{{msgTo}}</h1>
</template>
为什么vue不需要开发者手动处理 性能就很好?
编译器对模板的静态优化
因为模板支持的语法结构是固定的,编译器可以静态分析模板并在生成的代码中留下标记,使得运行时尽可能地走捷径。
- 静态提升
- 更新类型标记
- 树结构打平
以上三点源自vue官网。
响应式自动追踪
通过响应式api可以自动做依赖收集,获取到哪些组件发生了变化 精准渲染对应的组件。对比react不存在过度渲染的问题。
渲染流程的高效diff
通过渲染流程的diff算法后 计算出需要变更的dom节点被进一步缩小。
总结
通过静态优化大大减少了js的运行时时间。通过响应式自动追踪减少diff范围,通过高效diff算法减少真实操作dom数量。这一切都是vue自动帮我们做的 并不需要开发者手动处理。
其他文章
转载自:https://juejin.cn/post/7377295478281879567