如何在 .addEventListener 中访问 Vue.prototype?

Posted

技术标签:

【中文标题】如何在 .addEventListener 中访问 Vue.prototype?【英文标题】:How to acces Vue.prototype inside an .addEventListener? 【发布时间】:2021-05-22 17:20:10 【问题描述】:

我正在尝试访问在main.js 中声明的Vue.prototype.$firebase 的全局对象

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import VueTailwind from "vue-tailwind";
import  FirebaseApp  from "@/firebase/firebase";
//Style
import "@/assets/styles/app.css";
import settings from "@/assets/styles/Tailwind.js";

FirebaseApp.auth().onAuthStateChanged((user)=>
  Vue.prototype.$user = user;
)

//Vue
Vue.config.productionTip = false;
Vue.use(VueTailwind, settings);
Vue.prototype.$firebase = FirebaseApp;

new Vue(
  router,
  render: h => h(App)
).$mount("#app");

Login 组件内部

<script>
export default 
  name: "Login",
  mounted: function () 
    this.submit();
  ,
  methods: 
    submit() 
      let login = document.getElementById("login");     
      login.addEventListener(
        "submit",
        function (event) 
          event.preventDefault();
          const email = login.email.value;
          const password = login.password.value;
          this.$firebase
            .auth()
            .signInWithEmailAndPassword(email, password)
            .then((user) => 
              console.log(user)
              this.$router.replace('/')
            )
            .catch((error) => 
              console.log(error);
            );
        ,
        true
      );
    ,
  ,
;
</script>

但我得到TypeError: Cannot read property 'auth' of undefined,与this.$router 相同。 但是在.addEvenListener 之外实例化对象可以很好地打印并让我可以通过let signIn 访问,但这不是我想要的行为,相反,我想在logindashboard 之间“自动”路由onAuthStateChange 通过使用 Vue.prototype.$firebase 而不是本地实例化进行登录:

<script>
export default 
  name: "Login",
  mounted: function () 
    this.submit();
  ,
  methods: 
    submit() 
      let login = document.getElementById("login");
      let signIn = this.$FirebaseApp;
      let onLogin = this.$router;
      login.addEventListener(
        "submit",
        function (event) 
          event.preventDefault();
          const email = login.email.value;
          const password = login.password.value;
          signIn
            .auth()
            .signInWithEmailAndPassword(email, password)
            .then((user) => 
              console.log(user)
              onLogin.replace('/')
            )
            .catch((error) => 
              console.log(error);
            );
        ,
        true
      );
    ,
  ,
;
</script>

访问Vue.prototype.$firebase 的正确方法是什么?为什么它有这样的范围限制?

【问题讨论】:

【参考方案1】:

避免在组件回调中使用function(),而是使用arrow functions。

function 创建自己的this 上下文,这样this 将不再引用组件,但箭头函数使用周围的this 上下文:

login.addEventListener(
  "submit",
  (event) =>    // Changed to arrow function
  ...            // Now you can access `this.$firebase`
  ,
  true
);

【讨论】:

以上是关于如何在 .addEventListener 中访问 Vue.prototype?的主要内容,如果未能解决你的问题,请参考以下文章

vue中使用了window.addEventListener

如何在 Vue JS 中添加 window.addEventListener 和删除 window.removeEventListener

如何在游戏循环中使用 addEventListener

如何将一些参数传递给 addEventListener 中调用的函数? [复制]

多个 addEventListener 如何在 JavaScript 中工作?

js中addEventListener如何取消