“ TypeError:无法读取未定义的属性'$ emit'”-VueJS

时间:2019-04-09 19:29:16

标签: 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>
        <!--<input type="text" name="username" v-model="input.username" placeholder="Username" />-->
        <!--<input type="password" name="password" v-model="input.password" placeholder="Password" />-->
        <!--<button type="button" v-on:click="login()">Login</button>-->
    </div>
</template>

<script>
    /* eslint-disable no-console */
    // import Vue from 'vue'
    // import BootstrapVue from 'bootstrap-vue'
    // import 'bootstrap/dist/css/bootstrap.css'
    // import 'bootstrap-vue/dist/bootstrap-vue.css'
    //
    // Vue.use(BootstrapVue)
    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"})
                        }
                    })
                }
                    // for (var keys in this.$parent.mockAccount) {
                    //     console.log(keys[0].username)
                    //     if (this.input.username === keys[0] && this.input.password === keys[1]) {
                    //         this.$emit("authenticated", true);
                    //         this.$router.replace({name: "secure"})
                    //     }
                    // }
                    // if (!this.authenticated) {
                    //     alert("The username or password does not match!!")
                    // }

                //     if(this.input.username === this.$parent.mockAccount.username && this.input.password === this.$parent.mockAccount.password) {
                //         this.$emit("authenticated", true);
                //         this.$router.replace({ name: "secure" });
                //     } else {
                //         console.log("The username and / or password is incorrect");
                //     }
                // } else {
                //     console.log("A username and password must be present");
                // }
            }
        }
    }
</script>

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

这是我的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>

这是我遇到的错误 enter image description here

1 个答案:

答案 0 :(得分:1)

ES5函数具有自己的this,因此请更改

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

使用ES6箭头功能(与定义它们的上下文具有相同的this

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

或对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))

或使用闭包:

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"})
  }
})