VUE框架设计核心定位 - MVVM
·
前言
- 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 负责将状态映射到视图
核心机制:双向绑定(通过数据绑定与事件转发实现)
具体职责:
- 监听Model变化更新view;
- 依赖响应式系统:vue2的数据劫持,vue3的代理拦截
- 监听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>包裹 或 计算属性替代)
- Vue 3:v-if 优先级高于 v-for(可用
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回调函数。
- nextTick 利用 JS 的 Event Loop(微任务/宏任务) 机制:先将“需要更新的DOM”放入队列,等待本轮同步代码跑完,再统一执行组件的更新函数(render),完成真实DOM更新(patch),最后执行
-
- 应用:
-
-
- 即可获取元素尺寸(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 引擎 不会在对象失去引用时立即释放。采用标记-清除等算法,在特定时机统一回收。
压力缓解:对监听数据进行处理。比如防抖、差量合并等
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)