前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue归纳笔记:Vue 实例如何实现代理 data 对象属性的访问

Vue归纳笔记:Vue 实例如何实现代理 data 对象属性的访问

作者头像
用户1272076
发布2019-08-19 15:48:32
1.4K0
发布2019-08-19 15:48:32
举报
文章被收录于专栏:张培跃张培跃

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

看一段简单代码先:

代码语言:javascript
复制
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下的属性?

要弄明这两个问题首先你要明白下面3个点:

1、this即是通过Vue生成的实例vm

代码语言:javascript
复制
const vm = new Vue({
    el:"#myApp",
    created(){
        console.log(vm === this);// true
    }
})

2、$data与data是相等的

代码语言:javascript
复制
const data ={};
const vm = new Vue({
    el:"#myApp",
    data,
    created(){
        console.log(this.$data === data);// true
    }
})
console.log(vm.$data === data);// true

3、$data的属性被修改,vm实例下的属性也会发生相应的变化

代码语言:javascript
复制
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的源码模拟出了以下较易理解的代码:

代码语言:javascript
复制
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;
        }
    });
};

验证:

代码语言:javascript
复制
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—————

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 张培跃 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、通过Vue生成的实例中有一属性为$data,其值为接收对象的data值
  • 2、vm实例中代理了data的属性
  • 3、methods下的方法赋值给了vm实例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档