✨ 用了这么久的Vue2了你真的 知其然,知其所以然么?

✨今天博主就为大家带来一篇对Vue核心功能的部分剖析\textcolor{pink}{今天博主就为大家带来一篇对Vue核心功能的部分剖析}今天博主就为大家带来一篇对Vue核心功能的部分剖析

✨后续文章会用更多小案例来帮助大家理解Vue的原理\textcolor{green}{后续文章会用更多小案例来帮助大家理解Vue的原理}后续文章会用更多小案例来帮助大家理解Vue的原理

前言:

  • 相信大家阅读过很多关于Vue2的文章,我也阅读过很多,但是大部分文章介绍的都是如何在项目中进行应用,技术点如果使用,功能如何实现;
  • 今天小编为大家带来这篇Vue2的核心原理剖析就是为大家介绍我们常用的Vue2他是如何实现的核心内容,我们简单代码的背后究竟他做了哪些,让大家能够 知其然,知其所以然

学习目标:

  • 了解Object.defineProperty原理
  • 了解set、get关联使用
  • 了解数据反应到识图的过程
  • 了解视图更换如何影响数据
  • 掌握MVVM

Object.defineProperty

 <script>// 1. 字面量定义let data = {name: 'aa'}data.name = 'bb' // 这种情况下我们并不能知道name属性发生了变化// 2. Object.defineProperty  let data1 = {}Object.defineProperty(data1, 'name', {// 当我们访问data1的name属性的时候自动调用的方法// 并且get函数的返回值就是你拿到的值get() {console.log('你访问了data1的name属性')return 'aa'},// 当我们设置修改name属性的时候自动调用的函数// 并且属性最新的值会被当成实参传入进来set(newValue) {console.log('你修改了data1的name属性最新的值为', newValue)// 这个位置 只要你修改了name属性就会得到执行// 所以如果你想要在name变化的时候 完成一些自己的事情// 都可以放到这里来执行// 1. ajax()// 2. 操作一块dom区域}})// 以上是js中对象定义的另外一种方案,可以在访问属性和设置属性的时候自动调用对应的函数// 访问属性:data.name  data['name']  // 设置属性:data.name = 'bb'  data['name'] = 'bb'</script>
 响应式的核心API

get、set

 <script>// let data = {//   name: 'aa'// }let data = {}let _name = 'aa'Object.defineProperty(data, 'name', {get() {console.log('你访问了data1的name属性')return _name},set(newValue) {console.log('你修改了data1的name属性最新的值为', newValue)_name = newValue}})// 问题产生的原因:get中直接返回了一个固定的值,并且set函数中新值拿到了但是没有做任何事情// 解决方案:通过声明一个中间变量,让get函数中return出去这个变量// 并且在set函数中把最新的值设置到这个中间变量身上,起到一个set和get操作的一个// 数据的效果</script>

数据反应到视图

数据的变化可以引起视图的变化(通过操作dom把数据放到对应的位置上去 如果数据变化之后就用数据最新的值再重新放一次)

方案一:命令式操作

  1. document.querySelector(’#app’).innerText = data.name
  2. set函数中重新执行一下document.querySelector(’#app’).innerText = data.name

方案二:声明式渲染
v-text指令的实现

 <p v-text="name"></p>

核心逻辑:通过‘模板编译’找到标记了v-text的元素,然后把对应的数据通过操作domapi放上去

 <div id="app"><p v-text="name"></p><p></p></app>

1.通过app根元素找到所有的子节点 (元素节点,文本节点…) -> dom.nodeChilds
2.通过节点类型筛选出元素节点 (p) -> nodeType 1元素节点 3文本节点
3.通过v-text找到需要设置的具体的节点 <p v-text></p>
4.找到绑定了v-text标记的元素 拿到它身上所有的属性 id class v-text=“name”
5.通过v-text=“name” 拿到指令类型 ‘v-text’ 拿到需要绑定的数据的属性名 ‘name’
6.判断当前是v-text指令 然后通过操作domapi 把name属性对应的值放上去 node.innerText = data[name]
以上整个过程可以称作‘模板编译’

视图的变化反映到数据

input元素 v-model双向绑定
M -> V
V -> M

M -> V

1.通过app根元素找到所有的子节点 (元素节点,文本节点…) -> dom.nodeChilds
2.通过节点类型筛选出元素节点 (p) -> nodeType 1元素节点 3文本节点
3.通过v-text找到需要设置的具体的节点 <p v-text></p>
4.找到绑定了v-text标记的元素 拿到它身上所有的属性 id class v-text=“name”
5.通过v-model=“name” 拿到指令类型 ‘v-model’ 拿到需要绑定的数据的属性名 ‘name’
6.判断当前是v-model指令 然后通过操作domapi 把name属性对应的值放上去 node.value = data[name]
v-model和v-text除了指令类型不一致,使用的dom api不一致 其它的步骤是完全一致的

V -> M

本质:事件监听在回调函数中拿到input中输入的最新的值然后赋值给绑定的属性

 node.addEventListener('input',(e)=>{data[name] = e.target.value})

以上总结:
1.数据的响应式
2.数据变化影响视图
3.视图变化影响数据
4.指令是如何实现的(常规实现逻辑)

优化工作:
1.通用的数据响应式处理

   data(){return {name:'cp',age:28}}
基于现成的数据,然后都处理成响应式
 Object.keys(data) // 由所有的对象的key组成的数组Object.keys(data).forEach(key=>{// key 属性名// data[key]  属性值// data 原对象// 将所有的key都转成get和set的形式defineReactive(data,key,data[key])})function defineReactive(data,key,value){Oject.defineProperty(data, key, {get(){return value},set(newValue){value = newValue}})}

2.发布订阅模式
问题:

  <div><p v-text="name"></p><p v-text="name"></p><div  v-text="age"></div></div>

name发生变化之后 我需要做的事情是更新俩个p标签,而现在不管你更新了哪个数据,所有的标签都会被重新
操作赋值,无法做到精准更新

解决问题的思路:
1.数据发生变化之后最关键的代码是什么?

 node.innerText = data[name]

2.设计一个存储结构
每一个响应式数据可能被多个标签绑定 是一个‘一对多’的关系

 {name: [()=>{ node(p1).innerText = data[name]},()=>{ node(p2).innerText = data[name]}...]}

发布订阅(自定义事件) 解决的问题就是 ‘1对多’的问题
实现简单的发布订阅模式:
浏览器的事件模型
dom.addEventLister(‘click’,()=>{})
只要调用click事件,所有绑定的回调函数都会执行 显然是一个1对多的关系

  const Dep = {map:{},collect(eventName,fn){// 如果从来没有收集过当前事件就先初始化成数组if(!this.map[eventName]){this.map[eventName] = []}// 已经初始化好了就直接往里面push添加this.map[eventName].push(fn)},trigger(eventName){this.map[eventName].forEach(fn=>fn())}}

使用发布订阅模式优化现存问题
先前的写法 不管是哪个数据发生变化我们都是粗暴的执行一下compile函数即可

现在的写法 我们在compile函数初次执行的时候 完成更新函数的收集 然后在数据变化的时候
通过数据的key找到相对应的更新函数 依次执行 达到精准更新的效果

写在最后

✨原创不易,还希望各位大佬支持一下\textcolor{blue}{原创不易,还希望各位大佬支持一下}原创不易,还希望各位大佬支持一下

Vue2的核心原理剖析相关推荐

  1. Redux-Saga: 核心原理剖析

    剖析Saga底层原理: 手写Saga核心 Saga简介: (来自Saga文档介绍)redux-saga 是一个用于管理应用程序 Side Effect(副作用,例如异步获取数据,访问浏览器缓存等)的 ...

  2. 大型网站技术架构核心原理剖析,文末附知识图谱下载

    什么是软件架构 维基百科定义:软件架构是指有关软件整体结构与组件的抽象描述,用于指导大型软件系统各个方面的设计. 软件架构5大要素: 性能 可用性 伸缩性 扩展性 安全性 可以通过考察这5大要素来衡量 ...

  3. lua游戏脚本实例源码_Lua与其他宿主语言交互原理剖析

    Lua与其他宿主语言交互原理剖析 题外话:今天周末,刚好在家有时间就把我这次项目组内部分享的文章贴出来,分享给大家,同时也方便以后自己翻阅. 一. Lua简介 目标:Lua语言本身是用C语言来编写开发 ...

  4. Elasticsearch分布式一致性原理剖析(一)-节点篇

    2019独角兽企业重金招聘Python工程师标准>>> 摘要: ES目前是最流行的开源分布式搜索引擎系统,其使用Lucene作为单机存储引擎并提供强大的搜索查询能力.学习其搜索原理, ...

  5. 统计学习方法|支持向量机(SVM)原理剖析及实现

    欢迎直接到我的博客查看最近文章:www.pkudodo.com.更新会比较快,评论回复我也能比较快看见,排版也会更好一点. 原始blog链接: http://www.pkudodo.com/2018/ ...

  6. 统计学习方法|朴素贝叶斯原理剖析及实现

    欢迎直接到我的博客查看最近文章:www.pkudodo.com.更新会比较快,评论回复我也能比较快看见,排版也会更好一点. 原始blog链接: http://www.pkudodo.com/2018/ ...

  7. 每日一博 - CAS(Compare-And-Swap)原理剖析

    文章目录 What's CAS & sun.misc.Unsafe CAS & sun.misc.Unsafe 以AtomicInteger为例底层原理剖析 CAS缺点 ABA 问题 ...

  8. 开源 serverless 产品原理剖析 - Kubeless

    背景 Serverless 架构的出现让开发者不用过多地考虑传统的服务器采购.硬件运维.网络拓扑.资源扩容等问题,可以将更多的精力放在业务的拓展和创新上. 随着 serverless 概念的深入人心, ...

  9. 大型网站技术架构:核心原理与案例分析 mobi_阿里面试官:你会高并发技术吗?...

    前言 据有关数据统计,无论是游戏行业还是互联网行业,无论是软件开发公司还是大型网站,都对高并发技术人才有着巨大的需求.因此,无论为了是面试还是为了工作,学习高并发技术刻不容缓. 当然,高并发相关岗位的 ...

最新文章

  1. 2022-2028年中国光刻机行业深度调研及投资前景预测报告
  2. 不甘心只做输入工具,搜狗输入法上线AI助手,提供智能服务
  3. Python学习札记(二) python3.5安装 + (假装是)第一个Python程序
  4. g++编译时的常用选项说明
  5. java wait 参数_Java Object wait()方法
  6. qwebkit 网页无法加载图片_网页图片无法显示了?这样就能解决
  7. java 通用查询_java 通用查询
  8. TensorFlow函数使用总结
  9. springmvc mybatis 整合 框架源码 bootstrap html5 mysql oracle spring
  10. 服务器系统装驱动精灵,云服务器安装驱动精灵
  11. Python学习笔记—— 面向对象5.异常
  12. 漫谈数据仓库中的元数据管理
  13. —— GPS测量原理及应用复习-1 ——
  14. 谷歌浏览器扩展程序XDM_设计师的谷歌Chrome浏览器拓展程序推荐!Design Service Center...
  15. msvc2017配置qt5.12.8 x86和x64库版本切换
  16. 字典、集合、控制语句
  17. -Dmaven.multiModuleProjectDirectory system propert
  18. “消失”的Android技术博主们现在如何,framework框架
  19. Facebook、微软、腾讯、DiDi message等全球科技公司都在抢先布局元宇宙
  20. iOSsqlite3的线程安全BUG IN CLIENT OF sqlite3.dylib:illegal multi-threaded access to database connection

热门文章

  1. 台湾印象之八:海角七号
  2. Ubuntu 18.04 LTS环境下 MNN 的编译与使用
  3. wpfdiagram 学习 教学_李倩、吴欣歆:新高考背景下高中语文教学的三个转变
  4. pyecharts运行了但是没有图_新版pyecharts,Python可视化so easy and powerful !
  5. java跟python对比_【多年的Java程序员总结Java与Python的对比 】
  6. 主叫号码未显示怎么设置_微信未授权抖音,应该怎么设置?
  7. spark入门_入门必读 | Spark 论文导读
  8. axios发送自定义请求头的跨域解决
  9. echarts_部分图表配置_图表click事件
  10. hdu 5273 Dylans loves sequence 逆序数 区间dp