There are multiple issues with the codes you provided. Firstly, ensure that your JavaScript is wrapped in a script
tag within your Products.vue
file. Additionally, instead of creating the component files the way you did in Products.vue
, consider simply exporting them. You also forgot to import Vue
in your Products.vue
file while using it in Vue.component('Products', {})
. Here's how the structure of your Products.vue
file should look:
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>
In your main.js
file, don't forget to mount the <App />
template.
new Vue({
el: '#app',
template: '<App/>',
components: { App },
})
Additionally, move code for network requests and components to the 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 },
})
Ensure you are using the correct imported component in your code. If you're importing Products
, then use it as
<products></products>
.
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(', '),
section: '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 have tested and uploaded the code to GitHub https://github.com/azs06/vuejs-news. You can clone it and review. The deployed version can be accessed at
Note: I am temporarily using an API key which will be removed once you test it out.