this.$set的正确使用

this.#set(obj, key, value)

我们在项目开发的过程中,经常会遇到这种情况:为data中的某一个对象添加一个属性

<template>
  <div class="hello">
    <button @click="setMessage">添加属性</button>
    {{ student.name }}
    <input type="text" v-model="student.age">
  </div>
</template>
<script>
export default {
  data() {
    return {
      student: {
        name: '张三',
      }
    }
  },
  methods: {
    setMessage() {
      this.student.age = 15
      console.log(this.student)
    }
  }
}
</script>

当我们点击按钮,为student添加一个age属性,看看视图层是否能够更新

在这里插入图片描述

 

在这里我们发现虽然这个对象身上已经有了该属性,但是视图层并没有更新该数据,是什么造成的呢?由于受JavaScript的限制,vue.js不能监听对象属性的添加和删除,因为在vue组件初始化的过程中,会调用getter和setter方法,所以该属性必须是存在在data中,视图层才会响应该数据的变化

那么,我们该如何解决这个问题呢
解决这个问题的方法大体有两种:使用this.$set(obj, key, value)/vue.set(obj, key, value)

调用方法:this.$set( target, key, value )
target:要更改的数据源(可以是对象或者数组)   // 表示数据源,即是你要操作的数组或者对象
key:要更改的具体数据  //要操作的的字段
value :重新赋的值  //更改的数据

小案例:

给一个对象添加一个年龄属性并且让它可以响应式的进行改变

<template>
  <div class="text">
      <p>{{list}}</p>
      <button @click="add">age++</button>
  </div>
</template>
<script>
export default {
    data(){
        return {
            list:{ name: "张三"}
        }
    },
    methods: {
        add(){
            if(!this.list.age){ // 如果没有age属性就给它添加一个age属性
                this.list.age=18
            }else{
                this.list.age++
            }
            console.log(this.list)
        }
    }
}
</script>

当我们没有使用this.$set去添加对象属性的时候,效果:

数据确实已经添加进去了,但是页面并没有响应式的渲染age属性。

当我们使用this.$set(this.list,‘age',18)去添加一个属性之后。效果:

我们能看见添加的数据是响应式的。

为什么能够响应式?

仔细观察一下,使用了this.$set 多了get age和set age方法,这正是能够响应式的原因

分析

Vue的响应式原理为 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter。这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。这里需要注意的是不同浏览器在控制台打印数据对象时对 getter/setter 的格式化并不同,下图来自官方文档。

通过Object.assign(target, sources)方法

<script>
export default {
  data() {
    return {
      student: {
        name: '张三',
      }
    }
  },
  methods: {
    setMessage() {
      this.student.age = 15
      this.student = Object.assign({}, this.student)
      console.log(this.student)
    }
  }
}
</script>

我们发现,通过这两种方式为对象添加属性之后,他的对象身上多了get和set方法,所以,此时我们再次操作该属性的时候,就会引起视图的更新啦
在这里插入图片描述

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java程序设计 课程设计报告 设计题目:电子日历设计 班级: 学号: 姓名: 1. 需求分析 设计并实现一个电子日历,当用户在下拉列表中选择年份后,显示某年各个月的日 历。 2. 概要设计 本程序要求实现在点击按钮以及在下拉菜单中进行点击选择时日历页面以及日期信 息行能够正确显示当前选择的日期,所以在源程序中应该在点击按钮时产生ActionEven t事件,修改当前显示日期以及显示当月日历;在菜单中选择年份时能够产生ItemEvent 事件,使得日历直接跳转到所选年份。 3. 详细设计 源程序分为三部分,主程序部分 CalendarMainClass,日历实现部分 CalendarClass, 页面实现部分 CalendarFrame。 主程序CalendarMainClass 声明并创建一个页面实现部分CalendarFrame类的对象,使用 setBounds() 方法设置初始位置以及窗口大小;使用setTitle() 方法设置窗口标题;使用setLocationRelativeTo()方法设置窗口居中显示:使用setVi sible()以及 setDefaultCloseOperation() 方法设置窗口可见和单击窗体右上角的关闭图标后程序会做出怎样的处理。 日历实现部分 CalendarClass 首先创建一个长度为42的字符串数组,用来存放日期;其后判断所选月份的长短, 并存入数组中。 页面实现部分 CalendarFrame 窗口页面的布局设计如下:新建一个JPanel面板 panel,将其设置为 BorderLayout布局,放置于窗口的NORTH区,将按钮上月previousMonth ,按钮下月nextMonth 放置在JPanel的对象pNorth中,并将菜单组件list和pNorth分别放置在panel的NORTH区 ,SOUTH区;新建一个JPanel面板pCenter,将pCenter设置为7行7列的GridLayout布局, 将星期组件和日期组件添加入pCenture中,把pCenture添加入一个ScrollPane的对象sc rollPane当中,将scrollPane放置在窗口的CENTER区;将日期信息组件showMessage 添加入JPanel的对象pSouth中,并将pSouth放置在窗口的SOUTH区。 为按钮上月previousMonth ,按钮下月nextMonth以及下拉菜单设置监视器,重写public void actionPerformed (ActionEvent e),public void itemStateChanged (ItemEvent e)方法,使得在进行相应操作时能够产生相应的时间。 页面实现部分 CalendarFrame 的图形化显示 4. 程序代码 import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.Calendar; public class CalendarMainClass { public static void main(String args[]) { CalendarFrame frame =new CalendarFrame(); frame.setBounds(0,0,800,550); frame.setTitle("Calendar"); frame.setLocationRelativeTo(null); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } class CalendarClass { String day[]; int year=2010,month=0; public void setYear(int year) { this.year=year; } public int getYear() { return year; } public void setMonth(int month) { this.month=month; } public int getMonth() { return month; } public String[] getCalendar() { String a[]=new String[42]; Calendar date=Calendar.getInstance(); date.set(year,month-1,1); int week=date.get(Calendar.DAY_OF_WEEK)-1; int day=0; if(month==1"
this.$set()是Vue.js提供的一个方法,用于在Vue实例中改变数组或对象的值,并且能够驱动视图的更新。这个方法的语法是this.$set(object, key, value),其中object是要改变的数组或对象,key是要改变的属性名或索引,value是要设置的新值。通过调用this.$set()方法,Vue会在内部使用一些技巧来触发视图的重新渲染,确保更新后的数据能够正确地显示在界面上。 举个例子,如果你有一个数组arr,想要改变其中某个索引的值,并且让v-for指令更新对应的视图,你可以使用this.$set()方法来实现。比如,假设你要将数组arr中的第一个元素改为新的值newValue,你可以这样写代码:this.$set(arr, 0, newValue)。这样,Vue会自动更新视图,显示新的值。 此外,如果你想在Vue组件的方法中使用this.$set(),需要确保该方法是在Vue实例中定义的,并且要传入正确的作用域scope。例如,在beginEdit方法中使用this.$set()来改变数组arr的某个索引的值,可以这样写代码:this.$set(this.arr, scope.$index, true)。这样就可以将指定索引位置的值设置为true,并且能够触发视图的更新。 总之,使用this.$set()可以在Vue中改变数组或对象的值,并且能够自动更新视图,保证界面显示的数据与实际数据同步。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [this.$set的用法](https://blog.csdn.net/m0_59006402/article/details/119918110)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值