47 vue 常见的几种模型视图不同步的问题

news2024/11/29 2:54:19

前言

这里主要是来看一下 关于 vue 中的一些场景下面 可能会出现 模型和视图 不同步更新的情况

然后 这种情况主要是 vue 中的对象 属性没有响应式的 setter, getter

然后 我们这里就来看一下 大多数的情况下的一个场景, 和一些处理方式

当然 处理方式主要是基于 Vue.set, this.$set 之类, 这里不 着重介绍, 也可以使用 this.$forceUpdate 来强行渲染 

 

当然前面 出现过一些特殊场景下的 模型视图不同步 的问题, 之前的问题如下, 我们这里 主要是列举一下 常见的一些情况 

el-dialog 的 appendToBody 属性, 导致 vue 响应式失效

el-tree defaultCheckedKeys配置 和 树上面选中节点不同步问题

特定的操作之后响应式对象不“响应“了(一)

特定的操作之后响应式对象不“响应“了(二)

直接使用 dom api 更新了 #text节点, 之后响应式更新不生效了

 

 

data本身的手动配置的属性

样例代码如下

 <template>
   <div>
     <div v-if="message" >
       <span> {{message}} </span>
     </div>
     <div v-else > else </div>
   </div>
</template>

<script>
export default {
  data() {
    return {
      message: ""
    }
  },
  mounted() {
    let _this = this
    setTimeout(function() {
      _this.message = "this is message"
      // new field by VueComponent
      _this.field01 = "xx"
      console.log(_this.message)
    }, 5000)
  },
  methods: {

  }
}
</script>

 

当然 其实可以直接基于 this.data 的 message属性 和 field01属性

直接注册在 data 下面的 message 是一直都是响应式的, 但是通过 this.field01 设置的属性 Vue 这边是感知不到的, 是没有响应式的

从实际的 this 的相关属性来看 this 外层的 message 是有响应式的 getter, setter 的, 然后 field01 没有

this._data 也是只有 message 属性, 没有 field01 属性的

通过 this.field01 属性没有响应式的 setter, getter 就可以判断出 field01 是不会响应式更新的

4261233d1e3a4d22b55bf44a836304c2.png

 

 

data下面的对象的手动配置的属性

样例代码如下

 <template>
   <div> this is test </div>
</template>

<script>
export default {
  data() {
    return {
      info : {
        message: "xx",
        field02: "field02",
      }
    }
  },
  mounted() {
    let _this = this
    // case1. new field by update by attribute
    setTimeout(function() {
      _this.info.message = "this is message"
      // new field by VueComponent
      _this.info.field02 = "field02"
      _this.info.field03 = "field03"
      console.log(_this.info)
    }, 5000)

    // case1. update _this.info by new object 
    setTimeout(function() {
      _this.info = {
        message : "this is message2",
        field01 : "field01 updated",
        field02 : "field02 updated",
      }
      console.log(_this.info)
    }, 10000)
  },
  methods: {

  }
}
</script>

 

然后 这里有两个 case, 我们这依次来看一下

第一个是通过 this.info.field03在 this.info 中增加了两个字段, message, field02 是已有的字段

大概的规则是直接通过 this.info.xx 增加的这部分字段是没有响应式的 setter, getter 的, 我们来看一下 情况

从下面可以看到 确实如此

3caa7cec569d427f862cf62c2c22bafa.png

 

然后直接设置 this.info 对象, 其所有的属性都是有 响应式的 setter, getter 的

这个其中的区别大概是 this.info 是 Object, 而没有添加响应式的 setter, getter 的是基础的数据类型吧

然后 从结果来看 也是确实如此

64c5a35c3b184b88a0ceb704c88593b5.png

 

 

数组的手动配置的属性

样例代码如下

 <template>
  <div>
    <div v-for="(item, index) in planConfigs" :key="index" class="detail-box">
      <div class="detail-title">
        <div>
          <el-button type="primary" @click="handleClick(item)">
            收起
          </el-button>
        </div>
      </div>
      <el-collapse-transition>
        <div v-show="item.packUp" >
          <div>内容 {{item.name}} </div>
        </div>
      </el-collapse-transition>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      planConfigs: [
      ]
    }
  },
  mounted() {
    // case1. push an empty object, then update by attribute
    this.planConfigs.push({})
    this.planConfigs[0].name = "name"
    this.planConfigs[0].code = "code"

    // case2. push an attribute setten object
    this.planConfigs.push({
      name: "name2",
      age: "age",
      packUp: true
    })

    // case3. push an object, then reset object by array index
    this.planConfigs.push({
      name: "name2",
      age: "age",
      packUp: true
    })
    this.planConfigs[2] = {
      field01: "field01",
      field02: "field02",
      packUp: true
    }

    // case4. push an object, then reset object by splice
    this.planConfigs.push({
      name: "name2",
      age: "age",
      packUp: true
    })
    this.planConfigs.splice(3, 1, {
      field01: "field01",
      field02: "field02",
      packUp: true
    })

    this.planConfigs.forEach(ele => {
      ele.packUp = true
    })
    console.log(this.planConfigs)
  },
  methods: {
    handleClick(item) {
      item.packUp = !item.packUp
      // this.$forceUpdate()
      console.log(item)
    }
  }
}
</script>

 

这里有四个 case, 这几个 都有大大小小的不同, 也会产生一些不同的差异

第一个是往数组里面添加了一个空对象, 然后外层通过 属性配置增加字段

第二个是往数组里面添加对象, 待添加的对象本身就已经设置好了属性

第三个是往数组里面添加了设置好的对象, 然后之后通过 索引直接更新的对象

第四个是往数组里面添加了设置好的对象, 然后之后通过 splice更新的对象

 

我们这里来看一下 这里的四种情况, 每一个对象的响应式的 setter, getter 是不一样的

5fddb7b00a79409cb288505b4e3b8c8e.png

 

case1, code, name, pickUp 都是通过 item.xx 配置的属性, 然后这些属性都是没有响应式的 setter, getter 的

155d183a18b242308a29de2f4e9c918f.png

 

case2, code, name, pickUp 是在 push 之前就添加好的, 然后都有响应式的 setter, getter

d201f1e1a3864cf9b7edc016784fc2d3.png

 

case3, code, name, pickUp 是在 push 之前就添加好的 但是后面通过了 索引重置了对象

field01, field02 都是没有响应式的 setter, getter

84592a95c07e42768c0188f11cf92067.png

 

case4, code, name, pickUp 是在 push 之前就添加好的, 然后后面更新元素是通过 数组的 splice 函数来进行更新的

field01, field02, pickUp 都是有响应式 setter, getter 的

fea5b3028389416a99a75d957308ef88.png

 

 

响应式 setter, getter 的总结

综上, 可以总结出来的规则是 如果目标是对象, 通过 obj.fieldXXX 来添加的字段 是没有响应式的 setter, getter 的

但是通过 obj = newObj 的方式来进行更新 obj 整个对象, obj 整个对象都是响应式的

对于对象 增加响应式的属性的方法是 Vue.set 或者 this.$set

 

如果目标是 数组, 通过 push, splice 增加元素, 该元素是响应式的

如果通过 array[index] = newObj 来更新元素, array[index] 不是响应式的

如果通过 array[index].fieldXXX 来添加字段, 该元素的 fieldXXX 字段不是响应式的

 

 

 

 

完 

 

 

 

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

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

相关文章

53 v-bind 和 v-model 的实现和区别

前言 这个主要的来源是 偶尔的情况下 出现的问题 就比如是 el-select 中选择组件之后, 视图不回显, 然后 model 不更新等等 这个 其实就是 vue 中 视图 -> 模型 的数据同步, 我们通常意义上的处理一般是通过 模型 -> 数据 的数据同步, 比如 我们代码里面更新了 model.…

正多边形拓扑与泛函

&#xff08;原创&#xff1a;Daode3056&#xff09; 也许&#xff0c;关于“拓扑”&#xff0c;“泛函”几本书上的内容与实例都是大同小异&#xff0c;总是那么点内容&#xff0c;数学要开拓一些新领域与新内容才能满足不断发展的社会与工业各种需要。本文就以人工智能生成对…

鸿蒙OS开发实例:【ArkTS 实现MQTT协议】

介绍 MQTT是物联网中的一种协议&#xff0c;在HarmonyOS API9平台&#xff0c;解决方案以C库移植为实现方案。 遥遥领先的平台&#xff0c;使用MQTT怎能不遥遥领先呢&#xff01; 新年快乐&#xff0c;本篇将带领你手把手实现HarmonyOS ArkTS语言的MQTT协议。 准备 阅读…

阿里云通用算力型u1云服务器配置性能评测及价格参考

阿里云服务器u1是通用算力型云服务器&#xff0c;CPU采用2.5 GHz主频的Intel(R) Xeon(R) Platinum处理器&#xff0c;ECS通用算力型u1云服务器不适用于游戏和高频交易等需要极致性能的应用场景及对业务性能一致性有强诉求的应用场景(比如业务HA场景主备机需要性能一致)&#xf…

如何使用极狐GitLab 自定义 Pages 根域名

本文作者&#xff1a;徐晓伟 GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 本文主要讲述了极狐GitLab Pages …

JS实现正则匹配文本中的URL地址

如何利用JS正则表达式&#xff0c;提取文本中的URL地址呢&#xff1f; 目录 一、程序代码 二、运行结果 一、程序代码 function extractUrls(text) {var urlRegex /(https?:\/\/[^\s])/g;return text.match(urlRegex); }var text "3.02 复制打开抖音&#xff0c;看…

YOLOV8逐步分解(3)_trainer训练之模型加载

yolov8逐步分解(1)--默认参数&超参配置文件加载 yolov8逐步分解(2)_DetectionTrainer类初始化过程 接上2篇文章&#xff0c;继续讲解yolov8训练过程中的模型加载过程。 使用默认参数完成训练器trainer的初始化后&#xff0c;执行训练函数train()开始YOLOV8的训练。 1. t…

SaaS 电商设计 (十) 记一次 5000kw 商品数据ES迁移 (详细的集群搭建以及线上灰度过程设计)

目录 一.背景二.技术目标三.技术方案3.1 整体流程3.2 ES 切换前:完成整体新集群的搭建.i:拓扑结构设计ii: 如何选择整体的 **ES** 集群配置. 3.3 **ES** 版本切换中3.3.1 多client版本兼容3.3.2 Router的设计 3.4 ES 切换后3.5 开箱即用 四.总结 专栏系列 -SaaS 电商设计 (一) …

每日面经分享(pytest装饰器)

pytest装饰器 a. pytest.mark.parametrize&#xff1a;这个装饰器用于标记测试函数&#xff0c;并为其提供多组参数进行参数化测试。可以使用元组、列表、字典等形式来指定参数组合。 import pytestpytest.mark.parametrize("num1, num2, expected", [(2, 2, 4), (5…

2024 3.23~3.29周报

上周工作 SVInvNet论文研读 本周计划 加入DenseNet&#xff0c;修改网络架构&#xff0c;跑代码 总结 DenseNet 密集块&#xff1a;DenseNet将网络分成多个密集块&#xff08;Dense Block)。在每个密集块内&#xff0c;每一层都连接到前面所有的层。这种跳跃连接有助于解…

【Laravel】07 快速套用一个网站模板

【Laravel】07 快速套用一个网站模板 1. 新增post表2.补充 &#xff1a;生成Model、Controller、迁移文件3. 使用php artisan tinker4. 网站模板下载 课程地址 1. 新增post表 在Model中创建Post (base) ➜ example-app php artisan make:model Post Model created successfu…

手机有线投屏到直播姬pc端教程

1 打开哔哩哔哩直播姬客户端并登录(按下图进行操作) 2 手机用usb数据线连接电脑(若跳出安装驱动的弹窗点击确定或允许),usb的连接方式为仅充电(手机差异要求为仅充电),不同品牌手机要求可能不一样,根据实际的来 3 在投屏过程中不要更改usb的连接方式(不然电脑会死机需要重启) …

verilog中的testbench语句——display,fopen,fread,fwrite——更新中

一、fopen bmp_file_read $fopen("../pic/picture.bmp","rb"); 要注意这类操作文件的函数&#xff0c;在vivado2018自带的仿真软件里&#xff0c;不综合直接仿真&#xff0c;它的当前文件夹如图所示。 一、fwrite $fwrite(bmp_file_write,"%c"…

LeetCode - 岛屿数量

200. 岛屿数量 第一种写法&#xff1a;遍历岛屿&#xff0c;当遇到岛屿的时候&#xff0c;就开始进行深搜&#xff0c;遇到岛屿就将岛屿从1变为0。 class Solution { public:int dx[4] {0,0,1,-1};int dy[4] {1,-1,0,0};void dfs(int i, int j, vector<vector<char>…

【第十二届“泰迪杯”数据挖掘挑战赛】【2024泰迪杯】B题基于多模态特征融合的图像文本检索—解题全流程(论文更新)

【第十二届“泰迪杯”数据挖掘挑战赛】【2024泰迪杯】B题基于多模态特征融合的图像文本检索更新&#xff08;论文更新&#xff09; ​ 本节主要更新了论文、训练日志的log数据提取&#xff08;Loss、ACC、RK&#xff09;等数据可视化作图的代码 B题交流QQ群&#xff1a; 4583…

C#调用FreeSpire.Office读取word数据的基本用法

FreeSpire.Office是Spire.Office的免费版本&#xff0c;后者支持全面、复杂的office文件操作功能&#xff0c;包括文件格式转换、文档操作、文档打印等&#xff0c;详细介绍见下图及参考文献1。本文学习FreeSpire.Office的基本用法并用其获取word文档的基本信息。   新建Win…

JavaScript动态渲染页面爬取——Splash的使用

JavaScript动态渲染页面爬取 JavaScript动态渲染得页面不止Ajax一种。例如&#xff0c;有些页面的分页部分由JavaScript生成&#xff0c;而非原始HTML代码&#xff0c;这其中并不包含Ajax请求。还有类似淘宝这种页面&#xff0c;即使是Ajax获取的数据&#xff0c;其Ajax接口中…

Unix中的进程和线程-1

目录 1.如何创建一个进程 2.如何终止进程 2.2遗言函数 3.进程资源的回收 4.孤儿进程和僵尸进程 孤儿进程 (Orphan Process)&#xff1a; 僵尸进程 (Zombie Process)&#xff1a; 代码示例&#xff1a; 5. 进程映像的更新 在Linux中&#xff0c;进程和线程是操作系统进行工作调…

【Docker笔记02】【常用软件安装】

一、前言 本系列是根据 B 站 尚硅谷 Docker 视频 学习记录笔记。因为没有视频课件&#xff0c;部分内容摘自 https://www.yuque.com/tmfl/cloud/dketq0。 本系列仅为自身学习笔记记录使用&#xff0c;记录存在偏差&#xff0c;推荐阅读原视频内容或本文参考笔记。 本文主要介…

Adobe ColdFusion 任意文件读取漏洞复现(CVE-2024-20767)

0x01 产品简介 Adobe ColdFusion是美国奥多比(Adobe)公司的一套快速应用程序开发平台。该平台包括集成开发环境和脚本语言,将可扩展、改变游戏规则且可靠的产品的愿景变为现实。 0x02 漏洞概述 由于 Adobe ColdFusion 的访问控制不当,未经身份认证的远程攻击者可以构造恶…