Methods
我在向组件实例添加方法时,所有的方法都会挂载在实例上。
<!-- `greet` 是上面定义过的方法名 -->
<button @click="greet">Greet</button>
data() {
return {
name: 'Vue.js'
}
},
methods: {
greet(event) {
// 方法中的 `this` 指向当前活跃的组件实例
alert(`Hello ${this.name}!`)
// `event` 是 DOM 原生事件
if (event) {
alert(event.target.tagName)
}
}
}
使用 methods
在创建 Vue
实例时,methods
会自动绑定当前实例的 this
,确保在事件监听时,回调始终指向当前组件实例。
在定义 methods
时,应避免使用箭头函数,因为箭头函数会阻止 Vue
正确绑定组件实例。
例如,使用 @click="greet"
时,方法名后面的括号 ()
并不是执行符号,而是用于传递参数的容器。以下是分解写法:
onClick = { () => changeTitle('This is your TITLE') }
在模板中直接调用方法时,应尽量避免副作用。这样可以确保组件的可预测性和可维护性。
直接绑定方法执行
<h2>{{ yourTitle() }}</h2>
methods: {
yourTitle () {
return 'This is your TITLE';
},
}
JS 工具库 Lodash
Lodash
使 JavaScript
开发更加简便,减少了处理数组、数字、对象和字符串等的复杂性。常用的功能如节流、防抖和时间过期等,Lodash
都有涵盖。
https://github.com/lodash/lodash
使用方法
以下是一个使用 Lodash
实现节流功能的示例:
const TeacherList = {
data() {
return {
teachers: [],
};
},
template: `
<div>
<table border="1">
<thead>
<tr>
<td>ID</td>
<td>姓名</td>
<td>学科</td>
</tr>
</thead>
<tbody v-if="teachers.length > 0">
<tr v-for="teacher in teachers" :key="teacher.id">
<td>{{ teacher.id }}</td>
<td>{{ teacher.name }}</td>
<td>{{ teacher.subject }}</td>
</tr>
</tbody>
<tbody v-else>
<tr>
<td colspan="3">暂无数据</td>
</tr>
</tbody>
</table>
<button @click="debouncedFetchTeachers">获取教师数据</button>
</div>
`,
created() {
// 使用 Lodash 的 debounce 方法防抖
this.debouncedFetchTeachers = _.debounce(this.fetchTeachers, 1000);
},
unmounted() {
// 组件卸载时取消防抖函数
this.debouncedFetchTeachers.cancel();
},
methods: {
async fetchTeachers() {
try {
const response = await axios.get('http://localhost:8081/getTeachers');
this.teachers = response.data;
} catch (error) {
console.error('获取教师数据失败:', error);
}
},
},
};
Vue.createApp(TeacherList).mount('#app');
实现 methods
下面是一个简单的 Vue
实现,展示了如何初始化数据和方法:
var Vue = (function () {
function Vue(options) {
this.$data = options.data();
this._methods = options.methods;
this._init(this);
}
Vue.prototype._init = function (vm) {
initializeData(vm);
initializeMethods(vm);
};
function initializeData(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 initializeMethods(vm) {
for (var key in vm._methods) {
vm[key] = vm._methods[key].bind(vm);
}
}
return Vue;
})();
var vm = new Vue({
data() {
return {
countA: 1,
countB: 2,
};
},
methods: {
incrementA(amount) {
this.countA += amount;
},
incrementB(amount) {
this.countB += amount;
},
calculateTotal() {
console.log(this.countA + this.countB);
},
},
});
console.log(vm);
vm.incrementA(1);
vm.incrementA(1);
vm.incrementA(1);
vm.incrementA(1);
// countA 5
vm.incrementB(2);
vm.incrementB(2);
vm.incrementB(2);
vm.incrementB(2);
// countB 10
vm.calculateTotal(); // 15
在这个实现中,initializeData
函数通过 Object.defineProperty
将数据属性代理到实例上,使得可以直接通过 vm.countA
访问和修改数据。同时,initializeMethods
函数绑定了所有方法到实例,确保 this
指向正确的组件实例。