+1

Vuejs với Rails

Mở đầu

Vuejs được biết đến là một progressive framework dùng để xây dựng giao diện người dùng và được sử dụng rộng rải với cộng đồng php cụ thể là framework laravel việc sử dụng nên vuejs trên rails vẫn còn ít nên tôi sẽ demo cho các bạn một ví dụ nhỏ việc kết hợp vuejs và rails

Cài đặt Vuejs

Đầu tiên chúng ta có thể tạo mới một project để làm ví dụ:

rails new vuejs_project

sau khi tạo mới một project chúng ta bắt đầu cài đặt vuejs bằng cách cài đặt gem vuejs-rails

gem 'vuejs-rails'

sau đó đi tới file application.js thêm vào các dòng sau: //= require vue //= require vue-router (optional) //= require vue-resource (optional) //= require vuex (optional) đồng thời khuyến cáo các bạn có đang xài TurboLinks (thường được cài đặt mặc định khi khởi tạo ứng dụng mới) nên vô hiệu hóa nó vì nó sẽ khiến các trang tải mà không tải lại Javascript. sau đó trong app/views/layouts/application.html.erb, di chuyển dòng này từ phần đầu của xuống phía dưới thẻ body

<% = javascript_include_tag 'application'%>

việc cài đặt đã xong. để bắt đầu ví dụ chúng ta xây dựng những phần cần thiết như sau: đầu tiên chúng ta tạo một model products:

rails g model Product name:string price:integer manager:string

sau đó chúng ta tạo một controller tương ứng:

rails g controller products 

Để chạy được chúng ta cung phải thêm vào routes cho nó

resources :products, only: [:index, :new, :edit]

tạo danh sách products

chúng ta sẽ tạo action index trả về danh sách tất cả sản phẩm dưới dạng json:

def index
    @products = Product.all
    respond_to do |format|
      format.html
      format.json { render :json => @products }
    end
  end

sau đó chúng ta sử dụng vuejs để load list products:

// app/assets/javascripts/products.js
var products = new Vue({
  el: '#products',
  data: {
    products: []
  },
  ready: function() {
    var that;
    that = this;
    $.ajax({
      url: '/products.json',
      success: function(res) {
        that.products = res;
      }
    });
  }
});

view:

<!-- app/views/products/index.html -->
<h1>List Products</h1>

<div id="products">
  <table>
    <thead>
      <tr>
        <th>Name</th>
        <th>price</th>
        <th>Manager</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="product in products">
        <td>{{ employee.name }}</td>
        <td>{{ employee.price }}</td>
        <td>{{ employee.manager }}</td>
      </tr>
    </tbody>
  </table>
</div>

tách component ra dùng chung Vì đoạn này chúng ta sử dụng lại nhiều lần nên tốt nhất nên tách nó thành một component:

// app/assets/javascripts/products.js
Vue.component('product-row', {
  template: '#product-row',
  props: {
    product: Object
  }
})

bổ sung vào index template

<!-- app/views/products/index.html -->
<script type="text/x-template" id="products-row">
  <tr>
    <td>{{ product.name }}</td>
    <td>{{ product.price }}</td>
    <td>{{ product.manager }}</td>
  </tr>
</script>

<!-- ... -->

đồng thời thay đổi thẻ <tr> bên trong <tbody>

 <tbody>
      <tr
        is="product-row"
        v-for="product in products"
        :product="product">
      </tr>
    </tbody>

thêm một sản phẩm mới

để thêm một sản phẩm mới chungs ta phải thêm một row vào table gồm các thông số đã thiết lập như name, price và manager status. Component products sẽ cần một object mới khi product được tạo, đồng thời một hash errors để handle errors.

// app/assets/javascripts/products.js
var products = new Vue({
  el: '#products',
  data: {
    products: [],
    product: {
      name: '',
      price: '',
      manager: false
    },
    errors: {}
  },
// ...

tiếp theo trong controller chúng ta tạo action create để xử lý việc này trả về object nếu như success và errors nếu lỗi:

# app/controllers/products_controller.rb

  def create
    @product = Product.new product_params
    respond_to do |format|
      format.json do 
        if @product.save
          render :json => @product
        else
          render :json => { :errors => @product.errors.messages }, status: 422
        end
      end
    end
  end

  private

  def product_params
    params.require(:product).permit(:name, :price, :manager)
  end
end

Chúng ta sẽ thêm method hireProduct vào Vue instance, và nó sẽ được gọi khi Hire button được clicked. Hàm nãy sẽ tạo một ajax để insert products vào hệ thống.

// app/assets/javascripts/products.js
  methods: {
    hireProduct: function () {
      var that = this;
      $.ajax({
        method: 'POST',
        data: {
          product: that.product,
        },
        url: '/products.json',
        success: function(res) {
          that.errors = {}
          that.products.push(res);
        },
        error: function(res) {
          that.errors = res.responseJSON.errors
        }
      })
    }
  }

view

<!-- app/views/products/index.html -->

      <tr>
        <td>
          <!-- Input -->
          <input type="text" v-model="product.name"><br>
          <!-- Validation errors -->
          <span style="color:red">{{ errors.name }}</span>
        </td>
        <td>
          <!-- Input -->
          <input type="text" v-model="product.price"><br>
          <!-- Validation errors -->
          <span style="color:red">{{ errors.price }}</span>
        </td>
        <td><input type="checkbox" v-model="product.manager"></td>
        <!-- button click calls hireProduct -->
        <td><button @click="hireProduct">Hire</button></td>
      </tr>
    </tbody>

Như vậy chúng ta đã xong phần list và create một product ở bài hướng dân sau tôi sẽ hướng dẫn các bạn thêm 2 phương thức là edit và destroy product sử dụng vuejs. chúc các bạn thành công link tham khảo https://github.com/adambutler/vuejs-rails https://rlafranchi.github.io/2016/03/09/vuejs-and-rails/


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí