成都市成华区建设局官方网站,网站包503错误,微信网页登录入口,用织梦做外文网站✨ 用了这么久的Vue2了你真的 知其然#xff0c;知其所以然么#xff1f; ✨今天博主就为大家带来一篇对Vue核心功能的部分剖析\textcolor{pink}{今天博主就为大家带来一篇对Vue核心功能的部分剖析}今天博主就为大家带来一篇对Vue核心功能的部分剖析 ✨后续文章会用更多小案… ✨ 用了这么久的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 aaObject.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把数据放到对应的位置上去 如果数据变化之后就用数据最新的值再重新放一次)
方案一:命令式操作
document.querySelector(’#app’).innerText data.nameset函数中重新执行一下document.querySelector(’#app’).innerText data.name
方案二:声明式渲染 v-text指令的实现 p v-textname/p核心逻辑通过‘模板编译’找到标记了v-text的元素,然后把对应的数据通过操作domapi放上去 div idappp v-textname/pp/p/app1.通过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 - MM - 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.发布订阅模式 问题 divp v-textname/pp v-textname/pdiv v-textage/div/divname发生变化之后 我需要做的事情是更新俩个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(fnfn())}}使用发布订阅模式优化现存问题 先前的写法 不管是哪个数据发生变化我们都是粗暴的执行一下compile函数即可
现在的写法 我们在compile函数初次执行的时候 完成更新函数的收集 然后在数据变化的时候 通过数据的key找到相对应的更新函数 依次执行 达到精准更新的效果
写在最后 ✨原创不易还希望各位大佬支持一下\textcolor{blue}{原创不易还希望各位大佬支持一下}原创不易还希望各位大佬支持一下 点赞你的认可是我创作的动力\textcolor{green}{点赞你的认可是我创作的动力}点赞你的认可是我创作的动力 ⭐️ 收藏你的青睐是我努力的方向\textcolor{green}{收藏你的青睐是我努力的方向}收藏你的青睐是我努力的方向 ✏️ 评论你的意见是我进步的财富\textcolor{green}{评论你的意见是我进步的财富}评论你的意见是我进步的财富 看完文章啦 验证大家对这篇文章的掌握 大家参与下方的投票呦