В процессе использования vue для разработки мы можем столкнуться с ситуацией: при генерации экземпляра vue, при повторном назначении данных, иногда не будет автоматически обновляться до вида, когда мы посмотрим на документ vue, вы найдите это предложение: если вы добавите новое свойство в экземпляр после создания экземпляра, это не вызовет обновление представления. Следующий код добавляет возрастной атрибут к объекту ученика.
data () {
return {
student: {
name: '',
sex: ''
}
}
}
mounted () { // ——钩子函数,实例挂载之后
this.student.age = 24
}
Ограниченный ES5, Vue.js не может обнаруживать добавление или удаление свойств объекта. Поскольку Vue.js превращает свойства в геттеры/сеттеры при инициализации экземпляра, свойство должно находиться в объекте данных, чтобы 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 --- проблема обнаружения изменений (связанная с массивом)