<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title></title>

</head>

<body>

<div id='app'>

<input style="width: 200px;height: 38px;outline: none;display: inline-block;" type='text'  v-model='text' />{{text}}

<input style="width: 200px;height: 38px;outline: none;display: inline-block;" type='text'  v-model='name' />{{name}}

<div style="width: 200px;height: 40px;background: red;" v-if='show'></div>

</div>

<script>

function Vue(options){

this.data=options.data;

var id=options.el;

var data=this.data;

this.observe(data,this)

var dom=this.tofagerment(document.getElementById(id),this);

var pardom=document.getElementById(id).appendChild(dom)

}

Vue.prototype.tofagerment=function(node,vm){

var flag=document.createDocumentFragment();

var child="";

while(child = node.firstChild){

this.compile(child,vm)

flag.append(child);

}

return flag

}

Vue.prototype.compile=function(child,vm){

var name=""

if(child.nodeType==1){

if(child.hasAttribute('v-model')){

name=child.getAttribute('v-model');

child.addEventListener('input',function(e){

var e=e||window.event;

var target=e.target||e.srcElement;

vm[name]=target.value;

})

child.value=vm[name];

child.removeAttribute('v-model')

}

}else if(child.nodeType==3){

var reg=/\{\{(.*)\}\}/;

if(reg.test(child.nodeValue)){

var regname=reg.exec(child.nodeValue)[1];

regname=regname.trim();

child.nodeValue=vm[regname]

}

new Watcher(vm,child,regname)

};

}

//订阅

Vue.prototype.observe=function(obj,vm){

Object.keys(obj).forEach(function(key){

console.log(obj[key])

vm.defineReactive(vm,key,obj[key])

})

}

// 消费

Vue.prototype.defineReactive=function(obj, key , value){

var dep=new Dep()

Object.defineProperty(obj,key,{

get:function(){

console.log('获取值');

if(Dep.target){

console.log(32423423)

dep.addSub(Dep.target)

}

return value

},

set:function(newValue){

console.log('设置值'+newValue);

if(newValue==value)return ;

value=newValue;

dep.notify()

}

})

}

//观察者模式

function Watcher(vm,node,name){

Dep.target=this

this.vm=vm;

this.node=node;

this.name=name;

this.update();

Dep.target=null

}

Watcher.prototype.get=function(){

this.value=this.vm[this.name]

}

Watcher.prototype.update=function(){

this.get()

this.node.nodeValue=this.value

}

//发布者

function Dep(){

this.subs=[];//订阅客户

}

Dep.prototype.addSub=function(sub){

this.subs.push(sub)

}

Dep.prototype.notify=function(sub){

this.subs.forEach(function(item){

item.update()

})

}

var myvue=new Vue({

el:"app",

data:{

text:'1312323123',

name:"eqwewqeqeq",

show:false,

}

})

</script>

</body>

</html>

原生js开发vue的双向数据绑定的更多相关文章

  1. Vue基础01vue的基本示例,vue的双向数据绑定,vue中常见的几种用法,vue相关常见指令

    自学vue框架,每天记录重要的知识点,与大家分享!有不足之处,希望大家指正. 本篇将讲述:vue的基本示例,vue的双向数据绑定,vue中常见的几种用法,vue相关常见指令 前期学习基础,使用vue. ...

  2. 原生js开发,无依赖、轻量级的现代浏览器图片懒加载插件,适合在移动端开发使用

    优势 1.原生js开发,不依赖任何框架或库 2.支持将各种宽高不一致的图片,自动剪切成默认图片的宽高 比如说你的默认图片是一张正方形的图片,则各种宽度高度不一样的图片,自动剪切成正方形. 完美解决移动 ...

  3. 面试题:你能写一个Vue的双向数据绑定吗?

    在目前的前端面试中,vue的双向数据绑定已经成为了一个非常容易考到的点,即使不能当场写出来,至少也要能说出原理.本篇文章中我将会仿照vue写一个双向数据绑定的实例,名字就叫myVue吧.结合注释,希望 ...

  4. vue实现双向数据绑定的原理

    vue实现双向数据绑定的原理就是利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的. 在MDN上对该方法的说明是:O ...

  5. 浅析vue的双向数据绑定

    vue 的双向数据绑定是基于es5的 object对象的defineProperty属性,重写data的set和get函数来实现的.1.defineProperty 数据展示 Object.defin ...

  6. vue的双向数据绑定实现原理

    在目前的前端面试中,vue的双向数据绑定已经成为了一个非常容易考到的点,即使不能当场写出来,至少也要能说出原理.本篇文章中我将会仿照vue写一个双向数据绑定的实例,名字就叫myVue吧.结合注释,希望 ...

  7. 原生js实现数据的双向绑定

    原生js实现数据的双向绑定 需要了解的属性是原色js的Object.definePrototype(obj,pop,descript); obj:被构造的对象 pop:被构造的对象的属性,创建对象或修 ...

  8. 一个关于原生 js 开发一款插件的前端教程

    教程链接: http://www.codeasily.net/course/plugin_course/ 写的不是很好,前面比较松后面比较急,请大家见谅,本人也没多少年前端经验,拿以前写过的教程网站, ...

  9. 原生js实现 vue的数据双向绑定

    原生js实现一个简单的vue的数据双向绑定 vue是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时 ...

随机推荐

  1. YouTube数据:谁获得了最多订阅者?

    原文来源: https://www.kaggle.com/roshan77/youtube-data-who-got-the-most-subscribers 介绍: Python笔记 使用来自Soc ...

  2. 【mysql-server】遇到的坑

    一.前提 最近因为工作原因,不得不用windows电脑,发现windows装mysql真的坑太多 23333: 二.环境 windows 环境 mysql 5.7(不建议用5.8坑更多) 三.步骤 3 ...

  3. 转:Excel—“撤销工作表保护密码”的破解并获取原始密码

    在日常工作中,您是否遇到过这样的情况:您用Excel编制的报表.表格.程序等,在单元格中设置了公式.函数等,为了防止其他人修改您的设置或者防止您自己无意中修改,您可能会使用Excel的工作表保护功能, ...

  4. remove-weknow-ac from mac chrome

    refer:https://macreports.com/how-to-remove-weknow-ac-malware-macos/ 1-Remove the weknow.ac profile. ...

  5. iptables工作常用操作

    正确的设置iptables命令汇总 iptables -P INPUT ACCEPT iptables -F iptables -X iptables -Z iptables -I INPUT -p ...

  6. git 与 ftp 共同工作

    因git主要用于版本管理,代码同步方面,因临时调试等原因,需要使用ftp上传文件. 但因为git的账户为ubuntu,ftp是虚拟账户overlord 导致文件权限不同,出现的问题主要有: 1.ftp ...

  7. docker mysql8 注意

    1. mysql8 出了有段时间了,但公司项目的django还不支持mysql8的默认加密方式. 连接时报错 Error : The server requested authentication m ...

  8. mac 中 git 操作账号的保存与删除

    mac 系统中,运行命令:git config -l,输出中看到credential.helper=osxkeychain时,说明 git 密码保存在 Keychain 中. 右上角搜索框内搜索 gi ...

  9. 支持向量机(Support Vector Machine,SVM)

    SVM: 1. 线性与非线性 核函数: 2. 与神经网络关系 置信区间结构: 3. 训练方法: 4.SVM light,LS-SVM: 5. VC维 u-SVC 与 c-SVC 区别? 除参数不同外, ...

  10. 视频流PS,PS封装H264

    出处: ISOIEC 13818-1 PS流: PS流由PSGOP组成,每个PSGOP是由I帧起始的多帧集合,每个GOP之间没有相互依赖信息,可以剪切拼接. | PSGOP0 | PSGOP1 | P ...