methods中定义了Vue实例的方法,官网是这样介绍的:

例如::

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script><title>Document</title>
</head>
<body><div id="app">{{message}}<button @click="ChangeMessage">测试按钮</button></div><script>new Vue({el:'#app',data:{message:"Hello World!"},methods:{ChangeMessage:function(){this.message="Hello Vue!";}}})</script>
</body>
</html>

显示的样式为:

当我们点击按钮后变为了:

methods方法中的上下文为当前实例,也就是this为当前实例。

注:不应该使用箭头函数来定义 method 函数 (例如ChangeMessage:()=>this.message="Hello Vue")。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,this.message 将是 undefined。

源码分析


Vue实例后会先执行_init()进行初始化(4579行)时,会执行initState()进行初始化,如下:

function initState (vm) { //第3303行vm._watchers = [];var opts = vm.$options;if (opts.props) { initProps(vm, opts.props); }if (opts.methods) { initMethods(vm, opts.methods); }        //如果定义了methods,则调用initMethods初始化dataif (opts.data) {              initData(vm);                 } else {observe(vm._data = {}, true /* asRootData */);}if (opts.computed) { initComputed(vm, opts.computed); }if (opts.watch && opts.watch !== nativeWatch) {initWatch(vm, opts.watch);}
}

initMethods()定义如下:

function initMethods (vm, methods) {   //第3513行var props = vm.$options.props;for (var key in methods) {                 //遍历methods对象,key是每个键,比如例子里的ChangeMessage
    {if (methods[key] == null) {         //如果值为null,则报错warn("Method \"" + key + "\" has an undefined value in the component definition. " +"Did you reference the function correctly?",vm);} if (props && hasOwn(props, key)) {     //如果props中有同名属性,则报错warn(("Method \"" + key + "\" has already been defined as a prop."),vm);}if ((key in vm) && isReserved(key)) {   //如果key是以$或_开头则,也报错warn("Method \"" + key + "\" conflicts with an existing Vue instance method. " +"Avoid defining component methods that start with _ or $.");}}vm[key] = methods[key] == null ? noop : bind(methods[key], vm);             //如果key对应的值不是null,则执行bind()函数
  }
}

执行bind()函数,参数1为对应的函数体,参数2是当前的Vue实例,bind()函数定义在第196行,如下:

function polyfillBind (fn, ctx) {            //当Function的原型上不存在bind()函数时,自定义一个函数实现同样的功能,用apply()或call()来实现function boundFn (a) {var l = arguments.length;return l? l > 1? fn.apply(ctx, arguments): fn.call(ctx, a): fn.call(ctx)}boundFn._length = fn.length;return boundFn
}function nativeBind (fn, ctx) {             //调用Function的原型上的bind()方法,上下文闻ctxreturn fn.bind(ctx)
}var bind = Function.prototype.bind             //如果Function的原型上有bind方法,则调用该方法,否则用自定义的polyfillBind()方法? nativeBind: polyfillBind;

相比较其它API,method的实现是比较简单的。

转载于:https://www.cnblogs.com/greatdesert/p/11038026.html

Vue.js 源码分析(五) 基础篇 方法 methods属性详解相关推荐

  1. Vue.js 源码分析(九) 基础篇 生命周期详解

    先来看看官网的介绍: 主要有八个生命周期,分别是: beforeCreate.created.beforeMount.mounted.beforeupdate.updated   .beforeDes ...

  2. 【SA8295P 源码分析】53 - mifs.build.tmpl 脚本详解:启动QNX procnto-smp-instr微内核、启动QNX串口终端shell、加载解析并执行ifs2_la.img

    [SA8295P 源码分析]53 - mifs.build.tmpl 脚本详解:启动QNX procnto-smp-instr微内核.启动QNX串口终端shell.加载解析并执行ifs2_la.img ...

  3. Vue.js 源码分析(二十三) 指令篇 v-show指令详解

    v-show的作用是将表达式值转换为布尔值,根据该布尔值的真假来显示/隐藏切换元素,它是通过切换元素的display这个css属性值来实现的,例如: <!DOCTYPE html> < ...

  4. openstack-nova源码分析(五)flavor extra_specs 扩展属性

    Flavors extra-specs (flavors, os-flavor-extra-specs) Flavor 扩展属性设置, 扩展属性可以用来对虚拟机做一些额外的限制设置,具体的参数,将在后 ...

  5. 从源码分析RocketMQ系列-消息拉取PullMessageProcessor详解

    导语   在之前的分析中分析了关于SendMessageProcessor,并且提供了对应的源码分析分析对于消息持久化的问题,下面来看另外一个PullMessageProcessor,在RocketM ...

  6. Vue.js 源码分析—— Slots 是如何实现的

    今天主要分析 Vue.js 中常用的 Slots 功能是如何设计和实现的.本文将分为普通插槽.作用域插槽以及 Vue.js 2.6.x 版本的 v-slot 语法三部分进行讨论. 本文属于进阶内容,如 ...

  7. Android进阶——ExoPlayer源码分析之宽带预测策略的算法详解

    前言 由于国内基础设施非常优秀,在平时的开发中,很少会关注网络情况,很容易忽略弱网情况下的网络状况,如果项目属于国外App,则需要考虑到当前的基础设施和网络情况,特别是播放视频的时候,需要通过动态调整 ...

  8. underscore.js 源码分析5 基础函数和each函数的使用

    isArrayLike 检测是数组对象还是纯数组 var property = function(key) {return function(obj) {return obj == null ? vo ...

  9. android doze模式源码分析,Android Doze模式启用和恢复详解

    从Android 6.0(API level 23)开始,Android提出了两个延长电池使用时间的省电特性给用户.用户管理可以在没有充电的情况下管理app的行为.当用户一段时间没有使用手机的时候,D ...

最新文章

  1. 阿里发布2019十大科技趋势:AI依然最热
  2. Selenium常用方法及函数
  3. 《HTML5多媒体应用开发》——第2章 HTML5多媒体元素2.1 Web多媒体历史
  4. php 下拉菜单 搜索,DedeCMS实现百度搜索下拉菜单提示信息功能
  5. printf的两个需要注意的问题:无符号整数和64位整数
  6. ftp改为sftp_科普!一文详解 FTP、FTPS 与 SFTP 的原理
  7. 服务器访问oracle数据库,Oracle数据库的访问——通过不同服务器名对数据库的访问...
  8. kettle连接数据mysql查_Kettle连接MySQL报错的解决方法
  9. Seasonality Core for mac(世界天气预报)
  10. Python让繁琐工作自动化——chapter13 处理PDF和Word文档
  11. 《Head First》 MVC运用的设计模式
  12. 如何利用国内开源镜像站,下载想要的资源
  13. Unity3D IAP Google支付
  14. 80后年薪多少,才能摆脱中年危机?
  15. 阿里巴巴大数据学院落地成都,计划5年培养2000名高端专业人才
  16. 计算机硬件未来发展前景,计算机硬件发展现状
  17. PostgreSQL 荣获 DB-Engines 2018 年度数据库管理系统称号
  18. 关于UTF8,UTF16,UTF32,UTF16-LE,UTF16-BE
  19. iOS可复用控件之折线图
  20. [Codeforces Round #373 DIV1E (CF718E)] Matvey's Birthday

热门文章

  1. android简单小程序学成语,分享3个成语游戏小程序,让你学习游戏两不误
  2. 单独安装OneNote
  3. json、txt、xlsx
  4. PythonPyCharm
  5. Sql注入基础原理介绍(超详细)
  6. 艾伟:一个让人遗忘的角落—Exception(二)
  7. 手机电子邮件用outlook登录
  8. jeesite(一)
  9. Qt - 奇葩问题 解决方案
  10. 【Pytorch】| Pytorch中softmax的dim的详细总结