Mxkert
Mxkert

Reputation: 346

Import data from a JSON file in Vue.js instead of manual data

This is my first time using Vue.js. I made this app which uses data that I manually added in the script. Now I would like to be able to add a JSON file from which it fetches the data, but I have no idea how I could do this. Below you can find my code.

HTML:

<div id="app">

<div class="search-wrapper">
    <input type="text" v-model="keyword" placeholder="Zoek telefoon..." />
</div>

<div class="wrapper">

    <table style="width:100%; text-align: left;">
      <tr>
        <th style="text-align: left; width: 33%">Telefoon</th>
        <th style="text-align: left; width: 33%">Scherm</th> 
        <th style="text-align: left; width: 33%">Batterij</th>
      </tr>
    </table>

    <div v-for="post in filteredList">        
        <table style="width:100%; text-align: left">
          <tr style="text-align: left;">
            <td style="text-align: left; width: 33%">{{ post.title }}</td>
            <td style="text-align: left; width: 33%">{{ post.scherm }}</td> 
            <td style="text-align: left; width: 33%">{{ post.batterij }}</td>
          </tr>
        </table>
    </div>

</div>

Vue.js:

var app = new Vue({
  el: '#app',
  data: {
    keyword: '',
    postList: [
      { title: 'A', scherm: '35', batterij: '15' },
      { title: 'B', scherm: '65', batterij: '25' },
      { title: 'C', scherm: '40', batterij: '35' },
      { title: 'D', scherm: '35', batterij: '75' },
      { title: 'E', scherm: '20', batterij: '45' },
    ],
  },
  computed: {
    filteredList() {
      return this.postList.filter((post) => {
        return post.title.toLowerCase().includes(this.keyword.toLowerCase());
      });
    }
  }
});

EDIT: My code now looks like this, but it now only returns {{ post.title }} etc.

Head:

<head>
<title>Test Vue JSON</title>
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vue-axios.min.js"></script>

HTML:

<div class="search-wrapper">
    <input type="text" v-model="keyword" placeholder="Zoek telefoon..." />
</div>

<div class="wrapper">

    <table style="width:100%; text-align: left;">
      <tr>
        <th style="text-align: left; width: 33%">Telefoon</th>
        <th style="text-align: left; width: 33%">Scherm</th> 
        <th style="text-align: left; width: 33%">Batterij</th>
      </tr>
    </table>

    <div v-for="post in filteredList">        
        <table style="width:100%; text-align: left">
          <tr style="text-align: left;">
            <td style="text-align: left; width: 33%">{{ post.title }}</td>
            <td style="text-align: left; width: 33%">{{ post.scherm }}</td> 
            <td style="text-align: left; width: 33%">{{ post.batterij }}</td>
          </tr>
        </table>
    </div>

</div>

Script:

import posts from "../posts.json";

  el: '#app',
  data: {
    keyword: '',
    postList: [],
  },
  computed: {
    filteredList() {
      return this.postList.filter((post) => {
        return post.title.toLowerCase().includes(this.keyword.toLowerCase());
      });
    }
  },
  mounted(){
   axios
       .get('posts.json')
       .then(response => (this.postList = response.data))
       }
    }

JSON (posts.json):

  [
    { title: "Samsung Galaxy S9", scherm: "35", batterij: "15" },
    { title: "Huawei P10", scherm: "65", batterij: "25" },
    { title: "iPhone X", scherm: "40", batterij: "35" },
    { title: "Huawei P20 Lite", scherm: "35", batterij: "75" },
    { title: "Samsung A9", scherm: "20", batterij: "45" },
 ]

Upvotes: 2

Views: 15711

Answers (2)

fredrivett
fredrivett

Reputation: 6576

To import a dynamic file path using Vue 2 you can use the import method inside methods like created or watch:

import Vue from "vue";

export default Vue.extend({
  data() {
    return {
      dynamicPath: "my-path",
      importResult: null,
    };
  },
  created() {
    import(`@/${this.dynamicPath}/my-file.json`).then((module) => {
      this.importResult = module.default;
    });
  },
}

Upvotes: 1

Boussadjra Brahim
Boussadjra Brahim

Reputation: 1

Vue cli:

set that data inside a file called posts.json and import it as follows :

    import posts from "./posts.json";

and assign it to your postList in the mounted hook :

  computed:{
  .... 
  },  
  mounted(){
      this.postList=posts
        }

CDN

in your case you should use an AJAX api like axios

 computed:{
  .... 
  },  
  mounted(){
       axios
           .get('posts.json')
           .then(response => (this.postList = response.data))
           }
        }

and your should include the following scripts :

    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
   <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/vue-axios.min.js"></script>

Full example

var app = new Vue({
  el: '#app',
  data: {
    keyword: '',
    postList: []
  },
  computed: {
    filteredList() {
      return this.postList.filter((post) => {
        return post.title.toLowerCase().includes(this.keyword.toLowerCase());
      });
    }
  },
  mounted(){
    axios.get('https://jsonplaceholder.typicode.com/posts')
        .then((response)=> {
          this.postList=response.data;
        })
  }
});
<html lang="en" dir="ltr">

<head>
  <meta charset="utf-8">
  <title></title>
  <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <script src="https://unpkg.com/[email protected]/dist/vue-axios.min.js"></script>
</head>

<body>
  <div id="app">

  

    <div class="wrapper">

      <table style="width:100%; text-align: left;">
        <tr>
          <th style="text-align: left; width: 33%">ID</th>
          <th style="text-align: left; width: 33%">Title</th>
          <th style="text-align: left; width: 33%">Body</th>
        </tr>
      </table>

      <div v-for="post in postList">
        <table style="width:100%; text-align: left">
          <tr style="text-align: left;">
            <td style="text-align: left; width: 33%">{{ post.id }}</td>
            <td style="text-align: left; width: 33%">{{ post.title}}</td>
            <td style="text-align: left; width: 33%">{{ post.body }}</td>
          </tr>
        </table>
      </div>

    </div>
    </div>
</body>

Upvotes: 10

Related Questions