最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - "TypeError: Cannot read property '$emit' of undefined" - VueJS - Stack Overflow

programmeradmin4浏览0评论

I am trying to implement a simple authentication in vuejs. I have a list of objects in which I have authentic username and password. I am iterating over this list and checking with the entered username and password. If there is a match then I am emitting an event and updating my variable authenticated. But the problem is inside the login in the forEarch loop i am not able to access the emit.

This is my Login.vue file

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

I am trying to implement a simple authentication in vuejs. I have a list of objects in which I have authentic username and password. I am iterating over this list and checking with the entered username and password. If there is a match then I am emitting an event and updating my variable authenticated. But the problem is inside the login in the forEarch loop i am not able to access the emit.

This is my Login.vue file

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

Here is my App.vue file

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

This is the error i am getting

Share Improve this question edited Oct 21, 2019 at 8:34 Chalist 3,3095 gold badges43 silver badges72 bronze badges asked Apr 9, 2019 at 19:29 Siddharth SinhaSiddharth Sinha 6283 gold badges16 silver badges38 bronze badges 1
  • It is working fine. Thanks a lot for the help!! – Siddharth Sinha Commented Apr 10, 2019 at 15:39
Add a ment  | 

1 Answer 1

Reset to default 13

ES5 functions have their own this, so change

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

either to an ES6 arrow function (which have the same this as the context they're defined in)

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

or use explicit binding with 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))

or use a closure:

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"})
  }
})
发布评论

评论列表(0)

  1. 暂无评论