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()内容请搜索编程宝库以前的文章,希望以后支持编程宝库

前言以Element Plus 为例,配置按需加载组件和样式。环境 vue3.0.5 vite2.3.3安装 Element Plusyarn add element-plus# ORnpm ins ...