美文网首页
仿Vue 动态绑定数据

仿Vue 动态绑定数据

作者: 三生石上绛珠草 | 来源:发表于2017-05-14 02:02 被阅读128次

--2017.5.12
完成百度前端学院的糯米学院动态数据绑定第四题和第五题的一部分。

目前实现的功能有:

  1. 监测对象的属性的访问和改变
  2. 添加$watch
  3. 实现深层次数据变化逐层往上传播(记录每个属性的父亲,并检查祖先的所有监听回调,如果存在,就触发)
  4. DOM中数据渲染,尚未测试完全。目前并不支持双向数据绑定。

缺点:
1.不支持数组
2.不支持输入框数据绑定

function FVue(options, parent, parentKey) {
    this.$watch = this._watch;
    this.parent = parent;
    this.parentKey = parentKey;
    this.listeners = {};
    this.$data = options.data || options;
    this._walk(this.$data);
    //this.render(options);
}
FVue.prototype.render = function(opts)
{
    var el =  document.querySelector(opts.el);
    if (el) this._compileNode(el);
}
FVue.prototype._compileNode = function (el) {

    switch (el.nodeType) {
        case document.ELEMENT_NODE:
            this._compileElement(el);
            break;
        case document.TEXT_NODE:
            this._compileTextNode(el);
            break;
    }
}
FVue.prototype._compileElement = function (el) {
    if (el.hasChildNodes()) {
        Array.from(el.childNodes).forEach(this._compileNode, this)
    }
}
FVue.prototype._compileTextNode = function (el) {
    var pattern = /{{\w+}}/g;
    var text = el.nodeValue;
    var exps = text.match(pattern);
    var newNode = document.createTextNode('');
    exps.map(function (item) {
        var htmlText = item.nodeValue;
        var propText = item.replace(/[{}]/g, '');
        var props = propText.split('.');
        var len = props.length;
        if (len <= 0) return;
        var tmp = this.$data[props[0]];
        for (var i = 1; i < len; i++) {
            tmp = tmp[props[i]];
        }
        newNode.nodeValue += tmp;
    });
    el.parentNode.insertBefore(el, newNode);
    el.parentNode.removeChild(el);
}
function isArray(obj) {
    return Object.prototype.toString.call(obj) == "[object Array]";
}

FVue.prototype._walk = function (obj) {
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            var val = obj[key];
            if (typeof val === 'object') {
                this._bindData(this.$data, key, val);//bug fixed.every name must define getter/setter
                new FVue(val, this, key);
            }
            else if (typeof val === 'function') {
                this._bindData(this.$data, key, val());
            }
            else {
                this._bindData(this.$data, key, val);
            }
        }
    }
}
FVue.prototype._publish = function (key, val) {
    if (!this.listeners[key])//不要在Object.defineProperty里访问key,那时候key还没有定义
    {
        return;
    }
    else {
        for (var i = 0, len = this.listeners[key].length;
            i < len; i++) {
            this.listeners[key][i](val);
        }
    }
}
FVue.prototype._watch = function (prop, callback) {
    if (!this.listeners[prop]) {
        this.listeners[prop] = [];
    }
    this.listeners[prop].push(callback);
}
FVue.prototype._bindData = function (obj, key, val) {
    var self = this;
    self._watch(key, function (newVal) { // 为每个值设置一个监听事件
        console.log(`你设置了 ${key}, 新的值为${newVal}`);
    })
    Object.defineProperty(obj, key, {
        enumerable: true,
        configurable: true,
        get: function () {
            console.log('你访问了' + key);
            return val;
        },
        set: function (newVal) {
            // console.log('你设置了' + key);
            // console.log('新的' + key + ' = ' + newVal);

            if (self.parent != undefined) {
                //bug fixed.listeners={name,[callback]}.callback is an Array
                self.parent.listeners[self.parentKey].map(
                    function (item) { item(newVal) }
                );
            }
            if (val === newVal) {
                return;
            }
            val = newVal;
            self._publish(key, val);//在Object内部无法访问到this
            if (typeof newVal === 'object') {
                new FVue(val);
            }

        }
    })
}

相关文章

  • 仿Vue 动态绑定数据

    --2017.5.12完成百度前端学院的糯米学院动态数据绑定第四题和第五题的一部分。 目前实现的功能有: 监测对象...

  • Vue 实例 一

    Vue实例基础一 数据的双向绑定 v-model 绑定表单的相应事件,和数据实现动态的双向绑定,需要在Vue实例中...

  • vue的this.$set的作用

    用于手动让vue实现动态绑定数据 如果我们在创建实例以后,再在实例上绑定新属性,vue是无法进行双向绑定的。比如:...

  • 【融职培训】Web前端学习 第10章 小程序开发4 小程序开发

    一,数据绑定 VUE:vue动态绑定一个变量的变量元素的某个属性的时候,会在变量前面加上冒号:,例: 我的titl...

  • BaiDuIFE ------ vue动态数据绑定实现过程

    感谢百度前端技术学院带领我进步!谨以此文,记录我的学习过程~动态数据绑定 Vue的初学者一定对于数据的动态绑定并不...

  • 2019-03-25

    vue v-for通过index动态绑定input输入框的数据 vue项目中经常会遇到各种难题,比如v-for...

  • Vue 中的双向数据绑定

    双向绑定 单向数据流 双向绑定 or 单向数据流 Vue 是单向数据流,不是双向绑定 Vue 的双向绑定是语法糖 ...

  • vue 双向数据绑定

    Vue实现数据双向绑定的原理:Object.defineProperty()vue实现数据双向绑定主要是:采用数据...

  • vue实例和数据绑定

    vue实例和数据绑定 vue实例和数据绑定 通过script便签引入vue 通过vue构造函数来创建一个vue实例...

  • Vue入门(二)——数据绑定

    一、什么是双向数据绑定 双向数据绑定是Vue的核心功能之一。所谓双向数据绑定是指:HTML标签上的数据绑定到Vue...

网友评论

      本文标题:仿Vue 动态绑定数据

      本文链接:https://www.haomeiwen.com/subject/sjttxxtx.html