vue3双向数据绑定原理_demo
<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>proxyVue</title>
<style>
#app {
margin: 100px auto 0 auto;
width: 300px;
}
#btn {
margin: 10px auto;
}
</style>
</head> <body>
<div id="app">
<input type="text" v-model="num" />
<input id="btn" type="button" value="添加到Todolist" v-click="addList" /><br />
<span>您输入的是:</span><span v-bind="num"></span><span>{{num}}</span>
<ul id="list"></ul>
</div>
</body> <script>
class proxyVue {
constructor(options) {
this.$options = options || {};
this.$methods = this._methods = this.$options.methods;
const data = (this._data = this.$options.data);
this.subscribe = {};
this.observe(data);
this.compile(options.el);
}
publish(watcher) {
if (!this.subscribe[watcher.property])
this.subscribe[watcher.property] = [];
this.subscribe[watcher.property].push(watcher);
}
observe(data) {
const that = this;
let handler = {
get(target, property) {
return target[property];
},
set(target, property, value) {
let res = Reflect.set(target, property, value);
that.subscribe[property].map(item => {
item.update();
});
return res;
}
};
this.$data = new Proxy(data, handler);
}
compile(el) {
const nodes = Array.prototype.slice.call(
document.querySelector(el).children
);
let data = this.$data;
nodes.map(node => {
if (node.children.length > 0) this._complie(node);
if (node.hasAttribute("v-bind")) {
let property = node.getAttribute("v-bind");
this.publish(new Watcher(node, "innerHTML", data, property));
}
if (node.hasAttribute("v-model")) {
let property = node.getAttribute("v-model");
this.publish(new Watcher(node, "value", data, property));
node.addEventListener("input", () => {
data[property] = node.value;
});
}
/**
self ...
*/
if (/\{\{(.*?)\}\}/.test(node.innerHTML)) {
let ret = /\{\{(.*?)\}\}/.exec(node.innerHTML)
let property = ret[1];
this.publish(new Watcher(node, "innerHTML", data, property));
}
// self end
if (node.hasAttribute("v-click")) {
let methodName = node.getAttribute("v-click");
let mothod = this.$methods[methodName].bind(data);
node.addEventListener("click", mothod);
}
});
}
}
class Watcher {
constructor(node, attr, data, property) {
this.node = node;
this.attr = attr;
this.data = data;
this.property = property;
}
update() {
this.node[this.attr] = this.data[this.property];
}
} // 渲染todolist列表
const Render = {
// 初始化
init: function (arr) {
const fragment = document.createDocumentFragment();
for (let i = 0; i < arr.length; i++) {
const li = document.createElement("li");
li.textContent = arr[i];
fragment.appendChild(li);
}
list.appendChild(fragment);
},
addList: function (val) {
const li = document.createElement("li");
li.textContent = val;
list.appendChild(li);
}
}; // 实例化一个proxyVue
window.onload = function () {
let vm = new proxyVue({
el: "#app",
data: {
num: 0,
arr: []
},
methods: {
addList() {
this.arr.push(this.num);
// Render.addList(this.num);
}
}
});
};
</script> </html>
vue3双向数据绑定原理_demo的更多相关文章
- vue双向数据绑定原理探究(附demo)
昨天被导师叫去研究了一下vue的双向数据绑定原理...本来以为原理的东西都非常高深,没想到vue的双向绑定真的很好理解啊...自己动手写了一个. 传送门 双向绑定的思想 双向数据绑定的思想就是数据层与 ...
- vue的双向数据绑定原理
原理. vue是采用数据劫持结合发布者-订阅者模式的方式, 通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回 ...
- 深入vue源码,了解vue的双向数据绑定原理
大家都知道vue是一种MVVM开发模式,数据驱动视图的前端框架,并且内部已经实现了双向数据绑定,那么双向数据绑定是怎么实现的呢? 先手动撸一个最最最简单的双向数据绑定 <div> < ...
- Vue双向数据绑定原理深度解析
首先,什么是双向数据绑定?Vue是三大MVVM框架之一,数据绑定简单来说,就是当数据发生变化时,相应的视图会进行更新,当视图更新时,数据也会跟着变化. 在分析其原理和代码的时候,大家首先了解如下几个j ...
- Vue双向数据绑定原理分析(转)
add by zhj: 目前组里使用的是前端技术是jQuery + Bootstrap,后端使用的Django,Flask等,模板是在后端渲染的.前后端没有分离,这种做法有几个缺点 1. 模板一般是由 ...
- 手写MVVM框架 之vue双向数据绑定原理剖析
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 16、前端知识点--Object.defineProperty 的用法+双向数据绑定原理解析
一.Object.defineProperty 的用法 Object.defineProperty 可以用于给对象添加更新属性. <script> // Object.defineProp ...
- Vue双向数据绑定原理解析
基本原理 Vue.采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter和getter,数据变动时发布消息给订阅者,触发相应函数的回调 ...
- Vue的双向数据绑定原理是什么?
vue.js是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调. ...
随机推荐
- Python安装环境配置和多版本共存
Python安装环境配置和多版本共存 1.环境变量配置: (1) 右键点击"计算机",然后点击"属性" (2) 然后点击"高级系统设置" ( ...
- maven下载出错
求解
- Reinforcement Learning 强化学习入门
https://www.zhihu.com/question/277325426 https://github.com/jinglescode/reinforcement-learning-tic-t ...
- vue 接入 vod-js-sdk-v6.js 完成视频上传
东西有点多,耐心看完.按照操作一步一步来,绝对能成功 首先:npm 引入 npm install vod-js-sdk-v6 mian.js 全局引入 //腾讯云点播 import TcVod f ...
- Node.js 应用全链路追踪技术——[全链路信息获取]
全链路追踪技术的两个核心要素分别是 全链路信息获取 和 全链路信息存储展示. Node.js 应用也不例外,这里将分成两篇文章进行介绍:第一篇介绍 Node.js 应用全链路信息获取, 第二篇介绍 N ...
- Docker之Alpine制作jre镜像(瘦身)+自定义镜像上传阿里云
alpine制作jdk镜像 alpine Linux简介 1.Alpine Linux是一个轻型Linux发行版,它不同于通常的Linux发行版,Alpine采用了musl libc 和 BusyBo ...
- openswan源码ubantu下编译、安装、基本环境搭建
openswan的编译过程 文章目录 openswan的编译过程 1. 下载源码: 2. 在虚拟机上解压后编译: 2.1 查看INSTALL文件 2.2 查看文件buildlin.sh文件 3. 查看 ...
- ORACLE 12C Identity Column(身份列) 实现自增长字段
Oracle 12c提供的Identity Column特性简化了自增字段的定义. 声明自增字段通常有3种常见的用法,以下三种方式都支持INSERT语句中省略自增字段的插入,但有些许差别. 1. GE ...
- MySQL-技术专题-MySQL主从架构以及[半同步机制]模式大全
MySQL的主从复制 一般在大规模的项目上,都是使用MySQL的复制功能来创建MySQL的主从集群的. 主要是可以通过为数据库服务器配置一个或多个备库的方式来进行数据同步. 复制的功能不仅有利于构建高 ...
- 使用Eclipse的基本配置
因本人 IntelliJ IDEA 正版授权前些日子已到期,最近开始使用 Eclipse .体验开发了一阵子,觉得除了在界面美观与前端编辑的操作上 Eclipse 与 IDEA 差距还比较大以外,其他 ...