“类型错误:无法读取未定义的属性 '$emit'” - VueJS

Sid*_*nha 1 javascript authentication vue.js

我正在尝试在 vuejs 中实现一个简单的身份验证。我有一个对象列表,其中包含真实的用户名和密码。我正在遍历这个列表并检查输入的用户名和密码。如果有匹配项,那么我将发出一个事件并更新我的经过身份验证的变量。但问题出在 forEarch 循环中的登录内部,我无法访问发射。

这是我的 Login.vue 文件

<template>
    <div id="login">
        <h1>Login</h1>
        <b-form-input v-model="input.username" placeholder="Username"></b-form-input>
        <br/>
        <b-form-input v-model="input.password" placeholder="Password" type="password"></b-form-input>
        <br/>
        <b-button variant="primary" v-on:click="login()">Submit</b-button>
    </div>
</template>

<script>
    
    export default {
        name: 'Login',
        data() {
            return {
                input: {
                    username: "",
                    password: ""
                }
            }
        },
        methods: {
            login() {
                var enteredUsername = this.input.username;
                var enteredPassword = this.input.password;
                if(enteredUsername !== "" && enteredPassword !== "") {
                    this.$parent.mockAccount.forEach(function (element) {
                        if (enteredUsername === element.username && enteredPassword === element.password) {
                            this.$emit("authenticated", true)
                            this.$router.replace({name: "secure"})
                        }
                    })
                }
            }
        }
    }
</script>

<style scoped>
    #login {
        width: 500px;
        border: 1px solid #CCCCCC;
        background-color: #FFFFFF;
        margin: auto;
        margin-top: 200px;
        padding: 20px;
    }
</style>
Run Code Online (Sandbox Code Playgroud)

这是我的 App.vue 文件

<template>
  <div id="app">
    <div id="nav">
      <router-link v-if="authenticated" to="/login" v-on:click.native="logout()" replace>Logout</router-link>
    </div>
    <router-view/>
  </div>
</template>

<script>

    export default {
        name: 'App',
        data() {
            return {
                authenticated: false,
                mockAccount: [
                    {
                        username: "a",
                        password: "a"
                    },
                    {
                        username: "rick",
                        password: "rick2018"
                    },
                    {
                        username: "nick",
                        password: "nick2018"
                    },
                    {
                        username: "paul",
                        password: "paul2018"
                    }]
            }
        },
        mounted() {
            if(!this.authenticated) {
                this.$router.replace({ name: "Login" });
            }
        },
        methods: {
            setAuthenticated(status) {
                this.authenticated = status;
            },
            logout() {
                this.authenticated = false;
            }
        }
    }
</script>

<style>
  body {
    background-color: #F0F0F0;
  }
  h1 {
    padding: 0;
    margin-top: 0;
  }
  #app {
    width: 1024px;
    margin: auto;
  }
</style>
Run Code Online (Sandbox Code Playgroud)

这是我得到的错误 在此处输入图片说明

con*_*exo 9

ES5的功能有自己的this,所以改

this.$parent.mockAccount.forEach(function (element) {
  if (enteredUsername === element.username && enteredPassword === element.password) {
    this.$emit("authenticated", true)
    this.$router.replace({name: "secure"})
  }
})
Run Code Online (Sandbox Code Playgroud)

要么是 ES6 箭头函数(与this定义它们的上下文相同)

this.$parent.mockAccount.forEach((element) => {
  if (enteredUsername === element.username && enteredPassword === element.password) {
    this.$emit("authenticated", true)
    this.$router.replace({name: "secure"})
  }
})
Run Code Online (Sandbox Code Playgroud)

或使用显式绑定Function.prototype.bind()(ES5):

this.$parent.mockAccount.forEach(function (element) {
  if (enteredUsername === element.username && enteredPassword === element.password) {
    this.$emit("authenticated", true)
    this.$router.replace({name: "secure"})
  }
}.bind(this))
Run Code Online (Sandbox Code Playgroud)

或使用闭包:

const self = this;
this.$parent.mockAccount.forEach(function (element) {
  if (enteredUsername === element.username && enteredPassword === element.password) {
    self.$emit("authenticated", true)
    self.$router.replace({name: "secure"})
  }
})
Run Code Online (Sandbox Code Playgroud)