一入前端深似海,从此红尘是路人系列第九弹之如何实现一个双向数据绑定

简介:

前言

简单介绍一下双向数据绑定实现的是一个什么样的东西。首先有两个东西,他们分别是:
V-视图层
M-数据层
1、视图层传向数据层:V发生改变,M也发生改变
2、数据层传向视图层:M发生改变,V也发生改变
那么接下来我们也将自己书写代码实现这样两种功能,从而实现双向数据绑定。最终实现的效果如图:


修改input框里面的内容,p标签内容也实时相对应发生改变,data里面的数据也会发生改变

一、先奉献上自己完整的代码

这里我是基于jQuery进行的代码编写,其中的方法将在下面进行详细的解析


;(function($,doc,win) {
var VM = function(opt) {
  this.setting = {};
  $.extend(this.setting, opt.data);

  // 初始化VM
  this.init();
};
VM.prototype = {
  init: function() {
    this.render('input');
    this._render('p');
  },
  render: function(dom) {
    var self = this
      , data = self.setting;
    $(dom).each(function() {
      var _attr = $(this).attr('xq-model');
      if (_attr !== undefined) {
        if (data[_attr] !== undefined) {
          $(this).attr('value', data[_attr]);
          self.inputChange($(this), _attr);
        }
      }
    });
  },
  _render: function(dom) {
    var self = this;
    $(dom).each(function() {
      var val = $(this).html() || $(this).text() || $(this).val();
      if (val.indexOf('}}') !== -1 && val.indexOf('}}') !== -1) {
        val = val.replace(/^s+|{{|s+/,'');
        val = val.replace(/}}|[\s+]/g,'');
        self.labelChange(this, val);
      }
    })
  },
  labelRender: function(dom, _attr) {
    var self = this
      , data = self.setting;
    $(dom).each(function() {
      var val = $(this).attr(_attr);
      if (val !== undefined) {
        if (data[_attr] !== undefined) {
          $(this).html(data[_attr]) || $(this).text(data[_attr]) || $(this).val(data[_attr]);
        }
      }
    })
  },
  inputChange: function(_this, _attr) {
    var self = this
      , data = self.setting;
    _this.unbind('keydown');
    _this.keydown(function(){
      _this.unbind('keyup');
      _this.keyup(function() {
        var changeVal = _this.val()
          , oldVal = data[_attr];
        data[_attr] = changeVal;
        self.render('input');
        self.labelRender('p', _attr);
      })
    })
  },
  labelChange: function(_this,val) {
    var self = this
      , data = self.setting;
    if (val !== undefined) {
      if (data[val] !== undefined) {
        $(_this).html(data[val]) || $(_this).text(data[val]) || $(_this).val(data[val]);
      }
    }
    $(_this).attr(val,'')
  }
};
window.VM = VM;
})(jQuery,document,window);

二、创建自己的绑定规则

这里关于指令,我没有做作用域的包裹,比较完善的是需要用一个controller指令讲需要展示的view视图层包裹起来的。如果有想法的小伙伴们可以在最后自行去思考,接下来先直接上html代码


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>双向数据绑定</title>
</head>
<body>
    <input type="text" xq-model="msg">
    <p>
      {{ msg }}
    </p>
    <input type="text" xq-model="my">
    <p>{{ my }}</p>
</body>
<script src="js/jquery.js"></script>
<script src="js/api.js"></script>
</html>

这里我制定的双向指令是xq-model,内容的解析规则是{{}}。大家有自己喜欢的指令可以自行制定。

三、实现自己的绑定规则

我们现在需要做的就是一步一步去实现我们自己规定的一些绑定规则

首先我们需要做的第一步就是渲染出input中的xq-model指令指定的数据


/**
 * [render input框渲染]
 * @param  {[type]} dom [input]
 */
render: function(dom) {
  var self = this
    , data = self.setting;
  // 遍历dom中所有的input,搜寻带xq-model指令的input
  $(dom).each(function() {
    var _attr = $(this).attr('xq-model');
    // 判断是否有对应绑定data数据
    if (_attr !== undefined) {
      if (data[_attr] !== undefined) {
        $(this).attr('value', data[_attr]);
        // 调用input值改变方法
        self.inputChange($(this), _attr);
      }
    }
  });
}

实现inputChange方法


/**
 * [inputChange 值改变]
 * @param  {[type]} _this [当前input]
 * @param  {[type]} _attr [当前绑定对应的data数据]
 */
inputChange: function(_this, _attr) {
  var self = this
    , data = self.setting;
  // 绑定键盘事件进行监听
  _this.unbind('keydown');
  _this.keydown(function(){
    _this.unbind('keyup');
    _this.keyup(function() {
      var changeVal = _this.val()
        , oldVal = data[_attr];
      data[_attr] = changeVal;
      // 调用input框渲染方法
      self.render('input');
      // 调用标签值改变渲染方法
      self.labelRender('p', _attr);
    })
  })
}

到这里,对于input框的渲染及data数据的双向算完成了第一个了,接下来我们需要实现的便是对于标签的渲染


/**
 * [_render 标签渲染]
 * @param  {[type]} dom [element]
 */
_render: function(dom) {
  var self = this;
  // 遍历标签,拿到里面的内容
  $(dom).each(function() {
    var val = $(this).html() || $(this).text() || $(this).val();
    // 判断是否存在{{}},并截取拿到{{}} 里面的内容
    if (val.indexOf('}}') !== -1 && val.indexOf('}}') !== -1) {
      val = val.replace(/^s+|{{|s+/,'');
      val = val.replace(/}}|[\s+]/g,'');
      // 调用标签赋值方法
      self.labelChange(this, val);
    }
  })
}

实现labelChange方法


/**
 * [inputChange 值改变]
 * @param  {[type]} _this [当前input]
 * @param  {[type]} _attr [当前绑定对应的data数据]
 */
labelChange: function(_this,val) {
  var self = this
    , data = self.setting;
  if (val !== undefined) {
    if (data[val] !== undefined) {
      $(_this).html(data[val]) || $(_this).text(data[val]) || $(_this).val(data[val]);
    }
  }
  // 给当前对象绑定一个属性对应其data数据
  $(_this).attr(val,'')
}

最后实现input框输入,实时修改对应的标签的值labelRender方法


/**
 * [labelRender 标签实时渲染]
 * @param  {[type]} dom   [element]
 * @param  {[type]} _attr [当前data数据的key]
 */
labelRender: function(dom, _attr) {
  var self = this
    , data = self.setting;
  $(dom).each(function() {
    // 通过labelChange获取到对应data数据的attr属性
    var val = $(this).attr(_attr);
    if (val !== undefined) {
      if (data[_attr] !== undefined) {
        $(this).html(data[_attr]) || $(this).text(data[_attr]) || $(this).val(data[_attr]);
      }
    }
  })
}

最后我们调用一下实现好的VM


$(function() {
  new VM({
    data: {
      msg: 'hello',
      my: 'hehe'
    }
  });
})

好了,属于我们自己的一个简单的双向数据绑定至此便算是完成了,大家也可以自己将这个进行不断的完善,自己去实现一个完整的双向数据绑定。小伙伴们,加油↖(^ω^)↗

原文发布时间为:2016年11月21日
原文作者:qiangdada 

本文来源:开源中国 如需转载请联系原作者


目录
相关文章
|
4月前
|
缓存 JavaScript 前端开发
前端框架与库 - Vue.js基础:模板语法、数据绑定
【7月更文挑战第14天】Vue.js 是渐进式框架,以简洁API和高效数据绑定知名。本文聚焦模板语法与数据绑定,解释常见问题和易错点,助力初学者避坑。模板语法中,{{ expression }} 用于渲染值,v-bind/: 用于动态绑定属性。数据绑定涉及文本、属性和事件,注意v-model适用于表单元素,计算属性有缓存。理解正确用法,借助文档和IDE,可提升开发质量和效率。善用Vue.js,打造响应式UI。
143 4
|
6月前
|
前端开发
vue2与vue3双向数据绑定的区别,前端面试自我介绍
vue2与vue3双向数据绑定的区别,前端面试自我介绍
|
6月前
|
JavaScript 前端开发 开发者
深入探讨前端框架Vue.js的数据绑定原理
在前端开发中,数据绑定是Vue.js框架的核心特性之一,它实现了视图与数据的双向绑定,极大地提高了开发效率和用户体验。本文将深入探讨Vue.js数据绑定的原理,从响应式数据、依赖追踪到虚拟DOM等方面进行详细分析,帮助读者更好地理解Vue.js框架的工作机制。
96 0
|
6月前
|
JavaScript 前端开发 开发者
JavaScript 前端框架相关:Vue.js中的双向数据绑定是如何实现的?
JavaScript 前端框架相关:Vue.js中的双向数据绑定是如何实现的?
71 1
|
前端开发 JavaScript UED
数据绑定(Data Binding):实现实时数据交互的前端神器
数据绑定是现代前端开发中的一个重要概念,它允许开发人员将数据模型与用户界面保持同步,实现实时的数据交互。在本博客中,我们将深入研究数据绑定的概念、类型和用法,以及为什么它对构建响应式Web应用程序至关重要。
643 0
|
前端开发 API
前端知识案例-fetch api进行数据绑定
前端知识案例-fetch api进行数据绑定
90 0
前端知识案例-fetch api进行数据绑定
|
前端开发 JavaScript
#yyds干货盘点# 前端歌谣的刷题之路-第一百零九题-双向数据绑定
#yyds干货盘点# 前端歌谣的刷题之路-第一百零九题-双向数据绑定
103 0
#yyds干货盘点# 前端歌谣的刷题之路-第一百零九题-双向数据绑定
|
JavaScript 前端开发
前端-vue基础8-双向数据绑定
前端-vue基础8-双向数据绑定
90 0
前端-vue基础8-双向数据绑定
|
JavaScript 前端开发
前端-vue基础9-双向数据绑定2
前端-vue基础9-双向数据绑定2
85 0
前端-vue基础9-双向数据绑定2
|
前端开发
前端工作总结266-数据绑定逻辑处理
前端工作总结266-数据绑定逻辑处理
94 0
下一篇
无影云桌面