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

摘要:
scriptsrc=“https;divide=”app“>{{message}}<button@click=“更改消息”>测试按钮<newVue({el;()=>if(opts.props){initProps(vm;opts.prop);==nativeWatch){initWatch(vm;functioninitMethods(vm);

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

Vue.js 源码分析(五) 基础篇 方法 methods属性详解第1张

例如::

<!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>

显示的样式为:

Vue.js 源码分析(五) 基础篇 方法 methods属性详解第2张

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

Vue.js 源码分析(五) 基础篇 方法 methods属性详解第3张

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初始化data
  if (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()方法,上下文闻ctx
  return fn.bind(ctx)
}

var bind = Function.prototype.bind             //如果Function的原型上有bind方法,则调用该方法,否则用自定义的polyfillBind()方法
  ? nativeBind
  : polyfillBind;

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

免责声明:文章转载自《Vue.js 源码分析(五) 基础篇 方法 methods属性详解》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Java BTrace实战(1)--BTrace的入门和使用CodeSmith使用方法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

提高iOS开发效率的第三方框架等--不断更新中。。。

1. Mantle Mantle 让我们能简化 Cocoa 和 Cocoa Touch 应用的 model 层。简单点说,程序中经常要进行网络请求,请求到得一般是 json 字符串,我们一般会建一个 Model 类来存放这些数据。这就要求我们编写一系列的序列化代码,来把 json 转换为 Model 。这很费时间,容易错,不容易修改。 Mantle 很好...

配置RedisTemplate、JedisPoolConfig、JedisConnectionFactory+自定义序列化 (xml+java方式)+使用

java方式配置RedisTemplate   //spring注入ben    //@Bean(name = "redisTemplate") public RedisTemplate initRedisTemplate(){ JedisPoolConfig poolConfig = new JedisPoolConfig();...

ARM 汇编的mov操作立即数的疑问

1. 因为对arm汇编有些指令还不能理解,特别是一些相似功能指令间的区别。偶然在网上搜到“faq ARM assembly”,其中描述的几个问题还是值得好好研究一下。 2. 慢慢的发现自己也不再害怕英文的文档了,耐心看至少也能懂个大概。大批经典的文章和书籍都是en文的,所以经常看英文文档是一个非常好的习惯。看看GNU的一些reference manual,...

jQuery日期弹出选择框Datepicker效果

无论你是一个机票在线预定网站设计师,还是一个工程任务管理者,抑或在你的注册表单上有个生日填写项目;本文即将提到的日历日期选择弹出窗口都将帮助你简化用户操作,提高网站的用户体验和易用性。 教程目标:教会大家如何jQuery的UI插件Datepicker通过短短几行JavaScript代码制作一个日期选择弹出窗口,当用户在弹出的日期选择框中选择一个日期后,该日...

批量安装Zabbix_Agent

使用自动化部署工具Ansible批量部署zabbix_agent. 1. 安装Ansible   yum –y install ansible   内网情况下,现在ansible及其依赖的rpm包,添加到yum源进行安装。 2. 主机配置文件   在/etc/ansible中添加主机,主机配置文件为hosts,也可以在ansible.cfg中修改配置  ...

.net mvc使用FlexPaper插件实现在线预览PDF,EXCEL,WORD的方法

FlexPaper插件可以实现在浏览器中在线预览pdf,word,excel等。 在网上看到很多关于这个插件实现预览的技术,但是很难做到word和excel在线预览。 pdf很好实现。   首先下载相关的插件信息,这里不多说了。 其中这个插件主要需要配合Aspose来实现将上传的excel和word来转换为pdf。再通过pdf2swf来将pdf转换为swf...