前言
  • MVVM / 双向绑定的含义
  • watch 和 watchEffect的依赖追踪
  • v-if 和 v-for的执行和优先级
  • 为什么数据变了会更新?为什么nextTick才拿到新DOM

一、宏观架构:MVVM

1. 核心含义
  • Model(模型层):负责数据(接口数据、实体业务状态等数据)。在Vue中对应data、ref、reactive
  • Model 需具备变更通知能力(如 Vue 的响应式数据劫持),VM 才能精准捕获变化

  • view(视图层):负责UI展示。在Vue中对应template模版
  • ViewModel(视图模型):连接数据和视图的桥梁

核心定义:声明式视图{{ message }}+ VM 负责将状态映射到视图
核心机制:双向绑定(通过数据绑定与事件转发实现)
具体职责:

  1. 监听Model变化更新view;
    • 依赖响应式系统:vue2的数据劫持,vue3的代理拦截
  2. 监听view交互更新Model:暴露命令(Commands/Methods),接收并处理 View 的用户交互逻辑
    • el-model ,即 :value + @input 的语法糖
2. 为什么需要MVVM
  • 强依赖DOM(jQuery):改数据 -> 手动找DOM -> 赋值、改内容/样式
  • 数据驱动(MVVM_vue): 只改数据 -> vue自动更新DOM
<html>
	<body>
		<button id='but'>点击获取数据</button>
		<script>
			// 请求
			const model = {
				getData: function(){
					return new Promise((resolve) => {
						setTimeout(() => {
							resolve("获取姓名,年龄")
						},5000)
					)}
				}
			}
			// 触发
			const controller = {
				init: function(){
					$('#but').on('click',{
						model.getDate.then(res=>{
							$('#but').html(res)
						})
					})
				}
			}
			// 启动
			controller.init()
		</script>
	</body>
</html>

二、Vue 核心原理:数据如何驱动视图

ViewModel核心实现手段:响应式系统 + 模版编译 + 渲染与DIFF

1. 响应式系统

  • 核心:数据变化时,view 如何知道并通知视图更新?
  • 机制:
    • 数据劫持
    • 依赖收集
    • 派发更新
    • {{}}插值表达式底层编译时,会触发对应响应式数据的读取,从而将数据整体深层地进行自动联动与劫持。未被响应式系统处理的数据,无法实现这种动态监听。

  • API区分
    • ref / reactive
    • watch / watchEffect

2. 模版编译 (template complier)

  • 过程:将语义化模版(v-if、v-for、v-model、{{}} 等)编译成可执行的 render function 过程
  • 产物:render 函数执行后生成 VNode(虚拟 DOM)
  • 优先级:
    • Vue 2:v-for 优先级高于 v-if
    • Vue 3:v-if 优先级高于 v-for(可用 <template> 包裹 或 计算属性替代)

3. 渲染与更新(DIFF 算法)

  • 一次事件循环流程:数据变化-> 触发render -> 生成新的vnode -> 新旧vnode进行diff对比 -> 找出最小变更 -> 更新真实DOM
  • 双向绑定的体现:
    • 数据->视图:响应式系统 + Diff算法
    • 视图->数据:
      • v-model 本质是语法糖。
      • v-model 语法糖本质 —> 绑定value属性+监听input事件
<input :value="msg" @input=""msg = $envet.target.value></input>

3.1. 异步更新 与 NextTick

  • vue特性
    • Vue 的 DOM 更新 是异步的:数据改变但DOM不会立刻改变
    • 数据变化时,vue不是立刻重绘DOM,而是在队列中缓冲同一事件循环中的所有数据变更。(防抖)
  • NextTick 原理
    • 在数据变化后立刻获取 DOM,拿到的是更新前的旧 DOM
    • nextTick 利用 JS 的 Event Loop(微任务/宏任务) 机制:先将“需要更新的DOM”放入队列,等待本轮同步代码跑完,再统一执行组件的更新函数(render),完成真实DOM更新(patch),最后执行nextTick回调函数。
    • 应用:
      • 即可获取元素尺寸(v-if)
      • 自动聚焦(input.focus)
<template>
	<div ref="dataRef">{{message}}</div>
	<button @click="updateData">更新数据</button>
</template>
<script setup>
import {ref, nextTick} from 'vue' // 区别于 this.$nextTick
const message = ref('初始化01')
const dataRef = ref(null)
const updateData = () => {
	message = "updata data"
    console.log(dataRef.value.innerText) // 打印:初始内容
    // 或者 async/await 写法
    nextTick(() => {   // 等待 DOM 更新,返回 promise
		console.log(dataRef.value.innerText) // 打印:更新后内容
	})
}
</script>

三、生命周期与垃圾回收机制

1. VUE 生命周期(Tick 关键节点)

beforeCreate:new Vue() 创建实例
create:data|props|method|computed - 数据操作
beforeMount:vDom - 可进行数据操作
Mount:DOM
beforeUpdate:vdom更新
update:dom更新
beforeDestory:实例被销毁前(获取实例的绑定数据进行全局更新)
destory

2. mark and sweep(V8引擎垃圾回收机制)

GC压力:JS 引擎 不会在对象失去引用时立即释放。采用标记-清除等算法,在特定时机统一回收。
压力缓解:对监听数据进行处理。比如防抖、差量合并等

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐