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

例如::

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script>
  6. <title>Document</title>
  7. </head>
  8. <body>
  9. <div id="app">{{message}}<button @click="ChangeMessage">测试按钮</button></div>
  10. <script>
  11. new Vue({
  12. el:'#app',
  13. data:{message:"Hello World!"},
  14. methods:{
  15. ChangeMessage:function(){this.message="Hello Vue!";}
  16. }
  17. })
  18. </script>
  19. </body>
  20. </html>

显示的样式为:

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

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

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

源码分析


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

  1. function initState (vm) { //第3303行
  2. vm._watchers = [];
  3. var opts = vm.$options;
  4. if (opts.props) { initProps(vm, opts.props); }
  5. if (opts.methods) { initMethods(vm, opts.methods); } //如果定义了methods,则调用initMethods初始化data
  6. if (opts.data) {
  7. initData(vm);
  8. } else {
  9. observe(vm._data = {}, true /* asRootData */);
  10. }
  11. if (opts.computed) { initComputed(vm, opts.computed); }
  12. if (opts.watch && opts.watch !== nativeWatch) {
  13. initWatch(vm, opts.watch);
  14. }
  15. }

initMethods()定义如下:

  1. function initMethods (vm, methods) {   //第3513行
  2. var props = vm.$options.props;
  3. for (var key in methods) { //遍历methods对象,key是每个键,比如例子里的ChangeMessage
  4. {
  5. if (methods[key] == null) {         //如果值为null,则报错
  6. warn(
  7. "Method \"" + key + "\" has an undefined value in the component definition. " +
  8. "Did you reference the function correctly?",
  9. vm
  10. );
  11. }
  12. if (props && hasOwn(props, key)) {     //如果props中有同名属性,则报错
  13. warn(
  14. ("Method \"" + key + "\" has already been defined as a prop."),
  15. vm
  16. );
  17. }
  18. if ((key in vm) && isReserved(key)) {   //如果key是以$或_开头则,也报错
  19. warn(
  20. "Method \"" + key + "\" conflicts with an existing Vue instance method. " +
  21. "Avoid defining component methods that start with _ or $."
  22. );
  23. }
  24. }
  25. vm[key] = methods[key] == null ? noop : bind(methods[key], vm); //如果key对应的值不是null,则执行bind()函数
  26. }
  27. }

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

  1. function polyfillBind (fn, ctx) { //当Function的原型上不存在bind()函数时,自定义一个函数实现同样的功能,用apply()或call()来实现
  2. function boundFn (a) {
  3. var l = arguments.length;
  4. return l
  5. ? l > 1
  6. ? fn.apply(ctx, arguments)
  7. : fn.call(ctx, a)
  8. : fn.call(ctx)
  9. }
  10.  
  11. boundFn._length = fn.length;
  12. return boundFn
  13. }
  14.  
  15. function nativeBind (fn, ctx) { //调用Function的原型上的bind()方法,上下文闻ctx
  16. return fn.bind(ctx)
  17. }
  18.  
  19. var bind = Function.prototype.bind //如果Function的原型上有bind方法,则调用该方法,否则用自定义的polyfillBind()方法
  20. ? nativeBind
  21. : polyfillBind;

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

Vue.js 源码分析(五) 基础篇 方法 methods属性详解的更多相关文章

  1. Vue.js 源码分析(十三) 基础篇 组件 props属性详解

    父组件通过props属性向子组件传递数据,定义组件的时候可以定义一个props属性,值可以是一个字符串数组或一个对象. 例如: <!DOCTYPE html> <html lang= ...

  2. Vue.js 源码分析(十一) 基础篇 过滤器 filters属性详解

    Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化.过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持).过滤器应该被添加在 JavaScrip ...

  3. Vue.js 源码分析(四) 基础篇 响应式原理 data属性

    官网对data属性的介绍如下: 意思就是:data保存着Vue实例里用到的数据,Vue会修改data里的每个属性的访问控制器属性,当访问每个属性时会访问对应的get方法,修改属性时会执行对应的set方 ...

  4. Vue.js 源码分析(三) 基础篇 模板渲染 el、emplate、render属性详解

    Vue有三个属性和模板有关,官网上是这样解释的: el ;提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标 template ;一个字符串模板作为 Vue 实例的标识使用.模板将会 ...

  5. Vue.js 源码分析(二) 基础篇 全局配置

    Vue.config是一个对象,包含Vue的全局配置,可以在启动应用之前修改下列属性,如下: ptionMergeStrategies        ;自定义合并策略的选项silent         ...

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

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

  7. Vue.js 源码分析(八) 基础篇 依赖注入 provide/inject组合详解

    先来看看官网的介绍: 简单的说,当组件的引入层次过多,我们的子孙组件想要获取祖先组件的资源,那么怎么办呢,总不能一直取父级往上吧,而且这样代码结构容易混乱.这个就是这对选项要干的事情 provide和 ...

  8. Vue.js 源码分析(七) 基础篇 侦听器 watch属性详解

    先来看看官网的介绍: 官网介绍的很好理解了,也就是监听一个数据的变化,当该数据变化时执行我们的watch方法,watch选项是一个对象,键为需要观察的数据名,值为一个表达式(函数),还可以是一个对象, ...

  9. Vue.js 源码分析(十) 基础篇 ref属性详解

    ref 被用来给元素或子组件注册引用信息.引用信息将会注册在父组件的 $refs 对象上.如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素:如果用在子组件上,引用就指向组件实例,例如: ...

随机推荐

  1. jersey常用注解解释 JAX-RS常用注解:

    jersey常用注解解释: Annotation 作用 说明 @GET 查询请求 相当于数据库的查询数据操作 @PUT 更新请求 相当于数据库的更新数据操作 @POST 插入请求 相当于数据库的插入数 ...

  2. Object.defineProperty-vuejs数据响应基石

    https://www.jianshu.com/p/07ba2b0c8fca https://juejin.im/post/5b99215d5188255c520cfe22 vuejs数据双向绑定地核 ...

  3. 场sharepoint2016数据库恢复站点

    前不久公司support方,不小心把IIS的应用删除了,算是灼急了,不过有过原来恢复的经历,似乎有了心理准备,可是这次比上次严重些.技术操作复杂些,不过通过此事,也是进一步了解了SP2016数据库结构 ...

  4. CTF挑战赛丨网络内生安全试验场第一季答题赛火热开启

    前期回顾:挑战世界级“人机大战”,更有万元奖金等你来拿 网络内生安全试验场自上线以来,受到了业内的极大重视与关注. 自9月2日报名通道开启后,报名量更是持续高升,上百名精英白帽踊跃报名. 至此,网络内 ...

  5. shell脚本按当前日期输出日志

    shell脚本基本技能是设置变量,输出信息.如下: sh脚本输出到控制台 将以上脚本保存到test.sh脚本文件中,并赋予可执行权限:sudo chmod +x test.sh 执行脚本:bash t ...

  6. Centos7安装elasticSearch6

                                                    Elasticsearch6.0 1.Elasticsearch: Elasticsearch是一个基于 ...

  7. Everybody Dance Now

    一.摘要 作者提出了一种简单的动作迁移方法,实现了"do as I do":给定一个人跳舞的源视频,作者可以在目标对象表演标准动作的短短几分钟后,将该表演转移到一个新的(业余的)目 ...

  8. 7. Transformer-XL原理介绍

    1. 语言模型 2. Attention Is All You Need(Transformer)算法原理解析 3. ELMo算法原理解析 4. OpenAI GPT算法原理解析 5. BERT算法原 ...

  9. Rust中的枚举及模式匹配

    这个enum的用法,比c要强,和GO类似. enum Coin { Penny, Nickel, Dime, Quarter, } fn value_in_cents(coin: Coin) -> ...

  10. Python微信公众号开发—小白篇(1)

    本文面向想通过Python学习公众号开发的同学.一站式解决新手开发微信公众号遇到的所有问题. 为了防止我的文章被到处转载,贴一下我的公众号[智能制造社区],欢迎大家关注. github仓库地址http ...