Vue丐版数据双向绑定

迷南。 2023-07-13 04:13 158阅读 0赞

HTML

  1. <div id="app">
  2. <form>
  3. <input type="text" v-model="number">
  4. <input type="text" v-model="number">
  5. </form>
  6. </div>

创建VM实例

  1. window.onload = function() {
  2. var app = new VueModel({
  3. el:'#app',
  4. data: {
  5. number: 0,
  6. }
  7. })
  8. }

初始化函数

  1. function VueModel(options) {
  2. this._init(options);
  3. }

初始化函数实现

  1. VueModel.prototype._init = function (options) {
  2. this.$options = options;
  3. //判断传入的el类型
  4. this.$el = options.el.nodeType === 1 ? options.el : document.querySelector(options.el);
  5. this.$data = options.data;
  6. this.$methods = options.methods;
  7. this.vmbind = { };
  8. this._obverse(this.$data);
  9. this._complie(this.$el);
  10. }

实现数据监听

  1. //数据监听器
  2. VueModel.prototype._obverse = function (obj) {
  3. //获取数据对象data
  4. var _this = this;
  5. //遍历数据对象中的元素
  6. Object.keys(obj).forEach(function (key) {
  7. if (obj.hasOwnProperty(key)) {
  8. _this.vmbind[key] = { _direc: []};
  9. var value = obj[key];
  10. //递归遍历类型是对象的一级属性
  11. if (value instanceof Object) {
  12. _this._obverse(value);
  13. }
  14. var vmbind = _this.vmbind[key];
  15. //数据监听
  16. Object.defineProperty(_this.$data, key, {
  17. enumerable: true,
  18. configurable: true,
  19. get: function () {
  20. return value;
  21. },
  22. set: function (newVal) {
  23. //触发数据更新
  24. if (value !== newVal) {
  25. value = newVal;
  26. vmbind._direc.forEach(function (item) {
  27. item.update();
  28. })
  29. }
  30. }
  31. })
  32. }
  33. })
  34. }

绑定view和model

  1. //绑定view与model
  2. VueModel.prototype._complie = function (root) {
  3. //取出元素节点
  4. var _this = this;
  5. //取出所有一级子节点
  6. var nodes = root.children;
  7. for (var i = 0; i < nodes.length; i++) {
  8. var node = nodes[i];
  9. //递归子节点
  10. if (node.children.length) {
  11. this._complie(node);
  12. }
  13. if (node.hasAttribute('v-model') && (node.tagName = 'INPUT' || node.tagName == 'TEXTAREA')) {
  14. node.addEventListener('input', (function(key) {
  15. var attrVal = node.getAttribute('v-model');
  16. //增加订阅者
  17. _this.vmbind[attrVal]._direc.push(new Watcher(
  18. 'input',
  19. node,
  20. _this,
  21. attrVal,
  22. 'value'
  23. ))
  24. return function() {
  25. //数据更新
  26. _this.$data[attrVal] = nodes[key].value;
  27. }
  28. })(i));
  29. }
  30. }
  31. }

消息订阅

  1. function Watcher(name, el, vm, exp, attr) {
  2. this.name = name;
  3. this.el = el;
  4. this.vm = vm;
  5. this.exp = exp;
  6. this.attr = attr;
  7. this.update();
  8. }
  9. Watcher.prototype.update = function () {
  10. //将视图中的数据更新到model中
  11. this.el[this.attr] = this.vm.$data[this.exp];
  12. }

效果

在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,158人围观)

还没有评论,来说两句吧...

相关阅读