您现在的位置是:主页 > news > 只做水果的网站/免费推广论坛

只做水果的网站/免费推广论坛

admin2025/5/14 3:25:39news

简介只做水果的网站,免费推广论坛,用阿里云服务器做自己购物网站,企业线上推广公司响应式首先我们都知道,只要在 Vue 实例中声明过的数据,那么这个数据就是响应式的。什么是响应式,也即是说,数据发生改变的时候,视图会重新渲染,匹配更新为最新的值。也正是因为这个系统,让我们可…

只做水果的网站,免费推广论坛,用阿里云服务器做自己购物网站,企业线上推广公司响应式首先我们都知道,只要在 Vue 实例中声明过的数据,那么这个数据就是响应式的。什么是响应式,也即是说,数据发生改变的时候,视图会重新渲染,匹配更新为最新的值。也正是因为这个系统,让我们可…

响应式

首先我们都知道,只要在 Vue 实例中声明过的数据,那么这个数据就是响应式的。

什么是响应式,也即是说,数据发生改变的时候,视图会重新渲染,匹配更新为最新的值。

也正是因为这个系统,让我们可以脱离界面的束缚,只需要操作数据。

options.data传到new vue里面会被vue监听,然后会被vue实例代理,每次对data的读写都会被vue监控,vue会在data变化时,及时更新ui

vue如何监控数据的变化

代码演示:将数据模型通过data传入Vue之后发生的变化

<template><div>{{value}}</div>
</template><script>const myData = { value: 0 };console.log('还没有进入vue实例的myData')console.log(myData);export default {data() {return myData; //返回的是外部创建的myData对象}};setTimeout(() => {console.log('经过了vue实例之后的myData')console.log(myData);}, 2000);
</script>

控制台输出

870ae4b48604fcaf72b2d8503ce8476a.png

可以看到对象中多出了value属性的getter和setter方法,说明vue使用Object.definedProperty()定义了value属性。

Object.defineProperty

这个方法,是 Vue 响应式系统的精髓。使用 Object.defineProperty 可以为对象中的每一个属性,设置 get 和 set 方法。

Object.defineProperty 可以为属性设置很多特性,例如 configurable,enumerable,但是现在不过多解释,重点只放在 get 和 set

那么 get 和 set 方法有什么用?

get 值是一个函数,当属性被访问时,会触发 get 函数

set 值同样是一个函数,当属性被赋值时,会触发 set 函数

var obj={    name:"pink"
}
Object.defineProperty(obj,"name",{get(){        console.log("get 被触发")},set(val){        console.log("set 被触发")}
})

当我访问 obj.name 时,会打印 ' get 被触发 '

当我为 obj.name 赋值时,obj.name = 5,会打印 ' set 被触发 '

Vue 是怎么知道数据改变的呢?

Vue 在 属性的 set 方法中做了手脚,因而当数据改变时,触发 属性的 set 方法,Vue 就能知道数据有改变

vue文档深入响应式原理也明确的指出使用了Object.definedProperty来追踪依赖。

vue会使用定义setter对data中每一个属性进行跟踪,在 property 被访问和修改时通知变更。 每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。

data中的bug

1.vue会将data中所有的存在的属性进行跟踪,如果使用未定义的属性则会直接报错。

var vm = new Vue({data:{},methods:{foo(){return this.b //返回一个未定义的变量}}
})

控制台输出

2e9a2d3f59b03205dac341fb522b2e7a.png

如果是复杂的数据类型结果大不相同,也就是对象和数组。

2.关于对象

实例代码:点击按钮会先创建在obj中创建一个a属性,之后对obj.a不断自增

<template><div><button @click="create">点击为obj对象新增a属性</button>obj.a的值:{{obj.a}}  <--显示obj.a的值--></div>
</template><script>
export default {data(){return {obj:{}}},methods:{create(){console.log(this.obj);if(typeof this.obj.a === 'number'){this.obj.a++;}else{this.obj.a = 0}}}
};
</script>

由于vue只会对data中存在的属性值进行跟踪,所以上面代码中obj.a中的任何变化都不会触发页面的响应式渲染。

控制台中obj.a确识发生了变化,但是页面却没有渲染。obj.a属性没有使用definedProperty来定义。

解决办法:使用$set

可以使用 Vue.set(object, propertyName, value) 或$set(object, propertyName, value)方法向嵌套对象添加响应式 property。例如,对于:

Vue.set(this.obj, 'a', 0)
/**或**/
this.$set(this.obje,'a',0)

上面的代码可以改为:

 create(){if(typeof this.obj.a === 'number'){this.obj.a++;}else{this.$set(this.obj, 'a', 0)}}

有时你可能需要为已有对象赋值多个新 property,比如使用 Object.assign() 或 _.extend()。但是,这样添加到对象上的新 property 不会触发更新。在这种情况下,你应该用原对象与要混合进去的对象的 property 一起创建一个新的对象。

// 代替 `Object.assign(this.someObject, { a: 1, b: 2 })`
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })

3.关于数组

var vm = new Vue({data: {items: ['a', 'b', 'c']}
})
vm.items[1] = 'x' // 不是响应性的
vm.items.length = 2 // 不是响应性的

为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue 相同的效果,同时也将在响应式系统内触发状态更新:

// vm.$set()
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)

为了解决第二类问题,你可以使用 splice:

vm.items.splice(newLength) //将newLength之后的值切除
splice是被vue处理过的异变数组

变异数组:vue 在数组上添加了一层原型,对一下这些方法进行重新封装。以便在操作数组之后vue能够跟踪到对应的原型

  1. push
  2. pop
  3. shift
  4. unshift
  5. splice
  6. sort
  7. reverser

总结

1.Vue使用Object.definedProperty对所有存在的属性定义gettersetter,以此来对数据的修改进行跟踪,并通知watch对页面进行渲染。


2. Vue只会对data中存在的数据进行跟踪,后创建的属性需要使用this.$set(propertyName,callback)来进行添加跟踪。