Vue 实例 VM 访问属性
2025/4/22
向
一、查看有哪些属性
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script><title>初识VM</title>
</head>
<body><div id="app"><h1>{{msg}}</h1></div><script>const vm = new Vue({el : "#app",data :{msg : "hello vue!"}})</script></body>
</html>
运行结果如下,然后在控制台输入vm,查看Vue实例vm有哪些属性。
可以看见vm中含有非常多的属性。
二、访问Vue属性
vue实例中的属性很多,有的以 $ 开始,有的以 _ 开始。所有以 $ 开始的属性,可以看做是公开的属性,这些属性是供程序员使用的。所有以 _ 开始的属性,可以看做是私有的属性,这些属性是Vue框架底层使用的。一般我们程序员很少使用。通过vm也可以访问Vue实例对象的原型对象上的属性,例如:vm.$delete...
通过vue实例可以访问到msg。
<script>const vm = new Vue({el : "#app",data :{msg : "hello vue!"}})
</script>
其实通过vm.msg就能访问到msg的值是很奇怪的一件事情,上面的代其实就是如下代码。
<script>let obj = {msg : "hello vue!"}const vm = new Vue({el : "#app",data : obj })
</script>
所以vm.msg本应该访问不到msg的值,msg的值在obj对象中 ,当将代码改成上面那样,再次测试,看是否还能通过vm.msg访问到。
<script>let obj = {msg : "hello vue!"}const vm = new Vue({el : "#app",data : obj})console.log('obj的msg:', obj.msg)console.log('vm的msg:',vm.msg)
</script>
还是同样的访问到了,这是由于Vue 框架底层使用的数据代理机制,会把 data
选项中的属性转换为响应式属性,同时将这些属性代理到 Vue 实例上,所以你可以直接通过 vm.msg
访问和修改 data
中的 msg
属性。这种设计让开发者能够更方便地操作数据,同时确保数据的变化能够自动更新到 DOM 上。
在理解数据代理机制之前,要先理解基于 ES5 的 Object.defineProperty()
方法(Vue 2.x 版本)
2.1 Object.defineProperty()
Object.defineProperty()这个方法是ES5新增的。这个方法的作用是:给对象新增属性,或者设置对象原有的性。
object.defineProperty (
- 给哪个对象新增属性,
- ' 新增的这个属性名叫什么 ',
- {给新增的属性设置相关的配置项key:value对 } )
测试:
<body><div id="app"><h1>{{msg}}</h1></div><script>// 声明一个空对象let phone = {}// 使用Object.defineProperty添加新属性并赋值Object.defineProperty(phone,'name',{value: 'apple',writable: true})</script></body>
成功的使用Object.defineProperty()为phone对象添加了属性,并为其属性赋值了。
getter方法配置项和setter方法配置项,只要我们在读取/修改属性值的时候,其内部会自动的帮助我们去调用getter方法和setter方法,同时需要注意的是,当配置项中存在getter和setter方法的时候,其value和writable配置项都不能写。
测试一下自动调用getter方法和setter方法
<body><div id="app"><h1>{{msg}}</h1></div><script>// 声明一个空对象let phone = {}// 使用object.defineProperty添加新属性并赋值Object.defineProperty(phone,'name',{// value: 'apple',// writable: true,// getter方法配置项get : function() {console.log("getter方法执行了")},// setter方法配置项set : function(){console.log("setter方法执行了")}})</script></body>
可以发现在访问属性值的时候,getter方法自动的被执行了。 我们载为getter方法添加上返回值,getter方法的返回值非常的重要,其getter方法的返回值就是其属性的值。
<body><div id="app"><h1>{{msg}}</h1></div><script>// 声明一个空对象let phone = {}// 使用object.defineProperty添加新属性并赋值Object.defineProperty(phone,'name',{// value: 'apple',// writable: true,// getter方法配置项get : function() {console.log("getter方法执行了")return 'apple' },// setter方法配置项set : function(val){console.log("setter方法执行了")}})</script></body>
setter方法是有一个参数的,用于接受传过来的值 。进一步将代码变成如下所示。
<body><div id="app"><h1>{{msg}}</h1></div><script>// 声明一个空对象let phone = {}// 使用object.defineProperty添加新属性并赋值Object.defineProperty(phone,'name',{// value: 'apple',// writable: true,// getter方法配置项get : function() {console.log("getter方法执行了")return this.name},// setter方法配置项set : function(){console.log("setter方法执行了")this.name = val}})</script></body>
上述代码一旦访问或者设置的时候,就会一直的递归调用直到内存溢出。所以为达成上述效果因该进一步优化成如下效果
<body><div id="app"><h1>{{msg}}</h1></div><script>// 声明一个空对象let phone = {}//临时变量let temp// 使用object.defineProperty添加新属性并赋值Object.defineProperty(phone,'name',{// value: 'apple',// writable: true,// getter方法配置项get : function() {console.log("getter方法执行了")return temp},// setter方法配置项set : function(){console.log("setter方法执行了")temp = val}})</script></body>
2025/4/22