实现数据双向绑定

Vue实现

MVVM

  • MVVM,一种软件架构模式,决定了写代码的思想和层次

    • M: model数据模型 (data里定义)
    • V: view视图 (html页面)
    • VM: ViewModel视图模型 (vue.js源码)
  • MVVM通过数据双向绑定让数据自动地双向同步 不再需要操作DOM

    • V(修改视图) -> M(数据自动同步)
    • M(修改数据) -> V(视图自动同步)
      在这里插入图片描述
  1. 在vue中,不推荐直接手动操作DOM!!!

  2. 在vue中,通过数据驱动视图,不要在想着怎么操作DOM,而是想着如何操作数据!!(思想转变)

在这里插入图片描述

下面实现双向绑定

vue实现双向绑定,只使用v-model指令就可以完成。

  • 数据变化 -> 视图自动同步
  • 视图变化 -> 数据自动同步

1. 基本使用

<template>
  <div>
    <div>
      <span>用户名:</span>
      <!-- 1. v-model
         双向数据绑定
         value属性 - vue变量
       -->
      <input type="text" v-model="username">
    </div>
    <div>
      <span>密码: </span>
      <input type="password" v-model="pass">
    </div>
  </div>
</template>

<script>
export default {
  data(){
    return {
      username: "",
      pass: ""
    }
  }
}
</script>

<style>

</style>

2. 更多用法

<template>
  <div>
    <div>
      <span>来自于: </span>
      <!-- 下拉菜单要绑定在select上 -->
      <select v-model="from">
        <option value="北京市">北京</option>
        <option value="南京市">南京</option>
        <option value="天津市">天津</option>
      </select>
    </div>
    <div>
      <!-- (重要)
      遇到复选框, v-model的变量值
      非数组 - 关联的是复选框的checked属性
      数组   - 关联的是复选框的value属性
       -->
      <span>爱好: </span>
      <input type="checkbox" v-model="hobby" value="抽烟">抽烟
      <input type="checkbox" v-model="hobby" value="喝酒">喝酒
      <input type="checkbox" v-model="hobby" value="写代码">写代码
    </div>
    <div>
      <span>性别: </span>
      <input type="radio" value="男" name="sex" v-model="gender"><input type="radio" value="女" name="sex" v-model="gender"></div>
    <div>
      <span>自我介绍</span>
      <textarea v-model="intro"></textarea>
    </div>
  </div>
</template>

<script>
export default {
  data(){
    return {
      from: "",
      hobby: [],
      gender: "男",
      intro: ""
    }
  }
}
</script>

<style>

</style>

3. v-model的修饰符

<template>
  <div>
    <div>
      <span>年龄</span>
      <!-- .number修饰符-把值parseFloat转数值再赋予给v-model对应的变量 -->
      <input type="text" v-model.number="age">
    </div>
    <div>
      <!-- .trim修饰 - 去除首尾两边空格 -->
      <span>人生格言</span>
      <input type="text" v-model.trim="motto">
    </div>
    <div>
      <!-- .lazy修饰符 - 失去焦点内容改变时(onchange事件), 把内容同步给v-model的变量 -->
      <span>个人简介</span>
      <textarea v-model.lazy="intro"></textarea>
    </div>
  </div>
</template>

<script>
export default {
  data(){
    return {
      age: 0,
      motto: "",
      intro: ""
    }
  }
}
</script>

<style>

</style>

原生实现

原理就是利用了Object.defineProperty(),这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的。

<div id="app">
  <input type="text">
</div>

<!-- 
  双向绑定的原生实现
   1. 数据 -> 视图 
      数据一旦发生变化  视图会使用最新的数据进行更新

   2. 视图 -> 数据
      视图一旦发生变化  会把视图当前用户输入的最新的值 反向影响到数据
 -->

<!-- 
   数据 -> 视图
   本质: 如何知道数据变化了
  -->

<!-- 
    视图 -> 数据
    本质: 如何可以拿到当前视图最新的值  监听事件通过事件回调拿到最新的输入值
 -->

<script>
  //  let info = {
  //    name:'cp'
  //  }
  let info = {}
  let _name = ''
  Object.defineProperty(info, 'name', {
    // 获取info.name属性会执行 
    // return 值就是你获取到的值
    get() {
      return _name
    },
    // 修改info.name属性时候会执行
    set(value) {

      // 使用最新的数据 value 去更新视图的逻辑呢?
      // 什么是视图更新? dom操作
      // 使用value 让input元素的value跟着变化
      _name = value
      document.querySelector('#app input').value = value
    }
  })
  document.querySelector('#app input').addEventListener('input', (e) => {
    // 反向赋值
    info.name = e.target.value
  })

  /*
    1.数据响应式  object.defineProperty()
    2.数据驱动视图   数据变化 视图会使用最新的数据进行更新
    3.如何让视图更新  视图更新离不开dom操作
    4.视图发生变化 指的是用户因为输入 input 对视图的显示进行了修改
    5.视图变化如何拿到当前视图最新的输入内容  基于事件监听  通过回调函数中的事件对象e拿到
  */

</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值