【Vue】数据监视输入绑定

news2025/1/19 3:16:54

hello,我是小索奇,精心制作的Vue系列持续发放,涵盖大量的经验和示例,如有需要,可以收藏哈
本章给大家讲解的是数据监视,前面的章节已经更新完毕,后面的章节持续输出,有任何问题都可以留言或私信哈,一起加油~

数据监视

Vue实现数据监测的核心是通过defineProperty()劫持属性的getter& setter,当我们获取data数据时,底层都是通过调用getter & setter来实现的,在属性读取或修改时可以进行额外操作这实际上将数据对象“代理”了一层,形成所谓的“响应式数据”

具体一点来说哈,在初始化组件时,Vue会遍历data对象的所有属性,使用Object.defineProperty将它们转换成getter/setter这种代理允许Vue追踪依赖,在属性被访问和修改时通知变化(VM中的data就数据代理自_data)

例如我们定义了一个名为message的data属性,Vue会将其转化为

Object.defineProperty(data, 'message', {
  get () {
    // ...进行依赖收集 
  },
  set (newValue) {
    // ...触发更新
  }
})

这样在读取或修改message时,就可以触发getter和setter,从而进行依赖收集和更新触发,把这些直接叫做数据劫持即可

数据劫持就是Vue实现响应式的基石,它可以检测数据变化并触发回调来完成视图更新,使开发者只需要关注数据本身而不需要手动操作DOM

这里为什么提到数据劫持呢?

一句话形容:数据劫持是手段,数据监视是目的(没有数据劫持,就无法精确监视数据变化)

具体往下看,这里划重点,结合下面,不懂再爬上来一下哈

模拟一个小响应系统的工作方式:

<div id="app">
  <!-- 视图渲染 -->
</div>

<script>
// 数据对象  
const data = {
  name: 'John',
  age: 20
};

function reactive(obj) {
// 汇总所有obj形成一个数组并进行遍历
  // 核心响应式转换代码
  Object.keys(obj).forEach(key => {
    
    let value = obj[key];

    const dep = new Set();

    Object.defineProperty(obj, key, {

      get() {
        // 收集依赖
        dep.add(updateView); 
        return value;
      },

      set(newVal) {
        // 更新值
        value = newVal;
        
        // 触发依赖更新
        dep.forEach(fn => fn());
      }

    });

  });

  return obj;
}

// 数据响应式处理
const reactiveData = reactive(data);

// 视图更新函数 
function updateView() {
  // ...渲染视图
}

// 初始化
updateView(); 

// 数据改变时触发视图更新
reactiveData.name = "Bob";
</script>

这个响应式系统,可以自动更新视图

当获取属性值时,收集订阅者;当设置属性值时,通知订阅者更新视图

没有get和set就不会有响应式数据,也不会显示到页面上!(调试页面中的带括号的就证明有,直接定义的没有get、set也不会响应到页面上)

拓展

响应式转换可能不理解?

// 响应式转换
const reactiveData = reactive(data);

reactive函数是用来把普通对象转换成响应式对象的,它接受一个普通对象作为参数,对这个对象的所有属性进行响应式处理,然后返回这个响应式对象

所以这里

const data = {
  name: 'John',
  age: 20
};

是定义一个普通对象data

调用:

const reactiveData = reactive(data);

reactive函数会遍历data对象的所有属性,使用Object.defineProperty()把这些属性转换成getter/setter的形式

这样responsiveData就变成一个响应式对象了,它和data对象具有相同的属性,但多了响应式的功能之后我们使用responsiveData来代替data,就可以实现视图的自动更新

简单来说reactive(data)这一行的作用就是把一个普通对象data转换成响应式对象reactiveData,得到一个可以实现数据监听与视图更新的响应式数据对象

需要注意的是,由于是直接监测属性,所以对象上的层级结构过深时,内部属性的变化不会触发响应这需要完整替换对象或手动设置新值

data: {
  user: {
    name: 'John',
    friend: {
      name: 'Chris' 
    }
  }
}

如果直接这样改friend.name,Vue监测不到(直接修改深层属性无法被监测到,是因为Vue的响应式通过劫持属性的getter和setter来实现的但它只能劫持对象的第一层属性~)

this.user.friend.name = '小索奇'

重要:必须整个替换user对象,或者用Vue.set | this.$set 改friend.name,才会是响应式的数据,才会生效!

// 非响应式
this.user.name = '小索奇'
// 响应式
// Vue.set(target, key, value) | this.$set(target, key, value)
this.$set(this.user.friend, 'name', '小索奇')

数组也一样,记住不能够通过数组的索引值更改(数组本身不具备get、set方法)

this.list[0] = 'A'
// 如果数组下有对象属性,可以更改
this.list[0].name = '小索奇'

要直接调用Vue的全局API来改变数组,如用Vue.set改索引,或者用数组自身push、pop、shift、unshift、splice、sort、reverse、之类的API

  • 这些方法都被Vue做了包装,所以可以进行视图更新

上面的就可以用splice替换

this.list.splice(start, deleteCount, item1)

异步函数里改数据,页面也不会立刻更新,只有等异步函数完了,页面才显示新数据

setTimeout(() => {
  this.message = 'hello'
}, 1000)

所以用定时器、ajax之类的改数据,页面会晚一点才刷新

这就是Vue数据监测需要注意的几个点概括来说就是:

  • 嵌套深的数据要用Vue.set或者整个替换
  • 数组索引要用Vue.set或数组方法改
  • 异步函数里改数据,页面更新会 delay 一下

拓展

Vue.set(target,key,val)

// vm.$set()
Vue.set(vm._data.obj,'country','China')
// 为什么等同于下面的
Vue.set(vm.obj,'country','China')

这是因为数据代理-review

Vue.set 方法可以向响应式对象中添加一个属性并确保这个新属性同样是响应式的

Vue 在初始化时,会将 data 对象代理到 Vue 实例上,所以 vm.obj 等同于访问 vm._data.obj

也就是说,在组件实例 VM 中,访问 vm.obj 等同于访问 vm._data.obj,因为它会被代理到 _data 中的原始数据对象上

这是通过 Vue 的 proxy 方法实现的,大致如下:

function proxy(vm) {
  Object.keys(vm._data).forEach(key => {
    Object.defineProperty(vm, key, {
      get() { 
        return vm._data[key];
      }
    });
  });
}

所以 Vue.set 方法既可以接受原始的 _data 对象,也可以接受代理后的组件实例对象,效果是相同的

它们都指向同一个原始数据对象

注意

  • target不允许是VM实例,也不允许是直接根对象,比如data

image-20230823005727583

表单输入绑定

这里不废话,直接上重点了哈:

如果:<input type="text"/>,则v-model收集的是value值,用户输入的就是value值

如果:<input type="radio"/>,则v-model收集的是value值,且要给标签配置value值

如果:<input type="checkbox"/>

  • 没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)

配置input的value属性:

  1. v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)

  2. v-model的初始值是数组,那么收集的的就是value组成的数组

v-model默认是收集value值,必须要写value,才能够在vue中收集到设置的内容,否则收集默认值(比如checkbox默认为checked-布尔值)

Vue 中对表单元素绑定默认值的常见示例如下:

单选框绑定字符串值

// 不设置value默认读取null
<input type="radio" v-model="picked" value="A">
<script>
data() {
  return {
    picked: 'A'
  }
}  
</script>

复选框绑定布尔值:

// checkbox 必须设置value值,不设置的话默认为checked的状态(布尔值)
// 如果有多组值,需要把绑定的数据设置为数组,
睡觉<input type="checkbox" v-model="hobby" value="sleep">
玩<input type="checkbox" v-model="hobby" value="play">
吃<input type="checkbox" v-model="hobby" value="eat">

<script>
data() {
  hobby:[]
}
</script>

选择框绑定字符串:

<select v-model="selected">
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>

<script>
data() {
  return {
    selected: 'A'
  }  
}  
</script>

文本输入绑定字符串:

<input v-model="message">

<script>
data() {
  return {
    message: ''
  }
}
</script>

此外,还有更多实用的功能等着我们去汲取,例如:

  • 使用计算属性来处理表单输入的值,可以进行一些数据的预处理或者格式化。
  • 使用v-model的修饰符,如.number.trim,可以在需要时对输入进行自动转换或者修饰。

下节继续加油~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1051933.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

孤举者难起,众行者易趋,openGauss 5.1.0版本正式发布!

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

基于SSM的教师办公管理的设计与实现(有报告)。Javaee项目。

演示视频&#xff1a; 基于SSM的教师办公管理的设计与实现&#xff08;有报告&#xff09;。Javaee项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring S…

Selenium Webdriver自动化测试框架

最近正在编写selenium webdriver自动化框架&#xff0c;经过几天的努力&#xff0c;目前基本已经实现了一套即能满足数据驱动、又能满足Web关键字驱动的自动化框架&#xff08;主要基于 antjenkinstestngselenium webdriverjxl实现&#xff09;。通过这次的自动化框架开发&…

[CISCN2019 华北赛区 Day2 Web1]Hack World 布尔注入

正确的值 错误的值 我们首先fuzz一下 发现空格被过滤了 我们首先测试 (1)(1) (1)(2) 确定了是布尔注入了 我们写一下查询语句 (select(ascii(mid(flag,1,1))>1)from(flag))(select(ascii(mid(flag,1,1))102)from(flag)) 确定了f 开头 我们开始写脚本 import string …

喜获殊荣!迅镭激光获评“2023年苏州市质量奖”!

近日&#xff0c;苏州市质量奖评定委员会公示2023年苏州市质量奖评定结果&#xff0c;经过层层严格评审&#xff0c;迅镭激光从众多企业中脱颖而出&#xff0c;成功获评“苏州市质量奖”称号! 苏州市质量奖是苏州市政府设立&#xff0c;授予在经营质量上表现优秀的苏州企业的专…

交换机之间配置手动|静态链路聚合

两台交换机&#xff0c;配置链路聚合&#xff1a; 1、禁止自动协商速率&#xff0c;配置固定速率 int G0/0/1 undo negotiation auto speed 100int G0/0/2 undo negotiation auto speed 100 2、配置eth-trunk int eth-trunk 1 mode manual | lacp-staticint G0/0/1 eth-trun…

notion + nextjs搭建博客

SaaS可以通过博客来获得SEO流量&#xff0c;之前我自己在nextjs上&#xff0c;基于MarkDown Cloudfare来构建博客&#xff0c;很快我就了解到更优雅的方案&#xff1a;notion nextjs搭建博客&#xff0c;之前搭建了过&#xff0c;没有记录&#xff0c;这次刚好又要弄&#xf…

Yolov8-pose关键点检测:模型轻量化创新 | OREPA结合c2f,节省70%的显存!训练速度提高2倍! | CVPR2022

💡💡💡本文解决什么问题:浙大&阿里提出在线卷积重新参数化OREPA,节省70%的显存!训练速度提高2倍! OREPA | GFLOPs从9.6降低至8.2, mAP50从0.921提升至0.931 Yolov8-Pose关键点检测专栏介绍:https://blog.csdn.net/m0_63774211/category_12398833.html ✨✨…

平台登录页面实现(一)

文章目录 一、实现用户名、密码、登录按钮、记住用户表单1、全局css代码定义在asserts/css/global.css 二、用户名、密码、记住用户的双向绑定三、没有用户&#xff0c;点击注册功能实现四、实现输入用户名、密码、点击登录按钮进行登录操作五、实现表单项校验六、提交表单预验…

[python 刷题] 153 Find Minimum in Rotated Sorted Array

[python 刷题] 153 Find Minimum in Rotated Sorted Array 题目&#xff1a; Suppose an array of length n sorted in ascending order is rotated between 1 and n times. For example, the array nums [0,1,2,4,5,6,7] might become: [4,5,6,7,0,1,2] if it was rotated 4…

年度顶级赛事来袭:2023 CCF大数据与计算智能大赛首批赛题上线!

久等了&#xff01; 大数据与人工智能领域年度顶级盛事——2023 CCF大数据与计算智能大赛——首批赛题已上线&#xff0c;大赛火力全开&#xff0c;只等你来挑战&#xff01; 大赛介绍 CCF大数据与计算智能大赛&#xff08;CCF Big Data & Computing Intelligence Contes…

嵌入式Linux应用开发-第十二章设备树的改造

嵌入式Linux应用开发-第十二章设备树的改造 第十二章 LED模板驱动程序的改造&#xff1a;设备树12.1 总结3种写驱动程序的方法12.2 怎么使用设备树写驱动程序12.2.1 设备树节点要与platform_driver能匹配12.2.2 设备树节点指定资源&#xff0c;platform_driver获得资源 12.3 开…

基于vue+Element Table Popover 弹出框内置表格的封装

文章目录 项目场景&#xff1a;实现效果认识组件代码效果分析 封装&#xff1a;代码封装思路页面中使用 项目场景&#xff1a; 在选择数据的时候需要在已选择的数据中对比选择&#xff0c;具体就是点击一个按钮&#xff0c;弹出一个小的弹出框&#xff0c;但不像对话框那样还需…

第79步 时间序列建模实战:支持向量机回归建模

基于WIN10的64位系统演示 一、写在前面 这一期&#xff0c;我们介绍支持向量机&#xff08;SVM&#xff09;回归。 同样&#xff0c;这里使用这个数据&#xff1a; 《PLoS One》2015年一篇题目为《Comparison of Two Hybrid Models for Forecasting the Incidence of Hemor…

Linux shell编程学习笔记4:修改命令行提示符格式(内容和颜色)

一、命令行提示符格式内容因shell类型而异 Linux终端命令行提示符内容格式则因shell的类型而异&#xff0c;例如CoreLinux默认的shell是sh&#xff0c;其命令行提示符为黑底白字&#xff0c;内容为&#xff1a; tcbox:/$ 其中&#xff0c;tc为当前用户名&#xff0c;box为主机…

CSP-J第二轮试题-2021年-1.2题

文章目录 参考&#xff1a;总结 [CSP-J 2021] 分糖果题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 样例 #3样例输入 #3样例输出 #3 提示答案1答案2-优化 [CSP-J 2021] 插入排序题目描述输入格式输出格式样例 #1样例输入 #1样…

趣解设计模式之《小王的披萨店续集》

〇、小故事 在《小王的披萨店》这篇文章中&#xff0c;我们介绍了小王开披萨店的故事&#xff0c;并且为了解决多种口味披萨的扩展问题&#xff0c;引出了简单工厂和工厂方法模式。但是&#xff0c;故事仍在继续&#xff0c;如果芝加哥的披萨店和纽约的披萨店&#xff0c;要求…

T8161B T8403 T8448 ICS TRIPLEX 具有支持物联网边缘的计算机视觉

T8161B T8403 T8448 ICS TRIPLEX 具有支持物联网边缘的计算机视觉 edge Xpert(1.8版)现在提供了一个用于计算机视觉的插件&#xff0c;使用户能够在边缘运行他们的人工智能算法和视觉模型。基于英特尔的OpenVINO工具包&#xff0c;Edge Xpert计算机视觉服务为用户提供了在现…

「大数据-2.2」使用命令操作HDFS文件系统

目录 一、HDFS文件系统基本信息 1. HDFS的路径表达形式 2.HDFS和Linux的根目录的区分 二、 使用命令操作HDFS文件系统 0. Hadoop的两套命令体系 1. 创建文件夹 2. 查看指定目录下内容 3. 上传文件到HDFS指定目录下 4. 查看HDFS文件内容 5. 下载HDFS文件 6. 拷贝HDFS文件 7.…

快速幂算法-python

看了大神讲解&#xff0c;理论在这里&#xff1a;快速幂算法&#xff08;全网最详细地带你从零开始一步一步优化&#xff09;-CSDN博客 例题&#xff1a;求整数 base 的 整数 power 次方&#xff0c;对整数 num_mod 取幂。 python 代码如下&#xff1a; import timedef norm…