Vue.js 源码分析(五) 基础篇 方法 methods属性详解
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属性详解相关推荐
- Vue.js 源码分析(九) 基础篇 生命周期详解
先来看看官网的介绍: 主要有八个生命周期,分别是: beforeCreate.created.beforeMount.mounted.beforeupdate.updated .beforeDes ...
- 【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 ...
- Vue.js 源码分析(二十三) 指令篇 v-show指令详解
v-show的作用是将表达式值转换为布尔值,根据该布尔值的真假来显示/隐藏切换元素,它是通过切换元素的display这个css属性值来实现的,例如: <!DOCTYPE html> < ...
- openstack-nova源码分析(五)flavor extra_specs 扩展属性
Flavors extra-specs (flavors, os-flavor-extra-specs) Flavor 扩展属性设置, 扩展属性可以用来对虚拟机做一些额外的限制设置,具体的参数,将在后 ...
- 从源码分析RocketMQ系列-消息拉取PullMessageProcessor详解
导语 在之前的分析中分析了关于SendMessageProcessor,并且提供了对应的源码分析分析对于消息持久化的问题,下面来看另外一个PullMessageProcessor,在RocketM ...
- Vue.js 源码分析—— Slots 是如何实现的
今天主要分析 Vue.js 中常用的 Slots 功能是如何设计和实现的.本文将分为普通插槽.作用域插槽以及 Vue.js 2.6.x 版本的 v-slot 语法三部分进行讨论. 本文属于进阶内容,如 ...
- Android进阶——ExoPlayer源码分析之宽带预测策略的算法详解
前言 由于国内基础设施非常优秀,在平时的开发中,很少会关注网络情况,很容易忽略弱网情况下的网络状况,如果项目属于国外App,则需要考虑到当前的基础设施和网络情况,特别是播放视频的时候,需要通过动态调整 ...
- underscore.js 源码分析5 基础函数和each函数的使用
isArrayLike 检测是数组对象还是纯数组 var property = function(key) {return function(obj) {return obj == null ? vo ...
- android doze模式源码分析,Android Doze模式启用和恢复详解
从Android 6.0(API level 23)开始,Android提出了两个延长电池使用时间的省电特性给用户.用户管理可以在没有充电的情况下管理app的行为.当用户一段时间没有使用手机的时候,D ...
最新文章
- 阿里发布2019十大科技趋势:AI依然最热
- Selenium常用方法及函数
- 《HTML5多媒体应用开发》——第2章 HTML5多媒体元素2.1 Web多媒体历史
- php 下拉菜单 搜索,DedeCMS实现百度搜索下拉菜单提示信息功能
- printf的两个需要注意的问题:无符号整数和64位整数
- ftp改为sftp_科普!一文详解 FTP、FTPS 与 SFTP 的原理
- 服务器访问oracle数据库,Oracle数据库的访问——通过不同服务器名对数据库的访问...
- kettle连接数据mysql查_Kettle连接MySQL报错的解决方法
- Seasonality Core for mac(世界天气预报)
- Python让繁琐工作自动化——chapter13 处理PDF和Word文档
- 《Head First》 MVC运用的设计模式
- 如何利用国内开源镜像站,下载想要的资源
- Unity3D IAP Google支付
- 80后年薪多少,才能摆脱中年危机?
- 阿里巴巴大数据学院落地成都,计划5年培养2000名高端专业人才
- 计算机硬件未来发展前景,计算机硬件发展现状
- PostgreSQL 荣获 DB-Engines 2018 年度数据库管理系统称号
- 关于UTF8,UTF16,UTF32,UTF16-LE,UTF16-BE
- iOS可复用控件之折线图
- [Codeforces Round #373 DIV1E (CF718E)] Matvey's Birthday