概述
methods 是 Vue options API 中声明组件方法的选项
基本使用
export default {
methods: {
doSomething() {
// ...
},
// ...
},
};
具体步骤
- 在
methods中声明需要使用到的方法 - 在实例中使用
this.方法名(args)调用方法;在模板中直接挂载使用即可
注意
声明的方法可以直接通过组件实例访问,或者在模板语法表达式中使用。所有的方法都会将它们的 this 上下文自动绑定为组件实例,即使在传递时也如此。
在声明方法时避免使用箭头函数,因为它们不能通过 this 访问组件实例。
代码示例
import { defineComponent } from 'vue';
const Comp = defineComponent({
name: 'Comp',
// ...
methods: {
handleClick() {
console.log('click');
}
},
template: `
<div>
<h1>Comp</h1>
<button @click="handleClick">Click</button>
</div>
`
});
export default Comp;
methods 向组件实例添加方法时的特点
- 组件实例创建时, 会自动为 methods 绑定当前的实例 this - 确保在方法调用时, 注册的方法始终指向当前的组件实例 vm (所以,组件的 methods 要避免使用箭头函数, 箭头函数会阻止当前 method 的 this 指向)
- Vue 对于模板中调用的方法进行了优化:模板内的方法名后面的
()不是执行符号, 而是传入实参的容器 - methods 上的方法也能直接被视图绑定使用,但是每次更新都会导致方法的重新运算,一般这种情况更推荐使用计算属性
- 模板调用的方法尽量避免副作用操作 (事件处理函数除外)
- 经过 Vue 的代理(劫持)后, 所有的 method 都挂载到了 vm 实例上面, 而 methods 并没有暴露出来(所以,methods 注册的方法不能通过this.methods访问)
简单实现一下 methods
var Vue = (function () {
function Vue(options) {
this.$data = options.data();
this._methods = options.methods;
this._init(this);
}
Vue.prototype._init = function (vm) {
initData(vm);
initMethods(vm);
}
function initData(vm) {
for (var key in vm.$data) {
(function (key) {
Object.defineProperty(vm, key, {
get: function () {
return vm.$data[key];
},
set: function (newValue) {
vm.$data[key] = newValue;
}
})
})(key);
}
}
function initMethods(vm) {
for (var key in vm._methods) {
// vm[key] = vm._methods[key]
vm[key] = vm._methods[key]?.bind(vm);
}
}
return Vue;
})();
;(function (Vue) {
var vm = new Vue({
data() {
return {
count: 1,
};
},
methods: {
addCount() {
this.count += 1;
},
minusCount() {
this.count -= 1;
}
}
});
})(Vue);