Vue.set()和this.$set()使用和区别

在我们使用vue进行开发的过程中,可能会遇到一种情况:当生成vue实例后,当再次给数据赋值时,有时候并不会自动更新到视图上去; 当我们去看vue文档的时候,会发现有这么一句话:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。 如下代码,给 student对象新增 age 属性

data () {
  return {
    student: {
      name: '',
      sex: ''
    }
  }
}
mounted () { // ——钩子函数,实例挂载之后
  this.student.age = 24
}

受 ES5 的限制,Vue.js 不能检测到对象属性的添加或删除。因为 Vue.js 在初始化实例时将属性转为 getter/setter,所以属性必须在 data 对象上才能让 Vue.js 转换它,才能让它是响应的。

正确写法:this.$set(this.data,”key”,value')

mounted () {
  this.$set(this.student,"age", 24)
}

:: Vue 不允许动态添加根级响应式属性。

例如:

const app = new Vue({
  data: {
    a: 1
  }
  // render: h => h(Suduko)
}).$mount('#app1')

Vue.set(app.data, 'b', 2)

只可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性,例如

var vm=new Vue({
    el:'#test',
    data:{
        //data中已经存在info根属性
        info:{
            name:'小明';
        }
    }
});
//给info添加一个性别属性
Vue.set(vm.info,'sex','男');

Vue.set()和this.$set()实现原理

我们先来看看Vue.set()的源码:

import { set } from '../observer/index'

...
Vue.set = set
...

再来看看this.$set()的源码:

import { set } from '../observer/index'

...
Vue.prototype.$set = set
...

结果我们发现Vue.set()和this.$set()这两个api的实现原理基本一模一样,都是使用了set函数。set函数是从 ../observer/index 文件中导出的,区别在于Vue.set()是将set函数绑定在Vue构造函数上,this.$set()是将set函数绑定在Vue原型上。

function set (target: Array<any> | Object, key: any, val: any): any {
  if (process.env.NODE_ENV !== 'production' &&
    (isUndef(target) || isPrimitive(target))
  ) {
    warn(`Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`)
  }
  if (Array.isArray(target) && isValidArrayIndex(key)) {
    target.length = Math.max(target.length, key)
    target.splice(key, 1, val)
    return val
  }
  if (key in target && !(key in Object.prototype)) {
    target[key] = val
    return val
  }
  const ob = (target: any).__ob__
  if (target._isVue || (ob && ob.vmCount)) {
    process.env.NODE_ENV !== 'production' && warn(
      'Avoid adding reactive properties to a Vue instance or its root $data ' +
      'at runtime - declare it upfront in the data option.'
    )
    return val
  }
  if (!ob) {
    target[key] = val
    return val
  }
  defineReactive(ob.value, key, val)
  ob.dep.notify()
  return val
}

我们发现set函数接收三个参数分别为 target、key、val,其中target的值为数组或者对象,这正好和官网给出的调用Vue.set()方法时传入的参数参数对应上。

参考:

vue中遇到的坑 --- 变化检测问题(数组相关)

到此这篇关于Vue.set()和this.$set()使用和区别的文章就介绍到这了,更多相关Vue.set()和this.$set()内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 从vue源码解析Vue.set()和this.$set()

    前言 最近死磕了一段时间vue源码,想想觉得还是要输出点东西,我们先来从Vue提供的Vue.set()和this.$set()这两个api看看它内部是怎么实现的. Vue.set()和this.$set()应用的场景 平时做项目的时候难免不会对 数组或者对象 进行这样的骚操作操作,结果发现,咦~~,他喵的,怎么页面没有重新渲染. const vueInstance = new Vue({ data: { arr: [1, 2], obj1: { a: 3 } } }); vueInstance.

  • Vue.set() this.$set()引发的视图更新思考及注意事项

    引文 vue文档列表渲染中有条注意事项: 这里提到的两种情况实际改变了数据但是没有触发视图更新. 由此引出Vue.set(),先上文档API:   this.$set()和Vue.set()本质方法一样,前者可以用在methods中使用. set方法调用时,可以触发页面全部重新渲染. 比如在vue中有个data数组arr: //arr=[1,2,3] arr[1]='b' console.log(arr) // [1,2,3] Vue.set(arr,2,'c') console.log(arr

  • Vue路由钩子之afterEach beforeEach的区别详解

    vue-router作为vue里面最基础的服务,学习一段时间,对遇到的需求进行一些总结 使用vue-cli作为开发前提 vue-router已经配置好了 路由写法 routes: [ { path: '/cart', name: 'cart', component: cart, meta :{ title: "购物车"} //用于给定网页名 } ] vue-router 的路由跳转的方法 第一种 : 编程式的导航 <router-link to="/" tag

  • 深入浅析Vue全局组件与局部组件的区别

    1.组件声明 <!-- 全局组件模板father模板 --> <template id="father"> <div> <h3>这是{{name}}</h1> <div> <p>这是{{data}}</p> </div> </div> </template> var FATHER = { template: "#father", dat

  • 基于Vue全局组件与局部组件的区别说明

    1.组件声明 <!-- 全局组件模板father模板 --> <template id="father"> <div> <h3>这是{{name}}</h1> <div> <p>这是{{data}}</p> </div> </div> </template> var FATHER = { template: "#father", dat

  • vue渲染方式render和template的区别

    render函数详解 Vue中的Render函数中有一个参数,这个参数是一个函数通常我们叫做h.其实这个h叫做createElement.Render函数将createElement的返回值放到了HTML中 createElement这个函数中有3个参数 第一个参数(必要参数):主要用于提供DOM的html内容,类型可以是字符串.对象或函数 第二个参数(类型是对象,可选):用于设置这个DOM的一些样式.属性.传的组件的参数.绑定事件之类 第三个参数(类型是数组,数组元素类型是VNode,可选):

  • Vue中computed和watch有哪些区别

    计算属性computed: 支持缓存,只有依赖数据发生改变,才会重新进行计算 不支持异步,当computed内有异步操作时无效,无法监听数据的变化 computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed 如果computed属性属性值是函数,那么默认会走get方法:函数的返回值就是属性的属性

  • Vue.set()和this.$set()使用和区别

    在我们使用vue进行开发的过程中,可能会遇到一种情况:当生成vue实例后,当再次给数据赋值时,有时候并不会自动更新到视图上去: 当我们去看vue文档的时候,会发现有这么一句话:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新. 如下代码,给 student对象新增 age 属性 data () { return { student: { name: '', sex: '' } } } mounted () { // --钩子函数,实例挂载之后 this.student.age = 24

  • vue插值表达式和v-text指令的区别

    目录 1.使用插件表达式 2.在插件表达式中使用v-cloak解决闪烁问题 3.插件表达式 {{message}} 语法只能在标签内容中使用 {{}}这种语法叫做插值表达式,在插值表达式中可以写任何合法的js表达式 1.使用插件表达式 使用插件表达式,存在内容闪烁问题,但是v-text没有闪烁问题 <div id="app"> <p> {{message}} </p> <p v-text="message"></

  • vue $attrs和$listeners的使用与区别

    首先让我们看一下这张图,表示了一个多级关联的组件嵌套 为什么要用$attrs 和 $listeners 先让我们来想一种情况,就是组件A跟组件C怎么通信,我们可以有多少中解决方案? 看到这种情况,大多数人应该会想到用vuex来进行数据通信吧,但是如果项目中多个组件中的共享状态很少,且项目比较小,全局数据通信也很少,那我们用vuex来实现这个功能,就感觉有点杀鸡用牛刀了 我们可以使用组件B来做通信的中转站,当组件A需要把数据传到组件C时,组件A通过props将数据传给组件B,然后组件B再用prop

  • Vue中监视属性和计算属性区别解析

    目录 计算属性 需求 使用watch实现 准备工作 测试 测试 在computed当中书写 总结 计算属性 顾名思义,计算属性就是计算出来的属性,英文名儿computed这里要和data和methods里的东西区分,data里的属性,methods里的函数,你写的都会原封不动放到vm里,但是computed里面的东西写的是对象,最后放到vm里的是这个对象的名,值是get里的返回值. 下面看下Vue中监视属性和计算属性区别. 需求 我们将计算属性的案例使用watch写一遍 需求一揽 两个输入框 下

  • Vue 中的 computed 和 watch 的区别详解

    目录 computed 注意 应用场景 watch 总结 computed computed 看上去是方法,但是实际上是计算属性,它会根据你所依赖的数据动态显示新的计算结果.计算结果会被缓存,computed 的值在 getter 执行后是会缓存的,只有在它依赖的属性值改变之后,下一次获取 computed 的值时才会重新调用对应的 getter 来计算. 1)下面是一个比较经典简单的案例 <template> <div class="hello"> {{ful

随机推荐