简体   繁体   中英

Vue.js app no errors but white page

I'm trying to learn Vue. I read this tutorial and I'm trying to split it in single file components using the standard vue-cli webpack template. I don't have any error in console but the page is white, and I cannot understand why.

This is my main.js file

import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false
window.axios = require('axios');

const NYTBaseUrl = "https://api.nytimes.com/svc/topstories/v2/";
const ApiKey = "18e1540d187c4b46bae767782750f9fd";
const SECTIONS = "home, arts, automobiles, books, business, fashion, food, health, insider, magazine, movies, national, nyregion, obituaries, opinion, politics, realestate, science, sports, sundayreview, technology, theater, tmagazine, travel, upshot, world";

function buildUrl (url) {
  return NYTBaseUrl + url + ".json?api-key=" + ApiKey
}

const vm = new Vue({
  el: '#app',
  data: {
    results: [],
    sections: SECTIONS.split(', '), // create an array of the sections
    section: 'home', // set default section to 'home'
    loading: true,
    title: ''
  },
  mounted () {
    this.getPosts('home');
  },
  methods: {
    getPosts(section) {
      let url = buildUrl(section);
      axios.get(url).then((response) => {
        this.loading = false;
        this.results = response.data.results;
        let title = this.section !== 'home' ? "Top stories in '"+ this.section + "' today" : "Top stories today";
        this.title = title + "(" + response.data.num_results+ ")";
      }).catch((error) => { console.log(error); });
    }
  }
});

And this is the App.vue file

<template>
  <div id="app">
    <h1>Test</h1>
    <product-list></product-list>
  </div>
</template>

<script>
import Products from './components/Products'

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

<style lang="sass" >
  @import '~bulma/sass/utilities/initial-variables.sass'
  @import "~bulma/sass/utilities/_all"
  @import "~bulma/sass/base/_all"
  @import "~bulma/sass/grid/columns"
  @import "~bulma/sass/components/_all"
</style>

I also create a Products.vue file in the components folder

<template id="product-list">
  <section>
    <div class="row" v-for="posts in processedPosts">
      <div class="columns large-3 medium-6" v-for="post in posts">
        <div class="card">
        <div class="card-divider">
        {{ post.title }}
        </div>
        <a :href="post.url" target="_blank"><img :src="post.image_url"></a>
        <div class="card-section">
          <p>{{ post.abstract }}</p>
        </div>
      </div>
      </div>
    </div>
  </section>

</template>

Vue.component('Products', {
  props: ['results'],
  template: "#product-list",
  computed: {
    processedPosts() {
      let posts = this.results;

      // Add image_url attribute
      posts.map(post => {
        let imgObj = post.multimedia.find(media => media.format === "superJumbo");
        post.image_url = imgObj ? imgObj.url : "http://placehold.it/300x200?text=N/A";
      });

      // Put Array into Chunks
      let i, j, chunkedArray = [],
        chunk = 4;
      for (i = 0, j = 0; i < posts.length; i += chunk, j++) {
        chunkedArray[j] = posts.slice(i, i + chunk);
      }
      return chunkedArray;
    }
  }
});

Everything looks fine for me (except for the window.axios = require('axios'); that I don't understand why is not present in the original tutorial) but the page is blank and also the tag I add for debug is not present in the DOM.

Edit

Looks like the code is not compiled.

My page source code is

<body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  <script type="text/javascript" src="/app.js"></script>

</body>

** Edit 2 **

I understand the problem. This is my index.html.

There are several issues with your codes. First you have to wrap JavaScript in a script tag on your Products.vue file. Also on your Products.vue file you could just export the component files instead of creating the way you did, also you haven't imported Vue on Products.vue file but you are using it Vue.component('Products', {}) . You should create Products.vue file this way

Products.vue

<template>
  <section>
    <div class="container" v-for="posts in processedPosts">
      <div class="columns" v-for="post in posts">
        <div class="column is-6 is-offset-3">
           <div class="card">
           <header class="card-header">
             <p class="card-header-title">
            {{ post.title }}
            </p>
           </header>
           <div class="card-image">
           <a :href="post.url" target="_blank">
             <figure class="image">
               <img :src="post.image_url">
             </figure>
           </a>
           </div>

        <div class="card-content">
          <div class="content">
            <p>{{ post.abstract }}</p>
          </div>
        </div>
      </div>
        </div>
      </div>
    </div>
  </section>

</template>
<script>
export default{
  props: ['results'],
  computed: {
    processedPosts() {
      let posts = this.results;
      // Add image_url attribute
      posts.map(post => {
        let imgObj = post.multimedia.find(media => media.format === "superJumbo");
        post.image_url = imgObj ? imgObj.url : "http://placehold.it/300x200?text=N/A";
      });

      // Put Array into Chunks
      let i, j, chunkedArray = [],
        chunk = 4;
      for (i = 0, j = 0; i < posts.length; i += chunk, j++) {
        chunkedArray[j] = posts.slice(i, i + chunk);
      }
      return chunkedArray;
    }
  }  
}
</script>

On your main.js file you forgot to mount <App /> template.

new Vue({
  el: '#app',
  template: '<App/>',
  components: { App },
})

You should also move code for network request, components to App.vue file.

main.js

import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false
window.axios = require('axios');

new Vue({
  el: '#app',
  template: '<App/>',
  components: { App },
})

Have to use the component we are importing, on your code you imported Products but using <product-list></product-list> .

App.vue

<template>
  <div id="app">
    <products :results="results"></products>
  </div>
</template>

<script>
import Products from './components/Products'

const NYTBaseUrl = "https://api.nytimes.com/svc/topstories/v2/";
const ApiKey = "18e1540d187c4b46bae767782750f9fd";
const SECTIONS = "home, arts, automobiles, books, business, fashion, food, health, insider, magazine, movies, national, nyregion, obituaries, opinion, politics, realestate, science, sports, sundayreview, technology, theater, tmagazine, travel, upshot, world";

function buildUrl (url) {
  return NYTBaseUrl + url + ".json?api-key=" + ApiKey
}

export default {
  name: 'app',
  data: function(){
    return {
    results: [],
    sections: SECTIONS.split(', '), // create an array of the sections
    section: 'home', // set default section to 'home'
    loading: true,
    title: ''
    }
  },
  components: {
    Products
  },
  mounted(){
    this.getPosts('home');
  },
  methods:{
    getPosts(section) {
      let url = buildUrl(section);
      axios.get(url).then((response) => {
        this.loading = false;
        this.results = response.data.results;
        let title = this.section !== 'home' ? "Top stories in '"+ this.section + "' today" : "Top stories today";
        this.title = title + "(" + response.data.num_results+ ")";
      }).catch((error) => { console.log(error); });
    }    
  }
}
</script>

I tested this out, and uploaded code to github https://github.com/azs06/vuejs-news , you can clone it and check it out. Here it is deployed http://noisy-coach.surge.sh/

Note: I am using the api key temporarily will remove it, as soon as you test it out.

Next time to debug your code - first you should take a look at browser console for errors.

You can see full code of this tutorial here - https://github.com/sitepoint-editors/vuejs-news Just make sure you write code like it's shown on github files.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM