Vue2双向数据绑定的原理

编程入门 行业动态 更新时间:2024-10-10 15:25:58

Vue2双向数据<a href=https://www.elefans.com/category/jswz/34/1769902.html style=绑定的原理"/>

Vue2双向数据绑定的原理

Vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调

Vue双向数据绑定主要有以下几个步骤:
模板解析 事件添加 数据劫持 双向绑定

模板解析

文本解析编译

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vue双向数据绑定的原理</title><script src="vue01.js"></script>
</head><body><div id="app">{{str}}<h1>{{str}}</h1></div></body>
<script>// 创建一个Vue实例new Vue({el: "#app",data: {str: '前端小白学习中!'}});
</script></html><!-- 模板解析 事件添加  数据劫持 双向绑定 -->
<!-- 当我们没有写Vue的时候,浏览器是不能帮助我们解析{{}} 里面的文字的 
目的: 让str 正常输出文字--><!-- 在data里面定义一些自己的文本数据,进行挂载以{{}}形式进行展示 -->
// 为了让str正常显示,我们要创建Vue这个类
class Vue {// options 选择 在构造函数中传入参数 这个参数就是创建的Vue 传递过来的对象 ,所以我们通过el可以获取div这个DOMconstructor(options) {console.log(options.el)this.$el = document.querySelector(options.el)this.$data = options.data  //new Vue data 里面的数据console.log('Html页面创建的Vue实例里面的data数据', this.$el)// 第一步:成功获取模板// 第二步:解析编译模板——【我们需要使用到一个方法】并且把DOM传进去thispile(this.$el)}// 将我们获取的DOM 元素传递进去,看一下里面的节点compile (node) {node.childNodes.forEach((item, index) => {// 怎么获取文本节点:通过nodeType  案例中节点为3的是文本节点 1元素节点console.log(item.nodeType)  // 这里输出的是子节点,以及对应的下标// 第三步:我们获取文本节点的目的是将它替换成为data中的数据// 使用===进行判断if (item.nodeType === 1) {// 这里考虑到标签没有内容的情况获取单标签的情况if (item.childNodes.length > 0) {thispile(item)}}if (item.nodeType === 3) {// 是文本节点 使用正则来匹配这个格式let reg = /\{\{(.*?)\}\}/g// 获取节点的文本内容let text = item.textContent  //{{str}}item.textContent = text.replace(reg, (match, vmKey) => {// vnKey 这里我们获取到了一个str,通过str 我们可以获取这边的值// 因为对象作为参数已经进行了传递了// 对 {{}}里面可能存在的空格进行处理 vmKey=vmKey.trim()console.log("reg:", reg, "match:", match, "vmKey:", vmKey,)return this.$data[vmKey]// 按照正则的格式找到{{}}里面的文本,替换成为data里面的数据,也就是data中的字符串// 再把返回的值赋值给item的textContent,就是item文本节点里的内容已经发生改变了// 我们发现返回之后只有第一个节点进行了替换,因为h1是元素节点,这里只判断文本节点// 在上面的第21行进行递归调用 之后就获取数据成功了})}})}
}// 问题: Vue 创建类加构造函数的意义
// 当 new 一个对象的时候会自动调用这个对象的构造函数
// compile ——是什么??
// compile——【编译】是我们自己定义的一个方法 用来将我们获取的模板进行解析
// 问题3: forEach 的使用 里面的两个参数都是什么?
// 我们上面将node里面的节点进行了遍历,item 是node里面的每一个节点 index 是节点里面对应的下标// <h1></h1> 是元素节点 我们是不需要动的
// 我们需要获取的是文本节点
// 怎么获取文本节点:通过nodeType// 获取文本节点之后进行匹配 使用到了正则表达式 【对于个别关键字不是很了解】转义字符的作用

事件绑定

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>02Vues双向数据绑定的原理——事件绑定</title><script src="./vue02.js"></script>
</head><body><div id="app">{{str}}<h1>{{str}}</h1><button @click="cli">按钮</button></div></body>
<script>// 创建一个Vue实例new Vue({el: "#app",data: {str: '前端小白学习中_双向数据绑定的原理——事件绑定'},// 在methods进行方法的调用methods: {cli () {console.log('方法调用了')}}});
</script></html><!-- 事件绑定:我们使用了点击事件之后需要对数据进行处理 之后才可以实现点击的功能
2. 我们的点击事件是写在元素标签的里面2.1 我们需要找到元素节点 根据之前的判断元素类型为1就是元素节点2.2 找到所有的元素节点之后对节点进行判断,看一下里面有没有包含点击事件3.拿到方法名称之后通过名称拿到里面的整个方法,当我们点击的时候再让它进行执行就可以了
-->
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>02Vues双向数据绑定的原理——事件绑定</title><script src="./vue02.js"></script>
</head><body><div id="app">{{str}}<h1>{{str}}</h1><button @click="cli">按钮</button></div></body>
<script>// 创建一个Vue实例new Vue({el: "#app",data: {str: '前端小白学习中_双向数据绑定的原理——事件绑定'},// 在methods进行方法的调用methods: {cli () {console.log('方法调用了')}}});
</script></html><!-- 事件绑定:我们使用了点击事件之后需要对数据进行处理 之后才可以实现点击的功能
2. 我们的点击事件是写在元素标签的里面2.1 我们需要找到元素节点 根据之前的判断元素类型为1就是元素节点2.2 找到所有的元素节点之后对节点进行判断,看一下里面有没有包含点击事件3.拿到方法名称之后通过名称拿到里面的整个方法,当我们点击的时候再让它进行执行就可以了
-->

数据劫持

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>03Vue双向数据绑定的原理——数据劫持</title><script src="./vue03.js"></script>
</head><body><div><!--  
核心:对数据进行拦截
获取设置属性的时候对属性进行拦截,再另外执行操作
-->
</body>
<script>let obj = {name: '沐舒',age: 19,// other 是一个子对象 other: {like: '健身'}}// 第一个参数:要操作的对象  第二个参数:哪一个属性 第三个参数:也是一个对象里面的get set 方法Object.defineProperty(obj, 'name', {// 这里defineProperty这个方法已经給name属性劫持掉了,把它控制住了,和原本的name属性没有关系了// 后面再要获取值的时候就要触发get方法了,后面能获取到什么值就取决于get方法里面的return 返回值// 企图获取属性的时候再来执行这个方法get () {return name               //这里返回的是一个空的字符串,因为我们还没有对它进行设置},// 去设置修改属性的时候触发的 set (val) {name = val  // 这里在你设置值的时候,就已经把你输入的值赋值给name}})
</script></html><!--这里属于编译解析——最后它对视图进行更新这里的重点是:definedProperty 是Vue2里面实现数据劫持的方法
get: 不是用来获取属性值的,而是在企图获取属性值的时候要触发的方法
set: 设置修改属性的时候触发deg: 在控制台输入obj.name='jack'  触发了修改设置属性的这个行为,触发行为就会执行set
obj.name '沐舒'
这里必须要有设置的操作,设置成为什么不重要:重要的是进行触发
set(val){name=val  //set 方法将name设置成为amy 这样get就可以获取name为 沐舒
}获取到的值就是修改之后的值吗??
在set 方法中传入一个参数  ,将参数设置为属性就可以了
set(val){name=val  这个参数可以获取到当我们设置修改这个属性的时候输入的值
}使用 definedProperty 将数据进行劫持之后,这个属性已经和原本设置的值没有关系了
后面需要进行值的获取的时候,
① 明确在get 方法里面给它一个返回值
get () {return '小红'},虽然有set 方法进行设置但是获取的时候触发的还是get,当get方法中有具体的返回值的时候set方法中的值就不会返回②
-->
// Vue03
// 为了让str正常显示,我们要创建Vue这个类
class Vue {constructor(options) {this.$el = document.querySelector(options.el)this.$data = options.data// ① 把传过来的参数的对象也存储一下 {el...data,methods}this.$options = optionsconsole.log(" this.$options", this.$options)thispile(this.$el)}compile (node) {node.childNodes.forEach((item, index) => {if (item.nodeType === 1) {//         2. 我们的点击事件是写在元素标签的里面//  2.1 我们需要找到元素节点 根据之前的判断元素类型为1就是元素节点//  2.2 找到所有的元素节点之后对节点进行判断,看一下里面有没有包含点击事件if (item.hasAttribute("@click")) {// 通过getAttribute这个方法看一下里面的属性值是什么 let vmKey = item.getAttribute("@click")console.log("vmKey", vmKey)  // cli 可以拿到事件绑定的方法名称vmKey = vmKey.trim()          // 对vmKey 进行空格处理// 3.拿到方法名称之后通过名称拿到里面的整个方法,当我们点击的时候再让它进行执行就可以了item.addEventListener('click', () => {console.log(this.$options.methods[vmKey])// 4. 让方法执行 获取了里面的数据 this.$options.methods[vmKey]()})}if (item.childNodes.length > 0) {thispile(item)}}if (item.nodeType === 3) {let reg = /\{\{(.*?)\}\}/glet text = item.textContent  //{{str}}item.textContent = text.replace(reg, (match, vmKey) => {vmKey = vmKey.trim()return this.$data[vmKey]})}})}
}




更多推荐

Vue2双向数据绑定的原理

本文发布于:2023-12-05 03:07:56,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1662876.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:绑定   双向   原理   数据

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!