亲手实现一个简单的类 Vue 框架 —— 绑定外部传入方法

我们知道 Vue 中传入的对象有一个属性对象methods,其中的属性方法会被绑定到 Vue 实例上,可以通过this访问到,那么我们这一篇文章就来实现一下方法的绑定

【注:本节所有代码都是在上一节代码的基础上增加的,所以上一节的代码将会省略】

首先确定我们预期的使用方式:

var l = new Lue({
    methods: {
        init: function () {
            console.log(this)
        }
    },
    ready: function () {
          // 与上一节相同,先通过一个 $methods 作为所有方法被绑定到的对象
        this.$methods.init()
    }
})

根据上面的代码,我们大致可以推断出绑定方法的代码:

function Lue () {
    this.$methods = {}
    if (typeof opts.methods === 'object') {
        for (var key in opts.methods) {
            if (typeof opts.methods[key] === 'function') {
                this.$methods[key] = opts.methods[key]
            }
        }
    }

    if (typeof opts.ready === 'function') {
        opts.ready.call(this)
    }
}

执行后控制台输出一个包含init方法的对象,即我们传入的外部对象的methods属性,而不是我们期望的l实例。这是为什么呢?我们在 前端面试题——call与apply方法的异同这一节中已经剖析过了this的指向问题——this永远指向该方法被持有的对象,即谁(哪个对象)持有这个方法,this就指向这个对象。所以在这里打印出来的是methods对象,而不是我们所期望的l

那我们该怎么做呢?很简单,用callapply方法改变this的指向

但是这里又有一个问题:

通过callapply改变this的函数会被立即执行

所以在处理方法的绑定时,我们需要延迟绑定,即在该方法需要被执行时,再绑定到l上,但是又要能够通过this.$methods访问到这个方法

是不是有点绕?没关系,直接上代码!

function Lue () {
    this.$methods = {}
    if (typeof opts.methods === 'object') {
        this._bindMethods(opts.methods)
    }
    // 兼容当 methods 属性为方法,并且返回一个对象时的情况
    if (typeof opts.methods === 'function' && typeof opts.methods() === 'object') {
        this._bindMethods(opts.methods())
    }
  
   if (typeof opts.ready === 'function') {
       opts.ready.call(this)
   }
}

// 在 Lue 原型链上添加方法 _bindMethods
Lue.prototype._bindMethods = function (obj) {
    var self = this
    for (var key in obj) {
        var val = obj[key]
        if (typeof val === 'function') {
              // 放该属性为方法时,在 $methods 上创建一个同名方法
            // 这个方法的作用是改变传入的参数 $methods 属性上的对应方法的执行环境并执行
            // 两个连续的三目运算的作用是:当该方法无参数时,直接通过 call 改变执行环境并执行;当存在 1 个参数时,通过 call 方法并传入这个参数 arg;当参数多于 1 个时,通过 apply 方法并传入整个参数列表
            this.$methods[key] = function (arg) {
            var length = arguments.length
            length ? length > 1 ? val.apply(self, arguments) : val.call(self, arg)
                     : val.call(self)
             }
        }
    }
}

以上代码修改后再次执行,控制台成功输出了我们预期的l对象

大功告成!

这一节的内容到这里就结束啦!传说中的短小精悍,直戳要点!嗯,明天就是劳动节啦,虽然今天已经是假期第二天了:)虽然有点短,但小伙伴们不要介意啊,下周一定补回来!大家节日快乐,玩好吃好!但也不要忘了学习哦!

下面是重头戏!!!第一次公众号关注福利出炉~~~扫描二维码关注后回复【福利】即可领取

【HTML5程序设计】电子版

扫码关注前端周记公众号
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • //Clojure入门教程: Clojure – Functional Programming for the J...
    葡萄喃喃呓语阅读 3,616评论 0 7
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,204评论 0 4
  • 如果你现在出现在我面前你会看到我泪流满面因为我正伤心如果你现在出现在我面前你会不会自然地搂住我在安慰我后陪我静默?...
    飞鱼kiwi阅读 379评论 0 2
  • 今天资源要起来有点困难呢,同样的时间同样的地点结果却不同,不过我们都是打不死的小强,不会气馁! 要资源...
    金金归来阅读 656评论 0 0