您的位置:

uniapp$set详解

在Uniapp中,uniapp$set是一个非常重要的API。本文将从不同的角度对其进行详细的讲解,帮助读者更好地理解uniapp$set的功能和使用方法。

一、uniapp$set的基本语法

uniapp.$set(obj, key, value)

uniapp.$set是Vue.js中一个非常重要的工具函数,它主要用于改变Vue.js中响应式数据的值。uniapp.$set和Vue.set的语法完全一致,而Vue.set是Vue.js中的全局函数。

参数解释:

  • obj:要修改的响应式对象;
  • key:要修改的对象属性名称;
  • value:要设置的新值。

下面我们通过一个示例来展示uniapp$set函数的使用方法:

// 页面data中data对象
data: {
  userInfo: {
    name: '张三',
    age: 20,
    sex: '男'
  }
}

// 调用uniapp.$set修改响应式数据
uniapp.$set(this.userInfo, 'name', '李四');

上述代码就是使用uniapp.$set修改userInfo对象中的name属性值。

二、uniapp$set函数的使用场景

uniapp.$set主要用于解决Vue.js中对响应式数据的新增和删除操作无法触发视图更新的问题。为了更好地理解这个场景,我们可以通过下面一个例子来加深印象:

假设现在我们有一个数据列表,我们通过点击按钮的方式添加和删除数据。我们首先定义一个list数组:

data(){
  return{
    list:[]
  }
}

接下来我们定义一个add方法,每次调用它都会向list数组中添加一个新的对象:

add(){
  this.list.push({
    name:'张三',
    age:20,
    sex:'男'
  })
}

我们再定义一个remove方法,每次调用它都会删除list数组中的最后一个元素:

remove(){
  this.list.splice(this.list.length-1,1)
}

如果我们直接使用push和splice方法来添加和删除数据,问题就会出现了:每当我们添加或删除一条数据时,视图并不会立即更新,因为Vue.js几乎无法对数据新增或删除操作做出反应。

那么我们可以利用uniapp.$set函数来解决这个问题。每当我们添加一条数据时,调用uniapp.$set函数来改变数组的值:

add() {
  this.$set(this.list, this.list.length, {
    name: '张三',
    age: 20,
    sex: '男'
  })
}

接下来我们来改造一下remove方法,使用$set方法来删除list数组中的最后一个元素:

remove(){
  this.$set(this.list,this.list.length-1,null)
  this.list.pop()
}

这样我们就可以使用uniapp.$set来添加和删除数据,使得数据的变化能够及时地反映在视图中。

三、uniapp$set的底层实现原理

uniapp.$set背后的原理非常简单,它主要是利用Vue.js的Object.defineProperty方法来监测数据的变化。当我们利用uniapp.$set函数来改变数据时,Vue.js会自动调用Object.defineProperty方法来监测数据变化,从而触发视图更新。

下面我们来看一下uniapp.$set背后的实现原理:

export function $set(target: any, key: string | number, val: any): any {
  if (Array.isArray(target) && isValidArrayIndex(key)) {
    target.length = Math.max(target.length, key)
    // 利用 splice 方法来触发视图更新
    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)) {
    // 防止修改 Vue 实例或其 $data 对象
    return val
  }
  if (!ob) {
    target[key] = val
    return val
  }
  defineReactive(ob.value, key, val)
  ob.dep.notify()
  return val
}

从上面的代码中可以看出,如果target是一个数组,那么之所以使用splice方法来触发视图更新,是因为Vue.js能够监听到数组下标的变化,而使用splice方法能够触发数组下标的变化。如果target是一个对象且key是该对象的已有属性,那么直接将val赋值给该属性即可。如果key是该对象的新属性,那么使用defineReactive函数来监测这个新属性的变化。

四、uniapp$set的优缺点

uniapp.$set函数的主要优点在于它能够监听对象属性和数组下标的变化,从而让Vue.js能够及时地更新视图。同时,它还可以监听新属性的添加和删除,这样我们就不必在Vue.js初始化的时候就把所有的属性都定义好。

不过,uniapp.$set函数也有它的缺点。比如,调用该函数的代价比直接操作数据高得多。因为我们本来应该直接操作数据的,但是现在却要使用该函数来操作数据,这样会造成额外的开销,从而降低程序的执行效率。

五、总结

本文详细讲解了uniapp.$set函数的使用方法、使用场景、底层实现原理和优缺点。只有深入了解uniapp.$set函数,我们才能更好地使用它,从而让我们的程序更加高效、稳定和易于维护。