好家伙,狠狠地补一下代码量

 

本篇我们来尝试使用原生js实现vue的响应式

使用原生js,即代表没有v-bind,v-on,也没有v-model,所有语法糖我们都用原生实现

1.给输入框绑个变量

<body>
<input id="input_1"></input>
</body>
<script>
let datavalue = "66666"
const input_1 = document.getElementById("input_1")
input_1.value = datavalue
input_1.addEventListener('input', function(e) {
datavalue = e.target.value
console.log(datavalue)
}) </script>

 

诶,似乎这样就完成了

但我们要让他更像vue

2.加上Dep,Watcher

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input id="input_1"></input>
</body>
<script>
// 模拟 Vue 实例
let data = {
message: 'Hello'
};
const input_1 = document.getElementById("input_1")
input_1.value = data.message
input_1.addEventListener('input', function (e) {
e.target.value = data.message
console.log(datavalue)
}) function defineReactive(obj, key, value) {
let dep = new Dep(); // 依赖容器 Object.defineProperty(obj, key, {
get: function () {
if (Dep.target) {
dep.addDep(Dep.target);
}
return value;
},
set: function (newValue) {
value = newValue;
dep.notify();
}
});
} // 依赖容器
function Dep() {
this.deps = []; this.addDep = function (dep) {
this.deps.push(dep);
}; this.notify = function () {
this.deps.forEach(dep => {
dep.update();
});
};
} Dep.target = null; // Watcher
function Watcher(updateFunc) {
this.update = updateFunc;
} // 初始化响应式数据
defineReactive(data, 'message', data.message); // 模拟 Watcher
let watcher = new Watcher(function () {
console.log('Message updated:', data.message);
input_1.value = data.message
}); // 模拟视图更新
Dep.target = watcher;
data.message; // 触发依赖收集
setTimeout(() => {
data.message = '6666'; //触发更新
}, 1000)
</script> </html>

3.效果图

 

4.代码解释

  1. defineReactive 函数用来定义一个响应式属性,其中通过 Object.defineProperty 给属性添加 getter 和 setter 方法。在 getter 方法中,会判断 Dep.target 是否存在,如果存在则将当前 Watcher 对象添加到依赖容器 Dep 中;在 setter 方法中,更新属性的值,并通过依赖容器 Dep 的 notify 方法通知所有依赖的 Watcher 进行更新。

  2. Dep 函数是一个简单的依赖容器,其中包含了一个 deps 数组用来存储依赖(Watcher),addDep 方法用来添加依赖,notify 方法用来通知所有依赖进行更新。

  3. Watcher 函数用来创建 Watcher 对象,其中包含一个 update 方法,用来在属性发生变化时执行相应的更新操作。

  4. 在初始化响应式数据时,调用 defineReactive 函数定义了一个名为 message 的响应式属性。

  5. 创建了一个 Watcher 对象 watcher,并在其构造函数中定义了一个回调函数,用来在属性变化时输出消息并更新视图。

  6. 将 watcher 赋值给 Dep.target,然后访问 data.message,触发依赖收集,将 watcher 添加到依赖容器 Dep 中。

5.补充

一张响应式原理图

 

第142篇:原生js实现响应式原理的更多相关文章

  1. 原生js实现响应式轮播图,支持电脑端点击切图,手机端滑动切图

    轮播图的实现原理并不难,但是步骤有些繁琐.最近练习了一个轮播图,大部分是跟着网上的教程写的,然后自己做了一点兼容ie8的修改,加了点击切换图片的特效和手机端的滑动特效,让这个轮播图可以在响应式的网站中 ...

  2. Vue.js响应式原理

      写在前面 因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue.js源码,并做了总结与输出. 文章的原地址:answershuto/learnV ...

  3. Glide.js:响应式 & 触摸友好的 jQuery 滑块插件

    Glide.js 是一款响应式和对触摸友好的 jQuery 滑块.基于 CSS3 转换实现,并在低版本浏览器降级处理.Glide.js 简单,重量轻,快速,适用于智能手机,平板电脑和台式机.它支持 s ...

  4. Vue.js学习 Item12 – 内部响应式原理探究

    深入响应式原理 大部分的基础内容我们已经讲到了,现在讲点底层内容.Vue.js 最显著的一个功能是响应系统 —— 模型只是普通对象,修改它则更新视图.这让状态管理非常简单且直观,不过理解它的原理也很重 ...

  5. 利用JS去做响应式布局

    利用JS去做响应式布局 js动态改变布局方式 // 取浏览器可视区高宽 var lw = $(window).width(); var lh = $(window).height();// 页面加载完 ...

  6. vue.js响应式原理解析与实现

    vue.js响应式原理解析与实现 从很久之前就已经接触过了angularjs了,当时就已经了解到,angularjs是通过脏检查来实现数据监测以及页面更新渲染.之后,再接触了vue.js,当时也一度很 ...

  7. 深入解析vue.js响应式原理与实现

    vue.js响应式原理解析与实现.angularjs是通过脏检查来实现数据监测以及页面更新渲染.之后,再接触了vue.js,当时也一度很好奇vue.js是如何监测数据更新并且重新渲染页面.vue.js ...

  8. 详解Vue响应式原理

    摘要: 搞懂Vue响应式原理! 作者:浪里行舟 原文:深入浅出Vue响应式原理 Fundebug经授权转载,版权归原作者所有. 前言 Vue 最独特的特性之一,是其非侵入性的响应式系统.数据模型仅仅是 ...

  9. Vue 源码解读(3)—— 响应式原理

    前言 上一篇文章 Vue 源码解读(2)-- Vue 初始化过程 详细讲解了 Vue 的初始化过程,明白了 new Vue(options) 都做了什么,其中关于 数据响应式 的实现用一句话简单的带过 ...

  10. vue深入响应式原理

    vue深入响应式原理 深入响应式原理 — Vue.jshttps://cn.vuejs.org/v2/guide/reactivity.html 注意:这里说的响应式不是bootsharp那种前端UI ...

随机推荐

  1. LyScriptTools 扩展Script类API手册

    纯脚本类的功能实现都是调用的x64dbg命令,目前由于run_command_exec()命令无法返回参数,故通过中转eax寄存器实现了取值,目前只能取出整数类型的参数. 插件地址:https://g ...

  2. C/C++ 静态编译SQLITE数据库API

    C/C++ 编译并使用Sqlite数据库,实现增删改查. 首先下载数据库: https://sqlite.org/download.html 分别下载:sqlite-amalgamation-3350 ...

  3. BAT大厂面试的100道考题【算法、源码、架构、中间件、设计模式、网络、项目】,过60分的不到10%

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 独生子女生娃,没救了! 考题:https://docs.qq.com/form/page/DT ...

  4. 【奶奶看了都会】2分钟学会制作最近特火的ikun幻术图

    1.效果展示 最近ikun幻术图特别火啊,在网上能找到各种各样的ikun姿势图片,这些图片都是AI绘制的,能和风景完美融合在一起,今天小卷就来教大家怎么做这种图片 先看看图片效果 B站视频链接: 仿佛 ...

  5. JAVA入门学习之GUI编程思想——day01

    GUI编程 什么是GUI???图形化编程 组件 窗口 弹窗 按钮 文本框 图片 事件 ..... GUI的核心:AWT Swing GUI编程的缺陷: ​ 1.界面不美观 ​ 2.需要jre环境 虽然 ...

  6. 常用TS总结

    自己常用的 TS 写法总结,应该会一直更新.可使用 TS在线编译 校验 TS 语法. 基本用法 普通 const num: number = 10 const isStop: boolean = fa ...

  7. NC16681 [NOIP2003]加分二叉树

    题目链接 题目 题目描述 ​ 设一个n个节点的二叉树tree的中序遍历为(l,2,3,-,n),其中数字1,2,3,-,n为节点编号.每个节点都有一个分数(均为正整数),记第j个节点的分数为di,tr ...

  8. 从 KeyStore 中获取 PublicKey 和 PrivateKey

    KeyStore(译:密钥存储库) 代表用于加密密钥和证书的存储设施. KeyStore 管理不同类型的 entry(译:条目).每种类型的 entry 都实现了 KeyStore.Entry 接口. ...

  9. Ubuntu22.04 将EFI启动分区迁移到另一块硬盘

    机器上有两块硬盘, 一块已经安装了Win10, 另一块新装Ubuntu22.04, 在新硬盘上划分分区的时候, 有分出256M给 BOOT EFI, 但是安装的时候没注意, 启动分区不知道怎的跑到 W ...

  10. fold命令

    fold命令 fold命令用于限制文件列宽,其会从指定的文件里读取内容,将超过限定列宽的列加入增列字符后,输出到标准输出设备.若不指定任何文件名称,或是所给予的文件名为-,则fold命令会从标准输入设 ...