Vue学习笔记

本文详细介绍了Vue框架的核心概念,包括MVVM模式、data作为函数的原因、computed和watch的区别,以及双向数据绑定、生命周期钩子、虚拟DOM和v-for中的key使用。此外,还探讨了Diff算法在更新虚拟DOM中的作用。
摘要由CSDN通过智能技术生成

Vue

为什么要用Vue?

  • Vue 是一个MVVM(Model-View-ViewModel)框架,双向数据绑定把view和model层连接起来,通过对数据的操作自动更新DOM的状态,完成对页面视图的渲染,而不是进行繁琐的DOM操作。
  • MVVM模型是在前端页面中,把Model用纯JavaScript对象表示(对应data中的数据),View负责显示(对应DOM模板),ViewModel把Model和View关联起来(对应Vue对象)。

data为什么是函数

  • 在Vue中,组件的data必须被定义为一个函数,这样每个实例可以维护一份被返回对象的独立的拷贝。 如果data是一个对象,则所有的组件实例将共享这个对象,导致一个实例的状态变化可能会影响到所有其他实例。

computed和watch的区别

  • computed:计算属性,当依赖的数据变化时,会计算新的值。计算属性是基于依赖进行缓存的,只要依赖属性还没变,多次访问计算属性会立即返回之前的计算结果。watch属性也可以做到相同的事,但是实现更加复杂。计算属性不支持异步。
  • watch:监听某一个值,当被监听的值发生变化时,执行相关操作,更适合做一些数据变化后的异步操作或者较大开销操作。
  • 所有不被Vue管理的函数(定时器、ajax的回调函数等),最好写成箭头函数,this才能指向vue对象

双向绑定

  • Vue 2.0:数据代理,通过Object.defineProperty()将data中的所有属性转换为 getter/setter。当渲染函数(或计算属性等)被首次执行时,会访问与其相关的数据属性,这时数据属性的 getter收集依赖,使每个数据属性知道被那些组件依赖。
  • 当数据发生变化时,调用数据属性的setter,通知所有依赖于该数据属性的 watcher 对象数据已经改变。watcher 对象收到变化通知后,会触发其回调函数,更新视图。
  • Object.defineProperty(对象,属性,配置项): 为对象添加属性,通过这种方法添加的属性默认不可枚举、不可修改、不可删除(基本配置项:value,enumerable,writable,configurable)
  • get/set为defineProperty的配置项,属性值被读取时,会调用get函数返回属性值,属性值被修改时,set函数会被调用,收到修改的值(然后在函数体中修改被代理属性的值)。
    obj2代理obj.x属性的读写:
let obj = {x:100}
let obj2 = {y:100}
Object.defineProperty(obj2,'x',{
	get(){return obj.x},
	set(value){obj.x = value}
})
  • watcher:每个组件实例都对应一个 watcher 实例,可以订阅并收到每个属性的变动通知,执行指令绑定的相应回调函数,从而更新视图。渲染 watcher :组件渲染时观察该组件所依赖的所有数据;计算属性 watcher:计算属性被访问时响应数据变化;侦听器 watcher:使用组件的 watch 对数据进行侦听时,为每个侦听器创建watcher
  • 发布-订阅模式:消息的发送者不会直接将消息发送给接收者。发布的消息被分类后放入一个共享的消息队列或通道中,订阅者可以订阅这些通道来接收感兴趣的消息。
  • 缺点:当创建一个Vue实例时,Vue将遍历所有DOM对象,并为每个数据属性添加getter 和 setter,但如果在 Vue 实例创建之后,为对象添加或删除一个新的属性,Vue 将无法追踪这个新属性的变化。所以在 Vue 实例创建之后,应该使用Vue.set 和 Vue.delete向响应式对象添加或删除属性。
  • Vue3通过Proxy实现数据双向绑定, Proxy 可以对外界对对象的访问进行过滤和改写,可以拦截对象的任何操作,包括属性的添加和删除。

生命周期

  • Vue提供了许多生命周期钩子,可以在生命周期的不同阶段调用指定函数
  • 生命周期函数中的this指向vm或组件实例对象
  • 生命周期分为8个阶段:创建前/后、挂载前/后、更新前/后、销毁前/后
钩子函数状态用处
beforeCreate实例初始化完成,数据代理未开始
初始化数据监测、数据代理
created实例创建完成,属性已绑定,可以访问数据和方法
解析模板,生成虚拟DOM
beforeMount页面呈现未经编译的DOM结构,但随后会被虚拟DOM覆盖,无法进行对DOM的操作
将虚拟DOM转为真实DOM
mountedvue实例挂载完成,对DOM的操作有效可以进行开启定时器,发送请求等初始化操作
beforeUpdate页面尚未和数据保持同步
根据新数据生成虚拟DOM,与真实DOM比较最终完成页面更新
updated页面已经和数据保持同步
调用vm.$destoy()销毁组件或组件在 v-if 指令的条件下从真变为假
beforeDestory组件销毁之前,可以访问数据和方法,但是数据修改不会触发更新清除定时器,解绑自定义事件等
调用vm.$destoy()销毁组件,解绑全部指令和自定义事件,但是会保留原生事件回调
destroyed组件销毁之后,DOM结构依然存在

虚拟DOM

  • 虚拟DOM是以js 对象形式存在的DOM树结构。当状态变更时,渲染器得到新的虚拟DOM,对比新旧虚拟DOM的差异(Diff算法),只重新渲染变化的部分,减少多次重排和重绘,提高渲染效率。
  • 虚拟DOM对象中有三个属性:
    tagName:元素的标签名
    props:元素包含的属性
    children:元素的子节点

v-for中的key

  • 需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点。主要是为了高效的更新虚拟DOM。key属性不会放入真实DOM。
  • 为什么不能用index作为key:如果在列表中间插入新节点,索引会改变。

Diff算法

  1. 对新旧两棵树进行深度优先遍历,标记每个节点;每遍历到一个节点就把该节点和新的树进行对比
  2. 同层比较:diff 算法只会在同一层级的节点之间进行比较,如果一个节点在旧树中存在,而在新树中不存在,会直接移除该节点及其子节点
  3. 节点比较:如果新旧节点的tagName不同,新节点替换旧节点;如果节点相同,会递归比较子节点;如果节点属性、文本内容发生变化,使用patch对象记录。
  4. 子节点比较:Vue建议对列表元素使用key属性唯一标识,识别相同的列表元素,防止遍历时子节点的顺序发生变化。
  5. 对于子节点列表,采用双端对比算法,从列表两端开始向中间对比元素的key值,如果相同则复用旧节点,如果不相同,尝试对比对边节点元素的key值是否相同,相同则将节点移动到对边。如果都不相同,尝试通过 key 值查找对应节点进行对比。直到新列表或旧列表长度为0,插入新元素或删除旧元素。双端对比算法
/* 
    两端对比分为四种状况:
    1. oldStart <=>  newStart
    2. oldEnd   <=>  newEnd
    3. oldStart <=>  newEnd
    4. oldEnd   <=>  newStart
*/
  • 24
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值