0

I'm going through my first Vue tutorial and am a bit stuck. I've got an App.vue file, which I can see with the browser inspector extension is loading, a router index.js file, and login/signup forms. I can see the default Hello component.

I should be able to go to /login and /signup, but the components do not load. There are no console errors. Where do I begin troubleshooting?

App.Vue:

<template>
  <div id="app">
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'app'
}
</script>

<style>
  body {
    background-color: #f7f7f7;
    padding-top: 50px;
    padding-bottom: 50px;
  }

  .is-danger {
    color: #9f3a38;
  }
</style>

Router index.js file:

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import SignUpForm from '@/components/Auth/SignUpForm'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },
    {
      path: '/signup',
      component: SignUpForm
    }
  ]
}))

SignUpForm.vue:

<template>
  <div class="ui stackable three column centered grid container">
    <div class="column">
      <h2 class="ui dividing header">Sign Up, it's free!</h2>

      <Notification
        :message="notification.message"
        :type="notification.type"
        v-if="notification.message"
      />

      <form class="ui form" @submit.prevent="signup">
        <div class="field" :class="{ error: errors.has('name') }">
          <label>Full Name</label>
          <input type="text" name="name" v-model="name" v-validate="'required'" placeholder="Full name">
          <span v-show="errors.has('name')" class="is-danger">{{ errors.first('name') }}</span>
        </div>

        <div class="field" :class="{ error: errors.has('username') }">
          <label>Username</label>
          <input type="text" name="username" :class="{'input': true, 'is-danger': errors.has('username') }" v-model="username" v-validate="'required'" placeholder="Username">
          <span v-show="errors.has('username')" class="is-danger">{{ errors.first('username') }}</span>
        </div>

        <div class="field" :class="{ error: errors.has('email') }">
          <label>Email</label>
          <input type="email" name="email" :class="{'input': true, 'is-danger': errors.has('email') }" v-model="email" v-validate="'required|email'" placeholder="Email">
          <span v-show="errors.has('email')" class="is-danger">{{ errors.first('email') }}</span>
        </div>

        <div class="field" :class="{ error: errors.has('password') }">
          <label>Password</label>
          <input type="password" name="password" :class="{'input': true, 'is-danger': errors.has('password') }" v-model="password" v-validate="'required'" placeholder="Password">
          <span v-show="errors.has('password')" class="is-danger">{{ errors.first('password') }}</span>
        </div>

        <button class="fluid ui primary button" :disabled="!isFormValid">SIGN UP</button>

        <div class="ui hidden divider"></div>
      </form>

      <div class="ui divider"></div>

      <div class="ui column grid">
        <div class="center aligned column">
          <p>
            Got an account? <router-link to="/login">Log In</router-link>
          </p>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import Notification from '@/components/Notification'

export default {
  name: 'SignUpForm',
  components: {
    Notification
  },
  data () {
    return {
      name: '',
      username: '',
      email: '',
      password: '',
      notification: {
        message: '',
        type: ''
      }
    }
  },
  computed: {
    isFormValid () {
      return Object.keys(this.fields).every(key => this.fields[key].valid)
    }
  },
  beforeRouteEnter (to, from, next) {
    const token = localStorage.getItem('tweetr-token')

    return token ? next('/') : next()
  },
  methods: {
    signup () {
      axios// eslint-disable-line no-use-before-define
        .post('/signup', {
          name: this.name,
          username: this.username,
          email: this.email,
          password: this.password
        })
        .then(response => {
          // save token in localstorage
          localStorage.setItem('tweetr-token', response.data.data.token)

          // redirect to user home
          this.$router.push('/')
        })
        .catch(error => {
          // display error notification
          this.notification = Object.assign({}, this.notification, {
            message: error.response.data.message,
            type: error.response.data.status
          })
        })
    }
  }
}
</script>

My main.js file:

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'
import VeeValidate from 'vee-validate'

window.axios = axios
axios.defaults.baseURL = 'http://127.0.0.1:3333'

Vue.config.productionTip = false
Vue.use(VeeValidate)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})
2
  • 1
    Can you post the main.js file (or the file where Vue is instantiated). I believe it is missing the use of the router in the Vue instantiation (new Vue({ el: '#app', router, template: '<App/>', components: { App } }). Take a look at scotch.io/tutorials/getting-started-with-vue-router. Regards. Commented Apr 15, 2018 at 14:24
  • That's exactly what my main.js file looks like. See above. Commented Apr 16, 2018 at 6:16

2 Answers 2

1

Your main Vue instance needs to mount itself to the #app element:

new Vue({
    router
}).$mount('#app');

Here's a basic example with vue router. Codepen

Couple other things to try in main.js:

// render function
new Vue({
  el: '#app',
  router,
  render: h => h(App)
})

// component
new Vue({
  el: '#app',
  router,
  App
})
Sign up to request clarification or add additional context in comments.

6 Comments

Updated the answer with a couple other suggestions
Which version of the vue lib are you using? esm, runtime, common?
I'm using the esm version.
Interestingly, the Hello World component DOES render.
Have you added resolve.alias entries in webpack for the imports prepended with @? The '@/components/Auth/SignUpForm' may need one for the Auth folder.
|
1

My mistake was router configuration. It was not allowing me to go to the proper route without a #. I needed to add mode:'history' to the new Router object.

Proper router configuration:

export default new Router({
  mode: 'history',
  routes: [
    blahblahblah
  ]
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.