How to Use vue-resource In Vue.js

The vue-resource is a well-known HTTP request library in VueJS. Of course, you can also use axios and jQuery if you want, but today we will attempt HTTP calls using vue-resource.

For the backend API, we are using Laravel Framework. For this project, we are using Vue along with vue-router and vue-resource.

Here are the steps to use vue-resource in Vue.

Step 1: Create a project folder.

Create one project folder called VueResource.

mkdir VueResource

In the root, create one file called package.json and copy the following code to it.

{
  "name": "vueresorce",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.25.0",
    "babel-loader": "^7.1.1",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-stage-3": "^6.24.1",
    "babel-runtime": "^6.25.0",
    "vue-loader": "^13.0.2",
    "vue-template-compiler": "^2.4.2",
    "webpack": "^3.4.1",
    "webpack-dev-server": "^2.6.1"
  },
  "dependencies": {
    "vue": "^2.4.2",
    "vue-resource": "^1.3.4",
    "vue-router": "^2.7.0"
  }
}

Go to your terminal and type the following command.

npm install

It will install all of our NPM dependencies in our project.

The next step would be configuring the webpack, so in the root folder, create one file called webpack.config.js and put the following code in it.

// webpack.config.js

module.exports = {
  // This is the "main" file which should include all other modules
  entry: './src/main.js',
  // Where should the compiled file go?
  output: {
    filename: 'bundle.js'
  },
  resolve: {
  alias: {
    vue: 'vue/dist/vue.js'
  }
},
  module: {
    // Special compilation rules
    loaders: [
      {
        // Ask webpack to check: If this file ends with .js, then apply some transforms
        test: /\.js$/,
        // Transform it with babel
        loader: 'babel-loader',
        // don't transform node_modules folder (which don't need to be compiled)
        exclude: /node_modules/
      },
      {
        // Ask webpack to check: If this file ends with .vue, then apply some transforms
        test: /\.vue$/,
        // don't transform node_modules folder (which don't need to be compiled)
        exclude: /(node_modules|bower_components)/,
        // Transform it with vue
      use: {
        loader: 'vue-loader'
      }
    }
  ]
},
devServer: {
       port: 3000
   }
}

Webpack is a module bundler without a main JavaScript file. It will compile to ES5 with the help of Babel and run the code in any of the older browsers. So webpack will create the bundle.js file.

Step 2: Create index.html and main.js file.

Create one folder called src in your root directory, and create another folder called components.

Create one index.html file in a root folder.

<!-- index.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>vue-resource example in VueJS</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  </head>
  <body>
    <script src="bundle.js"></script>
  </body>
</html>

Create a main.js file inside the src directory, and this file would be our final javascript file in the sense of development, and it will be compiled with webpack and generates the bundle.js file.

Create one div tag inside the index.html and give the id app.

<!-- index.html -->

<body>
    <div id="app"></div>
    <script src="bundle.js"></script>
</body>

In the main.js file, put the following code in it.

// main.js

import Vue from 'vue';

import VueRouter from 'vue-router';
Vue.use(VueRouter);

import VueResource from 'vue-resource';
Vue.use(VueResource);

var router = new VueRouter({mode: 'history'});
new Vue(Vue.util.extend({ router })).$mount('#app');

Step 3: Set up a router and create the App.vue file.

A further step would be creating one App.vue file inside the src folder and not the components folder.

// App.vue

<template>
    <div class="container">
        <div id="page">
            <transition name="fade">
                <router-view></router-view>
            </transition>
        </div>
    </div>
</template>

<style>
    .fade-enter-active, .fade-leave-active {
      transition: opacity .5s
    }
    .fade-enter, .fade-leave-active {
      opacity: 0
    }
</style>

<script>

    export default{
    }
</script>

This is our container file, and all the components are rendered within this file. It is the container for our application, and when the route changes, the underlying components also change, but here the point is that the page will not be refreshed.

The <router-view></router-view> is the tag in which the route components will be rendered, and we can perform different actions and operations within that component.

We need to include this component in our main.js file so that routes can be configured correctly.

// main.js

import App from './App.vue';

new Vue(Vue.util.extend({ router }, App)).$mount('#app');

At the instance creation,  I passed the App component to the application.

We have registered the routes, but we have not defined them yet, so first, we need to define an array of routes, and then we will pass it as a constructor argument while creating a router object, and that’s how our routing task will be complete.

// main.js

const routes = [
  {
        name: 'Products',
        path: '/',
        component: Products
  }
];

var router = new VueRouter({ mode: 'history', routes: routes });
new Vue(Vue.util.extend({ router }, App)).$mount('#app');

We have not created the Products component yet, but We have registered the route and passed this array to the router constructor. So first, create that Products.vue component.

// Products.vue

<template>
    <div>
        <table class="table table-striped">
            <thead>
            <tr>
                <td>ID</td>
                <td>Name</td>
                <td>Price</td>
                <td>Actions</td>
            </tr>
            </thead>
            <tbody>
            </tbody>
        </table>
    </div>
</template>

<script>
    export default{
        
    }
</script>

Import this component into the main.js file, where we have registered the array of routes.

// main.js

import Products from './components/Products.vue';

Step 4: Create a Laravel backend.

Create a Laravel backend for the data. So first step would be to download this framework from its original website. 

https://laravel.com/docs/10.x

composer create-project laravel/laravel VueResourceLaravel --prefer-dist

Set up the database in a .env file. Now create the Product model and migrations by typing the following command.

php artisan make:model Product -m

It will also create a products migration. Finally, we need to define the columns in that migrations.

<?php

// create_products_migrations_table.php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateProductsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->integer('price');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('products');
    }
}

Run the following command to run the migrations.

php artisan migrate

It will create three tables, including products. If you have set up the database correctly, It will run perfectly.

Also, we need to create a controller file for our products data, so type the following command in the terminal.

php artisan make:controller ProductController --resource

Step 5: Seed the data in the database.

Seed the fake data in the products table. So type the following command in your terminal to fill in the fake data using Database Seeder.

php artisan make:seeder ProductsTableSeeder

Go to the ProductsTableSeeder.php file inside the database  >>  seeds  >>  ProductsTableSeeder

<?php

// ProductsTableSeeder

use Illuminate\Database\Seeder;

class ProductsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
      \DB::table('products')->insert([
          'name' => str_random(10),
          'price' => rand()
      ]);
      \DB::table('products')->insert([
          'name' => str_random(10),
          'price' => rand()
      ]);
      \DB::table('products')->insert([
          'name' => str_random(10),
          'price' => rand()
      ]);
      \DB::table('products')->insert([
          'name' => str_random(10),
          'price' => rand()
      ]);
      \DB::table('products')->insert([
          'name' => str_random(10),
          'price' => rand()
      ]);
      \DB::table('products')->insert([
          'name' => str_random(10),
          'price' => rand()
      ]);
      \DB::table('products')->insert([
          'name' => str_random(10),
          'price' => rand()
      ]);
    }
}

Go to the database  >>  seeds  >>  DatabaseSeeder.php. Put the following code on it.

<?php

// DatabaseSeeder.php

/**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $this->call(ProductsTableSeeder::class);
    }

Go to your terminal and type the following command.

php artisan db:seed

It will generate the data according to our insertion defined in the ProductsTableSeeder.php file.

Step 6: Set up routes and controllers for backend data. 

We are creating the API at the backend of Laravel. So in Laravel, you can use api.php for routing and not web.php because we are just calling an API. So go to the routes  >>  api.php and define one route.

// routes >> api.php

Route::get('products','ProductController@index');

In ProductController, first, we need to include the Product.php model in the app folder and then fire a query to retrieve the data.

<?php

// ProductController.php

use App\Product;

/**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $products = Product::all();
        return response()->json($products);
    }

It will return the response in JSON format. All the products are sent in JSON, and Frontend VueJS will consume it and display the Products.

Step 7: Need to create the product’s index component.

We need to set up API points in VueJS. So, go to the VueJS project and copy the whole code in the Products.vue file.

// Products.vue

<template>
    <div>
        <table class="table table-striped">
            <thead>
            <tr>
                <td>ID</td>
                <td>Name</td>
                <td>Price</td>
            </tr>
            </thead>
            <tbody>
            </tbody>
        </table>
    </div>
</template>

<script>
    export default{
      data(){
            return{
                products: []
            }
        },
      created: function()
      {
          this.fetchProducts();
      },
      methods: {
        fetchProducts(){
          {
              this.$http.get('http://localhost:8000/api/products').then((response) => {
                  this.products = response.body;
              });
          }
        }
      }
    }
</script>

Also, you need to start the Laravel server by typing the following command in Laravel Project.

php artisan serve

Now, if you switch the URL: http://localhost:3000, you get an error in the Console panel.

Possible Errors: XMLHttpRequest cannot load http://localhost:8000/api/products. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:3000’ is therefore not allowed access. The response had HTTP status code 500.

This error is caused by CORS security. When Browser hits the request to another domain, by default, it denies the request. 

Possible Solutions: We must allow this origin to the Laravel server side. So we need to create one middleware at the backend and apply this middleware to every API request. By putting this middleware, we are explicitly told Laravel that we are allowing this request to access our resources.

Download the following Laravel Specific CORS package to avoid this issue and follow the steps.

composer require barryvdh/laravel-cors 

Add the Cors\ServiceProvider to your config/app.php provider’s array

Barryvdh\Cors\ServiceProvider::class,

To allow CORS for all your routes, add the HandleCors middleware in the $middleware property of app/Http/Kernel.phpclass:

protected $middleware = [
    // ...
    \Barryvdh\Cors\HandleCors::class,
];

You can publish the config using this command:

php artisan vendor:publish --provider="Barryvdh\Cors\ServiceProvider"

Try again from the VueJS project, and you will get the data.

Step 8: Fetch and display data.

Fill this data in the table. Next, go to the Products.vue file and update the whole code by following the code.

// Products.vue

<template>
    <div>
        <table class="table table-striped">
            <thead>
            <tr>
                <td>ID</td>
                <td>Name</td>
                <td>Price</td>
            </tr>
            </thead>
            <tbody>
              <tr v-for="product in products">
                  <td>{{ product.id }}</td>
                  <td>{{ product.name }}</td>
                  <td>{{ product.price }}</td>
              </tr>
            </tbody>
        </table>
    </div>
</template>

<script>
    export default{
      data(){
            return{
                products: []
            }
        },
      created: function()
      {
          this.fetchProducts();
      },
      methods: {
        fetchProducts(){
          {
              this.$http.get('http://localhost:8000/api/products').then((response) => {
                console.log(response.body);
                  this.products = response.body;
              });
          }
        }
      }
    }
</script>

It will look like this.

Laravel 5.4 and VueJS 2.0

That’s it!

Download Vue.js Project On Github

Download Laravel Project On Github

1 thought on “How to Use vue-resource In Vue.js”

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.