问题复现

<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>

原因分析

  1. beforeCreatecreated 之间要做很多的事情,比如说:

    • 响应式处理、遍历一个对象的所有属性等;
    • 其实还有一步,叫做提取或者叫注入,在这一步它会遍历组件配置里边的东西,也就是 export default{} 里边的东西;
  2. 在这一步里边,它会读取 methods 配置,并且遍历里边的每一个成员,然后把这些成员一个一个的提取到组件实例里边去;

    • 比如说它遍历到了 methods 里的 moptions.methods.m ,然后使用 options.methods.m.bind(实例) 使方法的 this 指向组件实例,然后会返回一个新的函数;
    • 所以在组件里边调用的 this.m 实际上调用的是 options.methods.m.bind(实例) 返回的函数,这就解释了为什么在组件里边,函数的 this 始终会指向组件的实例,就是这样原因;
    • 所以说,外边的 m 函数和 methods 里的函数是同一个,但是通过 this.m 指向的函数就是组件实例里边的函数了,这时在 m 身上绑定的 属性 通过了 bind 重新绑定之后就会丢失;
  3. 解决:将函数放到 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>
    
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 问题复现
  2. 2. 原因分析