【vue】vue双向数据绑定的原理解析及代码实现_04

目录

❣️ 双向绑定

1. 问题

2. 原因

3. 何时使用双向绑定

4. 如何使用双向绑定: (普通文本框)

5. 结果

6. 示例: 文本框输入搜索关键词,点按钮执行搜索

7. 双向绑定的原理

8. 示例: 使用事件模拟v-model的原理

9. 实现按回车搜索,边输入边搜索

10. 不同表单元素,绑定原理不同

11. v-model简写

💥 扩展:this判断—8种指向

❣️ 总结:知识点提炼


 【前文回顾】👉 vue的常用指令及用法总结(续)_03 


❣️ 双向绑定

1. 问题

用传统的:绑定表单元素的value属性,无法自动获得界面上用户输入的新内容。

2. 原因

其实在vue中有两种绑定方式:

         (1). 单向绑定:

         a. 可自动将程序中的变化,更新到界面上显示(Model->View)

         b. 但是,如果界面中用户修改了内容,则无法将新内容自动更新到程序中的变量中(View ×-> Model)

         (2). 双向绑定:

         a. 即可以自动将程序中的变化,更新到界面上显示(Model->View)

         b. 又可以自动将界面上用户修改的新内容自动更新回程序中的变量中(View -> Model)

3. 何时使用双向绑定

今后,只要在vue中,想获得表单元素的新内容,都用双向绑定

4. 如何使用双向绑定: (普通文本框)

         <input v-model:value="变量">

            View<-Model

            View->Model

5. 结果

         (1). 程序中变量值发生了变化,则自动将程序中的变量值更新到界面上显示

         (2). 用户在界面中输入了新内容,则自动将界面上的新内容,更新回data中的变量里保存。

6. 示例: 文本框输入搜索关键词,点按钮执行搜索

6_v-model.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="js/vue.js"></script>
</head>
<body>
  <!--1. 做界面-->
  <div id="app">
    <!--1.1 找可能发生变化的位置
      本例中: 文本框的内容可能发生变化-->
    <input type="text" v-model:value="keywords">
    <!--1.2 找触发事件的元素
      本例中: button触发事件-->
    <button @click="search">百度一下</button>
  </div>
  <script>
    //2. 创建new Vue()对象
    var vm=new Vue({
      el:"#app",
      //3. 创建模型对象
      //3.1 因为界面上只需要一个变量,所以
      data:{
        keywords:"" //保存用户在文本框中输入的内容,开局,用户什么都没输入,默认""
      },
      //3.2 因为界面上需要一个函数
      methods:{
        search(){
          console.log(`查找 ${this.keywords} 相关的内容...`);
        }
      }
    })
  </script>
</body>
</html>
<!-- 事到如今呀。。。有些事儿,你也该知道了。孩子大了,瞒不住了。
其实,v-model后的“:value”和“:checkex”都可以省略。v-model很聪明,可以根据自己所在何种元素,自动判断应该绑定哪个属性。
比如,在文本框就自动绑定value属性,在radio就自动绑定checked属性。
虽然可以简写,但是,简写后更看不出原理,所以,一定要先把学习到的这四种不同情况,做熟练,再享受简写带来的便利。虽然简写,但是原理不变。 -->

 运行结果:

  

7. 双向绑定的原理

v-model会自动为当前表单元素绑定: @input或@change。当当前表单元素的value值发生变化时,自动触发事件,调用事件处理函数,自动修改data中的变量。

🏿 分析:双向数据绑定原理的实现
 

➡️ vue数据的双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的。其核心就是通过Object.defineProperty()方法设置set和get函数来实现数据的劫持(监听),在数据变化时发布消息给订阅者,触发相应的监听回调。也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;


总结起来,大致过实现过程就是:首先是对数据进行监听,然后当监听的属性发生变化时则告诉订阅者是否要更新,若更新就会执行对应的更新函数从而更新视图。


注:创建访问器属性,使用Object.defineProperty或Object.defineProperties添加,详情可参考我之后会发布的JS高级篇——关于保护对象知识点里的创建访问器属性,这里稍作解释:

👉 只要希望利用自定义规则保护对象属性值时,都要用访问器属性

👉 什么是访问器属性: 自己不保存属性值,而是只提供对另一个数据属性的保护!——保镖


 

➡️ MVVM模式就是Model–View–ViewModel模式。它实现了View的变动,自动反映在 ViewModel,反之亦然。对于双向绑定的理解,就是用户更新了View,Model的数据也自动被更新了,这种情况就是双向绑定。再说细点,就是在单向绑定的基础上给可输入元素input、textare等添加了change(input)事件,(change事件触发,View的状态就被更新了)来动态修改model。

8. 示例: 使用事件模拟v-model的原理

7_v-model2.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>双向绑定原理:使用@input事件模拟实现双向绑定</title>
  <script src="js/vue.js"></script>
</head>
<body>
  <!--1. 做界面-->
  <div id="app">
    <!--1.1 找可能发生变化的位置
      本例中: 文本框的内容可能发生变化-->
    <input type="text" @input="myInput" :value="keywords">
    <!--1.2 找触发事件的元素
      本例中: button触发事件-->
    <button @click="search">百度一下</button>
  </div>
  <script>
    //2. 创建new Vue()对象
    var vm=new Vue({
      el:"#app",
      //3. 创建模型对象
      //3.1 因为界面上只需要一个变量,所以
      data:{
        keywords:"" //保存用户在文本框中输入的内容,开局,用户什么都没输入,默认""
      },
      //3.2 因为界面上需要一个函数
      methods:{
        search(){
          console.log(`查找 ${this.keywords} 相关的内容...`);
        },
        myInput(e){
          //this不指当前触发事件的元素了
          //vue中所有的this都指向当前new Vue()对象本身!
          //获得当前文本框的内容
          var value=e.target.value;
          //        当前文本框 内容
          //将文本框的内容自动修改到data中的keywords变量上
          this.keywords=value;
        }
      }
    })
  </script>
</body>
</html>
<!-- 事到如今呀。。。有些事儿,你也该知道了。孩子大了,瞒不住了。
其实,v-model后的“:value”和“:checkex”都可以省略。v-model很聪明,可以根据自己所在何种元素,自动判断应该绑定哪个属性。
比如,在文本框就自动绑定value属性,在radio就自动绑定checked属性。
虽然可以简写,但是,简写后更看不出原理,所以,一定要先把学习到的这四种不同情况,做熟练,再享受简写带来的便利。虽然简写,但是原理不变。 -->

运行结果:

9. 实现按回车搜索,边输入边搜索

         (1). 按回车搜索:

         a. <input @keyup="事件处理函数">

         b. 问题: 虽然可以实现边输入边搜索,但是,按任意键都执行搜索,不是我们想要的。我们希望只有按回车才执行搜索

         c. 解决: vue中提供了一套事件修饰符:

                  1). 什么是: 对触发事件的条件或默认行为加以限制

                  2). 比如: @keyup.13,表示只有13号回车键才能触发事件

         d. 问题: 如果只有13号键可以触发事件,那么,如何实现边输入边搜索呢?

         e. 解决: 利用vue提供的"监听函数"

         (2). 实现边输入边搜索:

         a. 什么是"监听函数": 当data中某个变量一改变,就会立刻自动触发的特殊函数。

        b. 何时: 今后,只要希望data中的一个变量一变,立刻自动执行一个操作时,都要用监听函数!——个变量都可以有一个监听函数

         c. 如何:

                  new Vue({
                          el:"#app",

                          data:{ ... 变量: 值, ... },

                          methods:{

                                   事件处理函数(){

                                   }

                          },

                          watch:{ //专门包含所有监听函数的区域

                                   变量名(){

                                            //只有data中同名变量的值发生变化时自动触发!

                                   }

                          }
                  })

         (3). 示例: 实现边输入边搜索,按回车也能搜索

         8_v-model3.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="js/vue.js"></script>
</head>
<body>
  <!--1. 做界面-->
  <div id="app">
    <!--1.1 找可能发生变化的位置
      本例中: 文本框的内容可能发生变化-->
    <!--1.2 找触发事件的元素
      本例中: 
      button触发单击事件
      input还可触发键盘抬起事件,但是,只允许13号键触发事件-->
    <input type="text" v-model:value="keywords" @keyup.13="search">
    <button @click="search">百度一下</button>
  </div>
  <script>
    //2. 创建new Vue()对象
    var vm=new Vue({
      el:"#app",
      //3. 创建模型对象
      //3.1 因为界面上只需要一个变量,所以
      data:{
        keywords:"" //保存用户在文本框中输入的内容,开局,用户什么都没输入,默认""
      },
      //3.2 因为界面上需要一个函数
      methods:{
        search(){
          console.log(`查找 ${this.keywords} 相关的内容...`);
        }
      },
      watch:{//专门保存所有监听函数的区域
        keywords(){//专门监听data中keywords变量的函数
          //希望只要keywords变量发生改变,就自动搜索
          this.search();
        }
      }
    })
  </script>
</body>
</html>
<!-- 事到如今呀。。。有些事儿,你也该知道了。孩子大了,瞒不住了。
其实,v-model后的“:value”和“:checkex”都可以省略。v-model很聪明,可以根据自己所在何种元素,自动判断应该绑定哪个属性。
比如,在文本框就自动绑定value属性,在radio就自动绑定checked属性。
虽然可以简写,但是,简写后更看不出原理,所以,一定要先把学习到的这四种不同情况,做熟练,再享受简写带来的便利。虽然简写,但是原理不变。 -->

运行结果: 

◼️ 分析:本例是一个全方位的多个方式实现搜索的功能,这也是我们以后做网站需要集成的搜索功能:

1. 一边输入一边搜索(输入和搜索同步)的搜索功能,这是watch的功劳:watch:{...}

watch:{

        keywords(){

          this.search();

        }

}

2. 输入内容后,按回车实现,这是keyup.13的功劳:@keyup.13="search"

<input type="text" v-model:value="keywords" @keyup.13="search">

3. 默认保留的点击按钮,实现搜索:@click="search"

<button @click="search">百度一下</button>
 

👇 前3次是边输入边搜索功能的实现;第四次是回车实现;第五次是点击按钮触发 👇

10. 不同表单元素,绑定原理不同

◼️一般情况下我们默认用户提交的信息为绑定v-mode指令的表单元素的value属性的值;当然这只是一般情况下,实际上用户提交的信息与不同表单类型有关。 ​

         (1). radio:

         对应小程序视频: 小程序->在线->VUE->day02 4. 双向绑定 v-mode radio ...

         a. 特点:

                  1). 提前准备好一批写死的value,让用户多选一。

                  2). 选中哪个radio或不选中哪个radio改变的是checked

         b. 如何: 所以v-model应该绑定在checked属性上:

         <input type="radio" value="1" name="sex" v-model:checked="变量">男
         <input type="radio" value="0" name="sex" v-model:checked="变量">女

         c. 原理:

                1). Model变->View跟着变: v-model会拿变量的新值和当前的radio写死的value值做比较。如果变量的新值==当前radio的value值,则当前radio选中。否则如果变量的新值!=当前radio的value值,则当前radio不选中

                  2). View变->Model跟着变: v-model会将当前选中的radio的value自动更新到变量中。

         d. 示例: 选择性别:

         9_v-model_radio.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="js/vue.js"></script>
</head>
<body>
  <div id="app">
    <!-- 把表单元素写在label里,可以扩大选中区域 -->
    <label><input type="radio" value="1" name="sex" v-model:checked="sex">男</label>
    <label><input type="radio" value="0" name="sex" v-model:checked="sex">女</label>
    <h3>我是{{sex==1?"男生♂":"女生♀"}}</h3>
  </div>
  <script>
    new Vue({
      el:"#app",
      data:{
        sex:1
      }
    })
  </script>
</body>
</html>
<!-- 事到如今呀。。。有些事儿,你也该知道了。孩子大了,瞒不住了。
其实,v-model后的“:value”和“:checkex”都可以省略。v-model很聪明,可以根据自己所在何种元素,自动判断应该绑定哪个属性。
比如,在文本框就自动绑定value属性,在radio就自动绑定checked属性。
虽然可以简写,但是,简写后更看不出原理,所以,一定要先把学习到的这四种不同情况,做熟练,再享受简写带来的便利。虽然简写,但是原理不变。 -->

运行结果: 

​​​

         (2). select:

         a. 特点:

                  1). 先准备好一批写死的option和value值,备选

                  2). 用户每选择一个option,就会将当前选中的option的value值交给整个select的value属性

                  3). 所以,应该将v-model绑定在每次都会被改变的select的value属性上

         b. 如何:

                  <select v-model:value="变量">
                          <option value="值1">文本</option>

                          ... ...

         c. 原理:

                  1). Model变->View跟着变: v-model会用=右边的变量值和select下每个option的value值做比较。哪个option的value值==变量值,这个option就被选中

                  2). View变->Model跟着变: 用户选择了哪个option。select就会把选中的option的value交给select的value。然后v-model就将select的新value,自动更新到=右边的变量中保存

         d. 示例: 选择订单状态:

         10_v-model_select.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="js/vue.js"></script>
</head>
<body>
  <div id="app">
    <select v-model:value="orderStatus">
      <option value="0">未付款</option>
      <option value="10">已付款</option>
      <option value="20">已发货</option>
      <option value="30">已签收</option>
    </select>
    <h3>当前订单状态为: {{orderStatus==0?"未付款":orderStatus==10?"已付款":orderStatus==20?"已发货":"已签收"}}</h3>
  </div>
  <script>
    new Vue({
      el:"#app",
      data:{
        orderStatus:0 //保存当前订单状态,开局是未付款
      }
    })
  </script>
</body>
</html>
<!-- 事到如今呀。。。有些事儿,你也该知道了。孩子大了,瞒不住了。
其实,v-model后的“:value”和“:checkex”都可以省略。v-model很聪明,可以根据自己所在何种元素,自动判断应该绑定哪个属性。
比如,在文本框就自动绑定value属性,在radio就自动绑定checked属性。
虽然可以简写,但是,简写后更看不出原理,所以,一定要先把学习到的这四种不同情况,做熟练,再享受简写带来的便利。虽然简写,但是原理不变。 -->

运行结果:

​​​​​

         (3). checkbox: 单独使用

         对应小程序视频列表: 小程序->在线->VUE->day02 6. 双向绑定 v-model checkbox ...

         a. 特点: 不需要value属性,单纯修改checked属性,就可切换两种状态,所以,v-model应该绑定在checked属性上。且绑定的变量只有两种值: true或false.

         b. 如何: <input type="checkbox" v-model:checked="变量">

                  且变量值为bool值

         c. 原理:

                  1). Model变->View跟着变: 变量值为true,则选中;变量值为false,则未选中。

                  2). View变->Model跟着变: 将当前checkbox的选中状态(checked属性值)自动更新回程序中的变量里。

         d. 示例: 点同意,启用元素; 不同意,禁用元素

         11_v-model_checkbox.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="js/vue.js"></script>
</head>
<body>
  <!--1. 先做界面-->
  <div id="app">
    <!--1.1 找可能发生变化的位置: 
      两个文本框+按钮的disabled只需要一个变量控制即可——是否同意——isAgree
      用户选中checkbox修改isAgree的同意状态-->
    用户名:<input :disabled="isAgree==false"><br/>
    密码:<input type="password"  :disabled="isAgree==false"><br/>
    <input type="checkbox" v-model:checked="isAgree">同意<br/>
    <button  :disabled="isAgree==false">注册</button>
  </div>
  <script>
    new Vue({
      el:"#app",
      data:{
        isAgree:false //保存是否同意的状态,开局,默认不同意。
      }
    })
  </script>
</body>
</html>
<!-- 事到如今呀。。。有些事儿,你也该知道了。孩子大了,瞒不住了。
其实,v-model后的“:value”和“:checkex”都可以省略。v-model很聪明,可以根据自己所在何种元素,自动判断应该绑定哪个属性。
比如,在文本框就自动绑定value属性,在radio就自动绑定checked属性。
虽然可以简写,但是,简写后更看不出原理,所以,一定要先把学习到的这四种不同情况,做熟练,再享受简写带来的便利。虽然简写,但是原理不变。 -->

运行结果: 

​​​​​

11. v-model简写

以上案例中, v-model后的":value"或":checked",都可省略。v-model可自动根据自己所在的元素判断绑定哪种元素。但是,虽然简写,原理是不变的!

         <表单元素 v-model="变量">

💥 扩展:this判断—8种指向

this  8种指向: 判断this,一定不要看定义在哪儿!只看调用时!

➡️ 1. obj.fun()   this->obj

➡️ 2. fun() 或 (function(){ ... })() 或 多数回调函数 或 定时器函数   this->window

➡️ 3. new Fun()   this->new正在创建的新对象

➡️ 4. 类型名.prototype.共有方法=function(){ ... }   this->将来谁调用指谁,同第一种情况

➡️ 5. DOM或jq中事件处理函数中的this->当前正在触发事件的DOM元素对象

                               如果需要使用简化版函数,必须$(this)

➡️ 6. 箭头函数中的this->箭头函数外部作用域中的this

➡️ 7. jQuery.fn.自定义函数=function(){ ... }   this->将来调用这个自定义函数的.前的jQuery子对象,不用再$(this)

➡️ 8. new Vue()中methods中的函数中的this->当前new Vue()对象 

❣️ 总结:知识点提炼

1. MVVM: 界面View+模型Model+视图模型ViewModel

2. Vue绑定原理: 访问器属性+虚拟DOM树

         变量被修改时: 访问器属性发出通知,虚拟DOM树扫描并仅更新受影响的元素

3. 虚拟DOM树优点:

(1). 小: 只包含可能变化的元素。

(2). 遍历查找快

(3). 修改效率高: 只修改受影响的元素。

(4). 避免重复编码: 已封装DOM增删改查代码

4. Vue功能3步:

(1). 先创建增强版的界面:

  a. 整个界面必须包含在一个唯一的父元素下:

    通常是<div id="app">
  b. 可能变化的元素内容用{{自定义变量名}}标记

  c. 触发事件的元素用@click="自定义处理函数名"标记

(2). 再创建new Vue()对象,其中el:指向new Vue()要监控的页面区域

(3). 在new Vue()对象内定义模型对象data和methods

  a.界面所需的所有变量都放在data中

  b.界面所需的所有事件处理函数都放在methods中

5. 总结: 绑定语法+13种指令

(1). 如果元素的内容需要随变量自动变化:  {{}}

(2). 如果元素的属性值需要随变量自动变化:  :

(3). 控制一个元素显示隐藏: v-show //使用display:none隐藏元素

(4). 控制两个元素二选一显示:  v-if  v-else //使用删除元素方式隐藏元素

(5). 多个元素多选一显示: v-if  v-else-if   v-else

(6). 只要反复生成多个相同结构的元素组成列表时: v-for  :key="唯一标识"

强调: 为什么必须加:key="i"?给每个元素副本添加唯一标识。修改数组中某个元素值时,避免重建整个列表,只需要修改一个DOM元素副本即可!提高修改效率。

(7). 只要绑定事件: @  $event

(8). 防止用户短暂看到{{}}: v-cloak和v-text

(9). 只要绑定原始HTML代码片段内容: v-html

(10). 如果元素的内容只在首次加载时绑定一次,之后都不会改变: v-once

         优化: 减少虚拟DOM树中元素个数。

(11). 保护内容中的{{}}不被编译: v-pre

(12). 今后只要想获得表单元素的值或状态: v-model


 【后文传送门】👉  vue动态样式绑定详解_05 


​​​

如果这篇【文章】有帮助到你,希望可以给【青春木鱼】点个👍,创作不易,相比官方的陈述,我更喜欢用【通俗易懂】的文笔去讲解每一个知识点,如果有对【前端技术】感兴趣的小可爱,也欢迎关注❤️❤️❤️青春木鱼❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】💕💕!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

儒雅的烤地瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值