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,在数据变动时发布消息给订阅者,触发相应的监听回调. ...
随机推荐
- golang context包
go context标准库 context包在Go1.7版本时加入到标准库中.其设计目标是给Golang提供一个标准接口来给其他任务发送取消信号和传递数据.其具体作用为: 可以通过context发送取 ...
- string类型数据的操作指令
1. 2. 3. 4. 5. 6. 7. 8. 9. 从右到左是索引从-1开始 10. 11. 12. 13. 14. 15.
- java 线程状态 详解
线程被创建后,有一个生命周期,下图是线程的生命周期详解. java api java.lang.Thread.State 这个枚举中给出了六种线程状态,分别是: 线程状态 导致状态发生条件 NEW(新 ...
- 简说yuv
最近弄了一个读取y4m文件转成yuv的流的事情,记录一些yuv相关的细节 为什么会有yuv 因为我们目前的显示器显示的原理都是三原色,几乎所有的视频数据最后都要转为rgb格式才能渲染到显示屏上,而原始 ...
- JDK 1.7 正式发布,Oracle 官宣免费提供!“新版任你发,我用JDK 8”或成历史?
Oracle公司JDK 17正式发布,JDK 17属于长期支持(LTS)版本,也就是获得8年的技术支持,自2021年9月至2029年9月截止. JDK 17版本更新了很多比较实用的新特性,关于此版本的 ...
- Mybatis log plugin插件破解修复版 MyBatis Log Plugin License Authorization Failed
github地址 - https://github.com/Link-Kou/intellij-mybaitslog
- 关于goto
(下面一段来源<征服C指针>) 75: ReadLineStatus read_line(FILE *fp, char **line) 76: { 77: int ch; 78: Read ...
- html 表单input disabled属性提交后台无法获得数据
在input上加入disabled属性后, 点击提交会遗漏该值, 有两个办法: 一 可以考虑readonly属性,一样的不可修改操作,但是可以提交 二 在提交时 js 代码操作去除input上的dis ...
- httpd进程数统计,IP封禁,IP连接数量情况查看
ps -ef|grep httpd|wc -l 统计httpd进程数,连个请求会启动一个进程,使用于Apache服务器. 查看Apache的并发请求数及其TCP连接状态:netstat -n | aw ...
- 查看Docker启动jenkins的管理员密码
Docker启动docker后,第一次方法jenkins,需要输入管理员密码. 其实查看启动时候的日志可以看到密码,也可以按照以下方法找到密码. 1.查看docker容器ID:docker ps -a ...