Vue 2.0 深入源码分析(五) 基础篇 methods属性详解
程序员文章站
2022-06-29 08:09:11
用法 methods中定义了Vue实例的方法,官网是这样介绍的: 例如:: 显示的样式为: 当我们点击按钮后变为了: methods方法中的上下文为当前实例,也就是this为当前实例。 注:不应该使用箭头函数来定义 method 函数 (例如ChangeMessage:()=>this.messag ......
用法
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()对props, methods, data, computed 和 watch 进行初始化,如下:
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的实现是比较简单的。
上一篇: Ubuntu将自带的python3升级
下一篇: MySQL的Limit详解
推荐阅读
-
Vue 2.0 深入源码分析(八) 基础篇 依赖注入 provide/inject组合详解
-
Vue.js 源码分析(十一) 基础篇 过滤器 filters属性详解
-
Vue.js 源码分析(十三) 基础篇 组件 props属性详解
-
Vue 2.0 深入源码分析(七) 基础篇 侦听器 watch属性详解
-
Vue 2.0 深入源码分析(五) 基础篇 methods属性详解
-
Vue 2.0 深入源码分析(六) 基础篇 computed 属性详解
-
Vue 2.0 深入源码分析(四) 基础篇 响应式原理 data属性
-
Vue 2.0 深入源码分析(三) 基础篇 模板渲染 el、emplate、render属性详解
-
Vue.js 源码分析(十一) 基础篇 过滤器 filters属性详解
-
Vue.js 源码分析(十三) 基础篇 组件 props属性详解