【问题标题】:VueJS: components not renderingVueJS:组件不呈现
【发布时间】:2018-09-25 08:06:50
【问题描述】:

我正在阅读我的第一个 Vue 教程,但有点卡住了。我有一个 App.vue 文件,我可以看到浏览器检查器扩展正在加载,一个路由器 index.js 文件和登录/注册表格。我可以看到默认的 Hello 组件。

我应该可以访问 /login 和 /signup,但组件无法加载。没有控制台错误。我从哪里开始进行故障排除?

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>

路由器 index.js 文件:

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>

我的 main.js 文件:

// 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/>'
})

【问题讨论】:

  • 能不能发一下main.js文件(或者Vue实例化的文件)。我相信它缺少在 Vue 实例化中使用路由器(new Vue({ el: '#app', router, template: '&lt;App/&gt;', components: { App } })。看看scotch.io/tutorials/getting-started-with-vue-router。问候。
  • 这正是我的 main.js 文件的样子。见上文。

标签: vuejs2 vue-router


【解决方案1】:

我的错误是路由器配置。没有#,它不允许我去正确的路线。我需要将 mode:'history' 添加到新的 Router 对象。

正确的路由器配置:

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

【讨论】:

    【解决方案2】:

    您的主 Vue 实例需要将自己挂载到 #app 元素:

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

    这是一个 vue 路由器的基本示例。 Codepen

    main.js 中尝试其他一些事情:

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

    【讨论】:

    • 用其他一些建议更新了答案
    • 您使用的是哪个版本的vue lib? esm、运行时、通用?
    • 我使用的是 esm 版本。
    • 有趣的是,Hello World 组件确实会渲染。
    • 你是否在 webpack 中为前面添加了 @ 的导入添加了 resolve.alias 条目? '@/components/Auth/SignUpForm' 可能需要一个用于 Auth 文件夹。
    猜你喜欢
    • 2017-12-02
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    • 2018-11-18
    • 1970-01-01
    • 2017-06-26
    • 2021-04-29
    • 2016-10-26
    相关资源
    最近更新 更多