用法css
methods中定義了Vue實例的方法,官網是這樣介紹的:html
例如::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>
顯示的樣式爲:app
當咱們點擊按鈕後變爲了:函數
methods方法中的上下文爲當前實例,也就是this爲當前實例。oop
注:不該該使用箭頭函數來定義 method 函數 (例如ChangeMessage:()=>this.message="Hello Vue")。理由是箭頭函數綁定了父級做用域的上下文,因此 this
將不會按照指望指向 Vue 實例,this.message
將是 undefined。源碼分析
源碼分析測試
Vue實例後會先執行_init()進行初始化(4579行)時,會執行initState()進行初始化,以下:this
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()定義以下:spa
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的實現是比較簡單的。