Vue.js CRUD application

In this example below you will see how to do a Vue.js CRUD application with some HTML / CSS and Javascript

Thumbnail
This awesome code was written by -a, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright -a ©

Technologies

  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>Vue.js CRUD application</title>
  
  
  <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css'>
<link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap-theme.min.css'>

      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

  <html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <title>Vue.js CRUD application</title>
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>

<div class="container">
  <header class="page-header">
    <div class="branding">
      <img src="https://vuejs.org/images/logo.png" alt="Logo" title="Home page" class="logo"/>
      <h1>Vue.js CRUD application</h1>
    </div>
  </header>
  <div class="alert alert-warning">
    <strong>Outdated!</strong> Vue 2 implementation can be found <a href="https://codepen.io/mevdschee/pen/BpbEbj">here</a>.
  </div>
  <main id="app">
    <router-view></router-view>
  </main>
</div>

<template id="product-list">
  <div class="actions">
    <a class="btn btn-default" v-link="{path: '/add-product'}">
      <span class="glyphicon glyphicon-plus"></span>
      Add product
    </a>
  </div>
  <div class="filters row">
    <div class="form-group col-sm-3">
      <label for="search-element">Product name</label>
      <input v-model="searchKey" class="form-control" id="search-element" requred/>
    </div>
  </div>
  <table class="table">
    <thead>
    <tr>
      <th>Name</th>
      <th>Description</th>
      <th>Price</th>
      <th class="col-sm-2">Actions</th>
    </tr>
    </thead>
    <tbody>
    <tr v-for="product in products | filterBy searchKey in 'name'">
      <td>
        <a v-link="{name: 'product', params: {product_id: product.id}}">{{ product.name }}</a>
      </td>
      <td>{{ product.description }}</td>
      <td>
        {{ product.price }}
        <span class="glyphicon glyphicon-euro" aria-hidden="true"></span>
      </td>
      <td>
        <a class="btn btn-warning btn-xs" v-link="{name: 'product-edit', params: {product_id: product.id}}">Edit</a>
        <a class="btn btn-danger btn-xs" v-link="{name: 'product-delete', params: {product_id: product.id}}">Delete</a>
      </td>
    </tr>
    </tbody>
  </table>
</template>

<template id="add-product">
  <h2>Add new product</h2>
  <form v-on:submit="createProduct">
    <div class="form-group">
      <label for="add-name">Name</label>
      <input class="form-control" id="add-name" v-model="product.name" required/>
    </div>
    <div class="form-group">
      <label for="add-description">Description</label>
      <textarea class="form-control" id="add-description" rows="10" v-model="product.description"></textarea>
    </div>
    <div class="form-group">
      <label for="add-price">Price, <span class="glyphicon glyphicon-euro"></span></label>
      <input type="number" class="form-control" id="add-price" v-model="product.price"/>
    </div>
    <button type="submit" class="btn btn-primary">Create</button>
    <a v-link="'/'" class="btn btn-default">Cancel</a>
  </form>
</template>

<template id="product">
  <h2>{{ product.name }}</h2>
  <b>Description: </b>
  <div>{{ product.description }}</div>
  <b>Price:</b>
  <div>{{ product.price }}<span class="glyphicon glyphicon-euro"></span></div>
  <br/>
  <span class="glyphicon glyphicon-arrow-left" aria-hidden="true"></span>
  <a v-link="'/'">Backt to product list</a>
</template>

<template id="product-edit">
  <h2>Edit product</h2>
  <form v-on:submit="updateProduct">
    <div class="form-group">
      <label for="edit-name">Name</label>
      <input class="form-control" id="edit-name" v-model="product.name" required/>
    </div>
    <div class="form-group">
      <label for="edit-description">Description</label>
      <textarea class="form-control" id="edit-description" rows="3" v-model="product.description"></textarea>
    </div>
    <div class="form-group">
      <label for="edit-price">Price, <span class="glyphicon glyphicon-euro"></span></label>
      <input type="number" class="form-control" id="edit-price" v-model="product.price"/>
    </div>
    <button type="submit" class="btn btn-primary">Save</button>
    <a v-link="'/'" class="btn btn-default">Cancel</a>
  </form>
</template>

<template id="product-delete">
  <h2>Delete product {{ product.name }}</h2>
  <form v-on:submit="deleteProduct">
    <p>The action cannot be undone.</p>
    <button type="submit" class="btn btn-danger">Delete</button>
    <a v-link="'/'" class="btn btn-default">Cancel</a>
  </form>
</template>

</body>
</html>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/vue-router/0.7.13/vue-router.min.js'></script>

  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/-a/vuejs-crud-application-amOYGp */
.logo {
  width: 50px;
  float: left;
  margin-right: 15px;
}

.form-group {
  max-width: 500px;
}

.actions {
  padding: 10px 0;
}

.glyphicon-euro {
  font-size: 12px;
}


/*Downloaded from https://www.codeseek.co/-a/vuejs-crud-application-amOYGp */
var products = [
  {id: 1, name: 'Angular', description: 'Superheroic JavaScript MVW Framework.', price: 100},
  {id: 2, name: 'Ember', description: 'A framework for creating ambitious web applications.', price: 100},
  {id: 3, name: 'React', description: 'A JavaScript Library for building user interfaces.', price: 100}
];

function findProduct (productId) {
  return products[findProductKey(productId)];
};

function findProductKey (productId) {
  for (var key = 0; key < products.length; key++) {
    if (products[key].id == productId) {
      return key;
    }
  }
};

var List = Vue.extend({
  template: '#product-list',
  data: function () {
    return {products: products, searchKey: ''};
  }
});

var Product = Vue.extend({
  template: '#product',
  data: function () {
    return {product: findProduct(this.$route.params.product_id)};
  }
});

var ProductEdit = Vue.extend({
  template: '#product-edit',
  data: function () {
    return {product: findProduct(this.$route.params.product_id)};
  },
  methods: {
    updateProduct: function () {
      var product = this.$get('product');
      products[findProductKey(product.id)] = {
        id: product.id,
        name: product.name,
        description: product.description,
        price: product.price
      };
      router.go('/');
    }
  }
});

var ProductDelete = Vue.extend({
  template: '#product-delete',
  data: function () {
    return {product: findProduct(this.$route.params.product_id)};
  },
  methods: {
    deleteProduct: function () {
      products.splice(findProductKey(this.$route.params.product_id), 1);
      router.go('/');
    }
  }
});

var AddProduct = Vue.extend({
  template: '#add-product',
  data: function () {
    return {product: {name: '', description: '', price: ''}
    }
  },
  methods: {
    createProduct: function() {
      var product = this.$get('product');
      products.push({
        id: Math.random().toString().split('.')[1],
        name: product.name,
        description: product.description,
        price: product.price
      });
      router.go('/');
    }
  }
});

var router = new VueRouter();
router.map({
  '/': {component: List},
  '/product/:product_id': {component: Product, name: 'product'},
  '/add-product': {component: AddProduct},
  '/product/:product_id/edit': {component: ProductEdit, name: 'product-edit'},
  '/product/:product_id/delete': {component: ProductDelete, name: 'product-delete'}
})
  .start(Vue.extend({}), '#app');

Comments