上代码:
<body>
<div id="app">
{{msg}}
</div>
<script>
let datas = { //声明一个名为data的对象
msg: "hello"
}
let vm = new Vue({
el: '#app',
data: datas //把声明的date对象赋值给date属性
})
//现在,有三种方法可以获取到msg的值
console.log(datas.msg); //=> hello
console.log(vm.msg); //=> hello
console.log(vm.$data.msg); //=> hello
//而且,他们指向的是同一个地址
console.log(datas.msg === vm.msg); //=> true
console.log(vm.msg === vm.$data.msg); //=> true
console.log(vm.$data.msg === datas.msg); //=> true
</script>
</body>
由于datas对象我们已经声明了,显然,如果datas对象的地址的指向没有改变的话,另外两个对象(即vm.msg和vm.$data.msg)是引用了datas对象的地址
官方文档描述:
当一个 Vue 实例被创建时(
在钩子函数beforeCreate触发之后,钩子函数created触发之前),它将 data 对象中的所有的 property 加入到 Vue 的响应式系统中。当这些 property 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
所以vm示例下面会有一个msg属性,指向datas对象的msg属性,即vm.msg === datas.msg
暴露两个相同的属性,这样做有什么意义呢?
- 第一点,假如有如下情况(事实上,更常见的就是这种情况),那么你只能只用
vm.msg来访问或修改属性let vm = new Vue({ el: "#app", data: { msg: "hello" } }) - 第二点,你得知道两个数据指向同一个地址并不意味着什么时候他们两个对象都是等价的。例如在
Node.js中,module和module.export虽然也指向同一个地址,但是导出的对象是以module.export为准。
同样的道理,在Vue中监听msg的变化时是以vm.msg为准的,而data下的属性是在声明周期中的beforeCreate和created之间才被挂载的,这就意味着改变data下的且vm中不存在的属性是不会触发updated和beforeUpdate函数的let data = { msg: "hello" } let vm = new Vue({ el: '#app', data: data, updated:function(){ //目前只会检测vm.msg是否变化 console.log("update!") } }) vm.msg = 123; //=> update! vm.msg变化了,触发updated data.msg2 = "hello"; //没有触发updated,无输出
那为什么还要暴露vm.$data.msg呢?
官方描述:
除了数据 property,Vue 实例还暴露了一些有用的实例 property 与方法。它们都有前缀 $,以便与用户定义的 property 区分开来
- 所以当出现下述情况的时候,
vm.$data.msg比vm.msg能更好的描述data下的msg属性(语义上),而vm.msg用来被监听数据的变化
let vm = new Vue({
el: "#app",
data: {
msg: "hello"
}
})
- 如官方描述,Vue示例不止暴露了
$data属性,还暴露了许多属性和方法,例如可以这样使用:let vm = new Vue({ el: "#app", data: { msg: "hello" } }) console.log(vm.$el); //可以访问和修改el属性 vm.$watch('a', function(newValue, oldValue) { //可以定义监听函数 console.log(`before: ${oldValue},after:${newValue}`) })
本文探讨Vue实例中vm.$data.msg、data.msg与vm.msg的区别。Vue在创建实例时,将data对象的property加入响应式系统。vm.msg直接引用data.msg,两者通常指向同一地址,但在某些情况下,如在生命周期钩子之间赋值,仅修改data.msg不会触发视图更新。Vue实例的$data属性提供了一种访问data中属性的方式,而vm.msg则用于描述实例的msg属性,$watch监听通常基于vm对象。Vue实例还提供了许多以$开头的方法和property。

2万+

被折叠的 条评论
为什么被折叠?



