栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > Vue.js

Vue原理解析:Vue 实例如何实现代理 data 对象属性的访问

Vue.js 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Vue原理解析:Vue 实例如何实现代理 data 对象属性的访问

对于初学Vue.js的小伙伴而言,可能会认为Vue实例是一个很神奇的东西!因为它除了帮助我们完成双向绑定之外,还在某些细节方面为我们增加了一些理解上面的小烦恼!希望通过这篇文章能够为勤勉的你解惑~

看一段简单代码先:

new Vue({
    el:"#myApp",
    data:{
 userName:"laoWangTou",
 age:16
    },
    methods:{
 run(){
     // 输出结果:laoWangTou今年16岁了
     console.log(this.userName+"今年"+this.age+"岁了");
 }
    },
    created(){
 // this为什么可以调用methods的run方法?
 this.run();
    }
})

对于以上代码可能会有两个小疑问:
1、为什么钩子函数中的 this.run 可以调用到methods对像下的方法run?
2、为什么methods对象下的run方法可以通过this获得data下的属性?
要弄明白这两个问题首先你要明白下面几个点:

  • this即是通过Vue生成的实例vm
const vm = new Vue({
    el:"#myApp",
    created(){
 console.log(vm === this);// true
    }
})
  • $data与data是相等的
const data ={};
const vm = new Vue({
    el:"#myApp",
    data,
    created(){
 console.log(this.$data === data);// true
    }
})
console.log(vm.$data === data);// true
  • $data的属性被修改,vm实例下的属性也会发生相应的变化
const vm = new Vue({
    el:"#myApp",
    data:{
 userName:"laoWangTou",
 age:16
    },
    created(){
 this.$data.userName = "xiaoZhang"
 this.$data.age = 18;
 // 输出结果:xiaoZhang今年18岁了
 console.log(this.userName+"今年"+this.age+"岁了");
    }
})
// 输出结果:xiaoZhang今年18岁了
console.log(vm.userName+"今年"+vm.age+"岁了");

通过之前的两个疑问及得到的个结论,咱们可以先来个小猜测:

1、通过Vue生成的实例中有一属性为$data,其值为接收对象的data值 2、vm实例中代理了data的属性 3、methods下的方法赋值给了vm实例

于是,结合Vue.js的源码模拟出了以下较易理解的代码:

// 定义了一个构造函数
function Vue(options) {
    this.$data = options.data || {};
    this.initState(options);
}
Vue.prototype.initState = function (opts) {
    if(opts.data)
 this.initData(opts.data);
    if(opts.methods)
 this.initMethods(opts.methods);
    if(opts.created)
 opts.created.call(this);
}
Vue.prototype.initData = function (data) {
    var keys = Object.keys(data);
    var i = keys.length;
    while (i--){
 const key = keys[i];
 this.proxy("$data",key);
    }
}
Vue.prototype.initMethods = function (methods) {
    for (var key in methods) {
 this[key] = methods[key];
    }
}
Vue.prototype.proxy =function(sourceKey, key) {
    Object.defineProperty(this, key, {
 get() {
     return this[sourceKey][key]
 },
 set(val){
     this[sourceKey][key] = val;
 }
    });
};

验证:

const vm = new Vue({
    el:"#myApp",
    data:{
 userName:"laoWangTou",
 age:16
    },
    methods:{
 run(){
     // 输出结果:laoWangTou今年16岁了
     console.log(this.userName+"今年"+this.age+"岁了");
 }
    },
    created(){
 // this为什么可以调用methods的run方法?
 this.run();
    }
});
// 输出结果:laoWangTou今年16岁了
console.log(vm.userName+"今年"+vm.age+"岁了");

—————END—————

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/240358.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号