w

https://docs.microsoft.com/en-us/scripting/javascript/reference/object-defineproperty-function-javascript

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties

双向绑定

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="Generator" content="EditPlus®">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<title>Document</title>
</head>
<body>
<div id="app">
<form>
<input type="text" v-model="count"/>
<button type="button" v-click="increment">increment</button>
<button type="button" v-click="alert('Hello world')">alert</button>
</form>
<p v-bind="count"></p>
</div>
<script>
function Lue(options) {
this._init(options);
console.log(this)
} Lue.prototype._init = function (options) {
this.$options = options; //传入的实例配置
this.$el = document.querySelector(options.el); //实例绑定的根节点
this.$data = options.data; //实例的数据域
this.$methods = options.methods; //实例的函数域 //与DOM绑定的数据对象集合
//每个成员属性有一个名为_directives的数组,用于在数据更新时触发更新DOM的各directive
this._binding = {};
this._parseData(this.$data); this._compile(this.$el); //编译DOM节点
}; //遍历数据域,添加getter/setter
Lue.prototype._parseData = function (obj) {
var value;
for (var key in obj) {
//排除原型链上的属性,仅仅遍历对象本身拥有的属性
if (obj.hasOwnProperty(key)) {
this._binding[key] = { //初始化与DOM绑定的数据对象
_directives: []
};
value = obj[key];
this.convert(key, value);
}
}
}; /**对象属性重定义
* @param key 数据对象名称,本例为"count"
* @param val 数据对象的值
*/
Lue.prototype.convert = function (key, val) {
var binding = this._binding[key];
Object.defineProperty(this.$data, key, {
enumerable: true,
configurable: true,
get: function () {
console.log(`获取$
{
val
}`)
;
return val;
},
set: function (newVal) {
console.log(`更新$
{
newVal
}`)
;
if (val != newVal) {
val = newVal;
binding._directives.forEach(function (item) {
item.update();
})
}
}
})
}; function Directive(name, el, vm, exp, attr) {
this.name = name; //指令名称,例如文本节点,该值设为"text"
this.el = el; //指令对应的DOM元素
this.vm = vm; //指令所属lue实例
this.exp = exp; //指令对应的值,本例如"count"
this.attr = attr; //绑定的属性值,本例仅实验innerHTML this.update(); //首次绑定时更新
} Directive.prototype.update = function () {
//更新DOM节点的相应属性值
this.el[this.attr] = this.vm.$data[this.exp];
}; //解析DOM的指令
Lue.prototype._compile = function (root) {
var _this = this;
//获取指定作用域下的所有子节点
var nodes = root.children;
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
//若该元素有子节点,则先递归编译其子节点
if (node.children.length) {
this._compile(node);
} if (node.hasAttribute("v-click")) {
node.onclick = (function () {
var attrVal = nodes[i].getAttribute("v-click");
var args = /\(.*\)/.exec(attrVal);
if (args) { //如果函数带参数,将参数字符串转换为参数数组
args = args[0];
attrVal = attrVal.replace(args, "");
args = args.replace(/[\(|\)|\'|\"]/g, '').split(",");
}
else args = [];
return function () {
_this.$methods[attrVal].apply(_this.$data, args);
}
})()
} if (node.hasAttribute(("v-model"))
&& node.tagName == "INPUT" || node.tagName == "TEXTAREA") {
//如果是input或textarea标签
node.addEventListener("input", (function (key) {
var attrVal = node.getAttribute("v-model");
//将value值的更新指令添加至_directives数
_this._binding[attrVal]._directives.push(new Directive(
"input",
node,
_this,
attrVal,
"value"
)) return function () {
_this.$data[attrVal] = nodes[key].value;
}
})(i));
} if (node.hasAttribute("v-bind")) {
var attrVal = node.getAttribute("v-bind");
//将innerHTML的更新指令添加至_directives数
_this._binding[attrVal]._directives.push(new Directive(
"text",
node,
_this,
attrVal,
"innerHTML"
))
}
}
} window.onload = function () {
var app = new Lue({
el: "#app",
data: {
count: 0,
},
methods: {
increment: function () {
this.count++;
},
alert: function (msg) {
alert(msg)
}
}
})
}
</script>
</body>
</html>

Object.defineProperties()的更多相关文章

  1. 分享一个Object.defineProperties 定义一个在原对象可读可写的方法

    function A(){ this.name = 'hellow word'; } Object.defineProperties( A.prototype,{ doSomething2 : { v ...

  2. Object.defineProperties()和Object.defineProperty()方法

    Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象. 语法:Object.defineProperty(obj, pro ...

  3. JS Object.defineProperties()方法

    JS Object.defineProperties()方法 描述: Object.defineProperties()方法为目标对象同时配置多个属性. 语法: Object.defineProper ...

  4. Object.defineProperties()与Proxy对象代理

    Object.defineProperties() 了不起啊..vue.js通过它实现双向绑定的 Object.defineProperties(obj,props) 方法直接在一个对象上定义新的属性 ...

  5. Object.defineProperty和Object.defineProperties

    添加属性到对象,或修改现有属性的特性   用法:     Object.defineProperty(object, propertyName, descriptor); 参数:     object ...

  6. Object.defineProperties——MEAN开发后台的Model层

    Object.defineProperties是什么?有什么用? 这个问题比较听起来可能比较难以理解,确实我也是在项目中遇到的才会去想.以前看到<高级程序设计>的时候,有这么一种东西,定义 ...

  7. 定义多个属性 Object.defineProperties()

    var book = {} Object.defineProperties(book,{ _year:{ value:2004 }, editable:{ value:1 }, year:{ get: ...

  8. js中Object.defineProperties 定义一个在原对象可读可写的方法

    function A(){ this.name = 'hellow word'; } Object.defineProperties( A.prototype,{ doSomething2 : { v ...

  9. ES5 Object.defineProperties / Object.defineProperty 的使用

    临时笔记,稍后整理 var obj = { v: , render: function () { console.log(") } }; // Object.defineProperties ...

随机推荐

  1. Photoshop之学习笔记(2) - 常用快捷键

    1.1024x768常用桌面分辨率2.点阵图(像素图).矢量图3.PPI 分辨率  DPI 打印输出的分辨率4.选框工具5.拾色器(默认H恢复色条 色相)6.Ctrl+D 取消选框工具7.Ctrl+S ...

  2. android 类似微信的摇一摇实现

    一.在 AndroidManifest.xml 中添加操作权限 <uses-permission android:name="android.permission.VIBRATE&qu ...

  3. Photoshop | 快速抠头发(调整边缘/选择并遮住)

    ———————————————————————————————————————————— Photoshop快速抠头发(CS6中调整边缘功能,CC2017中更名为选择并遮住) - - - - - - ...

  4. 云计算的三种服务模式:IaaS,PaaS和SaaS(转载)

    云服务”现在已经快成了一个家喻户晓的词了.如果你不知道PaaS, IaaS 和SaaS的区别,那么也没啥,因为很多人确实不知道. “云”其实是互联网的一个隐喻,“云计算”其实就是使用互联网来接入存储或 ...

  5. MongoDB密码设置(基于windows)

    参考文档:http://www.cnblogs.com/zengen/archive/2011/04/23/2025722.html   MongoDB部署到Windows上后是默认是无权限限制的的. ...

  6. mysql无法启动ERROR! MySQL is running but PID file could not be found ?

    转载于:http://blog.csdn.net/wuzhilon88/article/details/17616635 第一种方法:可能是硬盘满了,清理下垃圾文件. 第二种: 查看下数据库运行状态 ...

  7. ftp获取远程Pdf文件

    此程序需要安装ftp服务器,安装adobe reader(我这里使用的adobe reader9.0) 1.部署ftp服务器 将ftp的权限设置为允许匿名访问,部署完成 2.安装adobe reade ...

  8. zendstdio的智能提示功能

    在项目的include的那个地方邮寄,在addsource file  然后指向TP类库的文件夹,刷新项目即可有智能提示

  9. Java synchronized详解(java 线程同步)

    http://www.cnblogs.com/devinzhang/archive/2011/12/14/2287675.html

  10. jquery插件实现分页

    Query Pagination分页插件 原项目地址:http://plugins.jquery.com/project/pagination 版本:v1.2 源文件下载:英文原版 或 中文翻译修改版 ...