问题复现
<template>
<el-button type="primary" @click="onClick">调用方法</el-button>
</template>
<script>
const m = () => {
console.log('m');
};
m.close = () => {};
export default {
data() {
return {};
},
methods: {
m,
onClick() {
console.log(this.m.close); // undefined
console.log(this.m === m); // true
},
},
};
</script>
原因分析
-
在 beforeCreate 和 created 之间要做很多的事情,比如说:
- 响应式处理、遍历一个对象的所有属性等;
- 其实还有一步,叫做提取或者叫注入,在这一步它会遍历组件配置里边的东西,也就是 export default{} 里边的东西;
-
在这一步里边,它会读取 methods 配置,并且遍历里边的每一个成员,然后把这些成员一个一个的提取到组件实例里边去;
- 比如说它遍历到了 methods 里的 m 即 options.methods.m ,然后使用 options.methods.m.bind(实例) 使方法的 this 指向组件实例,然后会返回一个新的函数;
- 所以在组件里边调用的 this.m 实际上调用的是 options.methods.m.bind(实例) 返回的函数,这就解释了为什么在组件里边,函数的 this 始终会指向组件的实例,就是这样原因;
- 所以说,外边的 m 函数和 methods 里的函数是同一个,但是通过 this.m 指向的函数就是组件实例里边的函数了,这时在 m 身上绑定的 属性 通过了 bind 重新绑定之后就会丢失;
-
解决:将函数放到 data 里面可以解决问题
<template> <el-button type="primary" @click="onClick">调用方法</el-button> </template> <script> const m = () => { console.log('m'); }; m.close = ()=>{}; export default { data() { return { m, }; }, methods: { onClick() { console.log(this.m.close); // ()=>{} console.log(this.m === m); // true }, }, }; </script>
css🌰 实现文字智能适配背景
上一篇