2
votes

I have the following app.js file as main Vue component.

import './bootstrap';
import router from './routes';

new Vue({
    el: '#app',
    router: router

});

My bootstrap.js is the following

import Vue from 'vue';
import VueRouter from 'vue-router';
import axios from 'axios';

// Global variable for API access
window.hostname = 'https://city.molotex.ru/cgi-bin/citygate.py?';

// Global variable for VueJS
window.Vue = Vue;

// Vue router
Vue.use(VueRouter);

//Vue Resource
var VueResource = require('vue-resource');
Vue.use(VueResource);

// axios
window.axios = axios;

window._ = require('lodash');

try {
    window.$ = window.jQuery = require('jquery');

    require('bootstrap-sass');
} catch (e) {}

window.axios.defaults.headers.common['X-CSRF-TOKEN'] = window.Laravel.csrfToken;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

My Login Vue is the following:

<template>

                        <form class="form-horizontal" role="form" method="POST" action="login">

                            <div class="form-group">
                                <label for="email" class="col-md-4 control-label">Логин (email)</label>

                                <div class="col-md-6">
                                    <input id="email" type="email" class="form-control" name="email" v-model="email">
                                </div>
                            </div>

                            <div class="form-group">
                                <label for="password" class="col-md-4">Пароль</label>

                                <div class="col-md-6">
                                    <input id="password" type="password" class="form-control" name="password" v-model="password">
                                </div>
                            </div>

                            <div class="form-group">
                                <div class="col-md-8 col-md-offset-4">
                                    <button type="button" v-on:click="login" class="btn btn-primary">
                                        Login
                                    </button>
                                </div>
                            </div>
                        </form>

</template>

<script>
    export default {
        mounted() {
            console.log('Component is mounted.');
        },

        data() {
            return {
                email: '',
                password: '',

                response_key: ''
            }
        },

        methods: {
            login() {
                let self = this;

                axios.post('/login', {
                    email: this.email,
                    password: this.password
                }).then(function (response) {
                    self.response_key = response.data.result;
                    this.$router.push('/user_main_page');
                        console.log(response);
                }).catch(function (error) {
                        console.log(error);
                });
            }
        }
    }
</script>

And my routes file is the following:

import VueRouter from 'vue-router';

let routes = [
    {
        path: '/',
        component: require('./components/Example.vue')
    },
    {
        path: '/about',
        component: require('./components/About.vue')
    },
    {
        path: '/login',
        component: require('./components/Login.vue')
    },
    {
        path:'/user_main_page',
        component: require('./components/UserMainPage.vue')
    }
];

export default new VueRouter({
    routes
});

But when I have the following error:

TypeError: Cannot read property '$router' of undefined at app.js:4341 at

I tried different types of routing such as: using global route variable as: window.router = VueRouter;

or importing VueRouter inside the component, but neither of this approaches helped. What am I doing wrong, how to make Router work.

3
this.$router should be self.$routerthanksd

3 Answers

5
votes

I'm assuming that the codes that you posted are all that there is and the error you are encountering can be traced down at this block at the Login Vue component, where you refer to the $router variable.

    axios.post('/login', {

        email: this.email,
        password: this.password

    }).then(function (response) {

        self.response_key = response.data.result;
        this.$router.push('/user_main_page');
        console.log(response);

    }).catch(function (error) {

        console.log(error);
    });

Although this.$router is the correct syntax for accessing the router dependency, calling it inside a callback function, using the regular function expression, creates a new binding to the "this" object instead of the Vue object itself.

You have two options to solve this:

  1. Store the object reference into a variable vm outside the callback function.
    const vm = this;
    axios.post('/login', {

        email: this.email,
        password: this.password

    }).then(function (response) {

        self.response_key = response.data.result;
        vm.$router.push('/user_main_page');
        console.log(response);

    }).catch(function (error) {

        console.log(error);

    });
  1. Use the arrow syntax when creating the function such that your reference to "this" is not overwritten. (Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
     axios.post('/login', {
         email: this.email,
         password: this.password
     }).then(response => {

         self.response_key = response.data.result;
         this.$router.push('/user_main_page');
         console.log(response);

     }).catch(error => {

         console.log(error);

     });
1
votes

1:

then(function (response) {
   self.response_key = response.data.result;
   this.$router.push('/user_main_page');
   console.log(response);
}.bind(this))

2: In ES6:

then((response) => {
   self.response_key = response.data.result;
   this.$router.push('/user_main_page');
   console.log(response);
})
0
votes

In Login Vue file, change code

this.$router.push('/user_main_page');

to

self.$router.push('/user_main_page');

you have already defined

let self = this;

so using:

self.$router.push('/user_main_page');

will work.