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. 【DB2】DB2中rank(),dense_rank(),row_number()的用法

    1.准备测试数据 DROP TABLE oliver_1; ),SUB_NO ),SCORE int); ,,); ,,); ,,); ,,); ,,); ,,); 2.详解rank(),dense_ ...

  2. iOS项目中的网络请求和上下拉刷新封装

    代码地址如下:http://www.demodashi.com/demo/11621.html 一.运行效果图 现在的项目中不可避免的要使用到网络请求,而且几乎所有软件都有上下拉刷新功能,所以我在此对 ...

  3. 网站定时任务IIS配置

    网站中的定时任务一般是必不可少的,具体的实现方法此文不做详细说明,如有需要了解的请留言.本文主要讲述定时任务有关IIS中的设置. 如果一个网站在20分钟内(IIS默认为20分钟)没有客户端访问,服务器 ...

  4. .NET Core环境安装

    .Net Core可从https://www.microsoft.com/net/download下载 如果你使用自己喜欢的命令行工具或使用Visual Studio Code,你需要下载.NET C ...

  5. unity, iOS下画面错乱解法

    unity版本号为5.1.1f1 Personal 在ipod5,系统为iOS7.1上测试.发现下面两种出现画面错乱的问题: 一,退后台在返回前台时画面发生错乱(错乱持续一两秒,然后变为正常).   ...

  6. Atitit.数据库存储引擎的原理与attilax 总结

    Atitit.数据库存储引擎的原理与attilax 总结 1. 存储引擎是什么1 2. 其它数据库系统(包括大多数商业选择)仅支持一种类型的数据存储2 3. 表的存储有三个文件:结构+数据+索引2 4 ...

  7. PILE读书笔记_文件I/O

    open函数 int open(const char *pathname, int flags, mode_t mode); 参数说明: (1)pathname: 表示要打开的文件路径 (2)flag ...

  8. ARM处理器的运行模式

    ARM处理器的7种运行模式 用户模式( usr ):ARM处理器正常的程序执行状态: 快速中断模式( fiq ):用于高速数据传输或通道处理: 外部中断模式( irq):用于通常的中断处理: 管理模式 ...

  9. Eclipse开发C/C++之使用技巧小结,写给新手

    我需要在Linux下开发C++项目,没有VS,用Vim开发是不错,但项目大了,效率 就跟不上IDE了,所以选了Eclipse+CDT插件.当然,Vimers觉得我说的不对的请 勿喷哈,我也是水手一个. ...

  10. Time Limit Exceeded 求逆序对数。

    /** 题目:Time Limit Exceeded 链接:https://oj.ejq.me/problem/28 题意:求逆序对数. 思路:树状数组求逆序对数.维护前面有多少个<=当前数的数 ...