≡
  • 网络编程
  • 数据库
  • CMS技巧
  • 软件编程
  • PHP笔记
  • JavaScript
  • MySQL
位置:首页 > 网络编程 > vue.js

vue用Object.defineProperty手写一个简单的双向绑定的示例

人气:505 时间:2019-04-10

这篇文章主要为大家详细介绍了vue用Object.defineProperty手写一个简单的双向绑定的示例,具有一定的参考价值,可以用来参考一下。

感兴趣的小伙伴,下面一起跟随四海网的小编两巴掌来看看吧!

前言 上次写了一个Object.defineProperty() 不详解,文末说要写用它来写个双向绑定。说话算话,说来就来

前文链接 Object.defineProperty() 不详解

先看最后效果

【图片暂缺】

model演示.gif

 

什么是双向绑定?

 

 

1.当一个对象(或变量)的属性改变,那么调用这个属性的地方显示也应该改变,模型到视图(model => view)

2.当调用属性的这个地方改变了这个属性(通常是一个表单元素),那么这个对象(或变量)的属性也会改为最新的值 ,即视图到模型(view => model)

 

我们怎么知道对象的属性变了?

 

 

上文说到,Object.defineProperty 设置对象属性的描述字段里面有两个属性 set (设置属性时被调用)和get(获取属性时被调用),只说不练,你再讲什么?眼见为实好吗?OK ,上代码

代码如下:


var user = {};
var defaultName = "狂奔的蜗牛";
Object.defineProperty(user,"name",{
  get:function(){
    console.log("你是不是来获取值啦");
    return defaultName;
  },
  set:function(value){
    console.log("你是不是来设置值啦");
    defaultName = value;
  }
})

console.log(user.name);
user.name = "狂奔的萝卜";
console.log(user.name);

【图片暂缺】

get和set存取时被调用

如上图所示 每当我获取user.name属性时,get方法被调用,get 方法对应的函数被执行,输出 你是不是来获取值啦;每当我设置user.name属性时,set方法对应的函数被执行,输出 你是不是来设置值啦 ; 是的,我们监控到了代码对user.name属性的存取。

说明 假设id="model" 的元素的 value 是user.name的值,既然我们可以在改变属性的执行日志输出(console.log("你是不是来设置值啦");),那么,我们在设置值的时候给id="model" 的元素设置下新值,不就实现了从模型到视图?!!,说干就干

 

模型到视图(model => view)的同步

 

说明 假设id="model" 的元素的 value 是user.name的值,既然我们可以在改变属性的执行日志输出(console.log("你是不是来设置值啦");),那么,我们在设置值的时候给id="model" 的元素设置下新值,不就实现了从模型到视图?!!,说干就干

代码如下:


<body>
  手写一个简单双向绑定<br/>
  <input type="text" id="model"><br/>
  <div id="modelText"></div>
</body>
<script>
var user = {};
var defaultName = "狂奔的蜗牛";

document.querySelector("#model").value = defaultName;
document.querySelector("#modelText").textContent = defaultName;

//定义属性 监控改变
Object.defineProperty(user,"name",{
  get:function(){
    console.log("你是不是来获取值啦");
    return defaultName;
  },
  set:function(newValue){
    console.log("设置新值");
    defaultName = newValue;
    console.log("实现 模型 => 视图");
    document.querySelector("#model").value = newValue;
    document.querySelector("#modelText").textContent = newValue;
  }
})

console.log("2s 后改变值");

setTimeout(() => {
  //改变值
  user.name = "狂奔的萝卜";
}, 2000);
</script>

【图片暂缺】

模型到视图(model => view)的同步

 

视图到模型(view => model)的同步

 

问: 我们能捕捉到view对值更改吗?

答:可以!! id="model" 的input元素的 value 是user.name的值,填充在这个文本框里面,文本框有个“ keyup” 事件,当我们在文本框中输入文字的时候,文本框的值会跟着改变,并且会连续触发keyup事件,那么我们只需要监听这个事件,是不是就可以捕捉到view对值的更改了??既然文本框的值会跟着改变,我们获取最新的值再把新值更新到user.name属性,不就实现了视图到模型(view => model)的同步?没代码说个啥

代码如下:


<body>
  手写一个简单双向绑定<br/>
  <input type="text" id="model"><br/>
  <div id="modelText"></div>
</body>
<script>
  var user = {};
  var defaultName = "狂奔的蜗牛";
  var model = document.querySelector("#model");
  var modelText = document.querySelector("#modelText");

  model.value = defaultName;
  modelText.textContent = defaultName;

  //定义属性 监控改变
  Object.defineProperty(user,"name",{
    get:function(){
      console.log("你是不是来获取值啦");
      return defaultName;
    },
    set:function(newValue){
      console.log("设置新值");
      defaultName = newValue;
      model.value = newValue;
      modelText.textContent = newValue;
    }
  })

  model.addEventListener("keyup", function () {
    user.name = this.value;
    console.log("实现 视图 => 模型");
  }, false)
</script>

【图片暂缺】

view2model.gif

 

【最终源码】

 

在上述代码的基础上,加入了 用户输入中文的判断(用户输入中文时,频繁触发 keyup事件,但实际上输入并没有结束。)

代码如下:


<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>双向绑定</title>
</head>
<body>
  手写一个简单双向绑定<br/>
  <input type="text" id="model"><br/>
  <div id="modelText"></div>
</body>
<script>
  var model = document.querySelector("#model");
  var modelText = document.querySelector("#modelText");
  var defaultName = "defaultName";
  var userInfo = {}
  model.value = defaultName;
  Object.defineProperty(userInfo, "name", {
    get: function () {
      return defaultName;
    },
    set: function (value) {
      defaultName = value;
      model.value = value;
      console.log("-----value");
      console.log(value);
      modelText.textContent = value;
    }
  })

  userInfo.name = "new value";
  var isEnd = true;

  model.addEventListener("keyup", function () {
    if (isEnd) {
      userInfo.name = this.value;
    }
  }, false)
  //加入监听中文输入事件
  model.addEventListener("compositionstart", function () {
    console.log("开始输入中文");
    isEnd = false;
  })
  model.addEventListener("compositionend", function () {
    isEnd = true;
    console.log("结束输入中文");
  })
</script>
</html>

 

【完结】

 

Object.defineProperty 可以做很多好玩儿的,自己慢慢探索哈~

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持四海网。

本文来自:http://www.q1010.com/184/5259-0.html

注:关于vue用Object.defineProperty手写一个简单的双向绑定的示例的内容就先介绍到这里,更多相关文章的可以留意四海网的其他信息。

关键词:vue.js

您可能感兴趣的文章

  • Vue自定义指令封装节流函数的方法示例
  • vue.js绑定事件监听器示例【基于v-on事件绑定】
  • vue.js使用v-pre与v-html输出HTML操作示例
  • vue.js实现的绑定class操作示例
  • vue中锚点的三种方法
  • vue.js 实现点击展开收起动画效果
  • vue中倒计时组件的实例代码
  • vue-cli配置环境变量的方法
  • vue.js通过路由实现经典的三栏布局实例代码
  • Vue脚手架的简单使用实例
上一篇:vue超时计算的组件实例代码
下一篇:Vue脚手架的简单使用实例
热门文章
  • Vue 报错TypeError: this.$set is not a function 的解决方法
  • vue实现动态添加数据滚动条自动滚动到底部的示例代码
  • vue项目设置scrollTop不起作用(总结)
  • vue项目中使用vue-i18n报错的解决方法
  • iview实现select tree树形下拉框的示例代码
  • 分析关于element级联选择器数据回显问题
  • vue项目打包后打开页面空白解决办法
  • 解决element ui select下拉框不回显数据问题的解决
  • element-ui table span-method(行合并)的实现代码
  • element-ui 设置菜单栏展开的方法
  • 最新文章
    • 理解vue ssr原理并自己搭建简单的ssr框架
    • vue favicon设置以及动态修改favicon的方法
    • vue-router启用history模式下的开发及非根目录部署方法
    • 从零开始在NPM上发布一个Vue组件的方法步骤
    • Element input树型下拉框的实现代码
    • Vue 报错TypeError: this.$set is not a function 的解决方法
    • Vue.js组件高级特性实例分析
    • 浅谈VueJS SSR 后端绘制内存泄漏的相关解决经验
    • 分析Vue.js自定义tipOnce指令用法实例
    • 浅谈vuex actions和mutation的异曲同工

四海网收集整理一些常用的php代码,JS代码,数据库mysql等技术文章。