簡體   English   中英

如何將 vue.js 與 django 集成?

[英]how to integrate vue.js with django?

這是帶有 vue.js 的單頁應用程序,它進行了一些簡單的計算,我試圖在 django 中實現這個計算,但它沒有給我想要的結果。 在這里,我在 vue.js 中動態創建了數組,這僅完美地顯示了產品的圖像,而不是product.nameproduct.sell_price以及@click.prevent="addToCart(product)"這個函數不起作用?? 我該如何解決?

Vue.js

   <script src="{% static 'js/vue.js' %}"></script>

   <script type="text/javascript" src="{% static '/js/vue-resource.js' %}"></script>
    <script>

 new Vue({
    el: '#posApp',
    
    data: {
        total: 0,
        discount: 0,
        products: [
            {% for product in products %}
                {
                    "id": {{product.id}},
                    "name": "{{product.name}}",
                    "image": "/media/{{product.image}}",
                    "price": {{product.sell_price}}
                },
              {% endfor %}

        ],
        cart: [],
        search: ""
    },
    methods: {

        addToCart: function(product){

            var found = false;
            for (var i = 0; i < this.cart.length; i++){
                if (this.cart[i].id === product.id){
                    this.cart[i].quantity++;
                    found = true;
                }
            }
            if (!found) {
                this.cart.push({
                    id: product.id,
                    name: product.name,
                    sell_price: product.sell_price,
                    quantity: 1
                });
            }

            this.total += product.sell_price;
        },
        inc: function(item){
            item.quantity++;
            this.total += item.sell_price;
        },
        dec: function(item){
            item.quantity--;
            this.total -= item.sell_price;
            if (item.quantity <= 0){
                var i = this.cart.indexOf(item);
                this.cart.splice(i, 1);
            }
        },
        removeFromCart: function(item){
            this.cart.splice(this.cart.indexOf(item), 1);
            this.total = this.total - (item.sell_price * item.quantity);
        },
        clearCart: function(){
            this.cart = [];
            this.total = 0;
            this.discount = 0;
        },
        payment: function(){
            this.cart = [];
            this.total = 0;
            this.discount = 0;
            alert('Transaction Completed');
        }
    },
    computed: {
        filteredProducts(){
            // var lowerTitle = product.title.toLowerCase();
            return this.products.filter((product) => {
                return product.name.toLowerCase().match(this.search);
            });
        }
    }
});
</script>

html

 <div class="col-md-3" v-for="product in filteredProducts" :key="product.id"> <!-- Inner-Col .// -->
                  <a href="#" @click.prevent="addToCart(product)">
                    <div class="box box-default pos-product-card"> <!-- /.box -->
                      <img class="card-img-top img-responsive" :src="product.image" alt="Card image cap">
                      <div class="box-body"> <!-- /.box-body -->
                        <h4 class="box-title">{{ product.name }}</h4>
                        <!-- <p class="box-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p> -->
                        <button class="btn btn-info"><i class="fas fa-shopping-cart"></i></button>
                      </div> <!-- /.box-body -->
                    </div> <!-- /.box -->
                  </a>
                </div>
{% for category in categories %}
            <div class="tab-pane fade" id="category-{{category.id}}">

                <div class="row"> <!-- Inner-Row .// -->
                    {% for product in category.product_set.all %}
                   <div class="col-md-3" v-for="product in filteredProducts" :key="product.id"> <!-- Inner-Col .// -->
                  <a href="#" @click.prevent="addToCart(product)">
                    <div class="box box-default pos-product-card"> <!-- /.box -->
                      <img class="card-img-top img-responsive" :src="product.image" alt="Card image cap">
                      <div class="box-body"> <!-- /.box-body -->
                        <h4 class="box-title">{{ product.name }}</h4>
                        <!-- <p class="box-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p> -->
                        <button class="btn btn-info"><i class="fas fa-shopping-cart"></i></button>
                      </div> <!-- /.box-body -->
                    </div> <!-- /.box -->
                  </a>
                </div>
                    {% endfor %}
     <table class="table table-hover text-center">
                                  <!-- <thead class="thead-dark"> -->
                                    <tr>
                                      <th>Item</th>
                                      <th>Quantity</th>
                                      <th>Rate</th>
                                      <th>Subtotal</th>
                                      <th>&nbsp;</th>
                                    </tr>
                                  <!-- </thead> -->
                                      <tr v-for="item in cart" :key="{{item.id}}">

                    <td><a href="#">{{ item.name }}</a></td>
                    <td><button class="btn btn-flat btn-xs btn-info p-1 mx-1" @click="inc(item.id)">+</button>[[ item.quantity ]]<button class="btn btn-flat p-1 mx-1 btn-xs btn-info" @click="dec(item.id)">-</button></td>
                    <td><span class="text-muted">{{ item.sell_price }}</span> </td>
                    <td>Rs {{ item.sell_price * item.quantity }}</td>
                    <td><button class="btn btn-xs btn-outline-primary" @click="removeFromCart(item)"><i class="fas fa-trash-alt"></i></button></td>
                  </tr>
                                  </table>
                                </div>
                                <div class="no-item-msg" v-if="cart.length === 0">No items in the cart.</div>
                              </div>
         <table class="table">
                                    <tr>
                      <td>Total Items</td>
                      <td>{{ cart.length }}</td>
                    </tr>
                    <tr>
                      <td>Total Amount</td>
                      <td>{{ total }}</td>
                    </tr>
                    <tr>
                      <td><span class="height-control">Discount (In Amount)</span></td>
                      <td><input type="number" v-model="discount" class="form-control"></td>
                    </tr>
                    <tr class="bg-dark">
                      <td>TO PAY</td>
                      <td>{{ total-discount }}</td>
                    </tr>

您需要考慮以下幾點:

  1. 似乎您的 html 中有語法沖突,因為 Django 和 Vue.js 使用相同的{{}}來放置變量。 但是,由於 Django 將在 Vue之前處理您的 html,因此它將替換

    ``` <h4 class="box-title">{{ product.name }}</h4>```

通過它將在上下文中找到的內容(服務器端的 Django tepmlate 上下文)。 您可以在瀏覽器中查看源代碼或您的頁面,您可能會在該行看到:

<h4 class="box-title"></h4>

因為它不會找到 python product變量(你實際上是指 js(vue) 變量)。

解決方案:使用另一個 Vue 分隔符。 請參閱https://v2.vuejs.org/v2/api/#delimiters 例如使用[[而不是{{ in Vue: an option to your Vue instance delimiters: ['[[', ']]'],並將該行(以及其他您指 Vue 變量的地方)更改為

<h4 class="box-title">[[ product.name ]]</h4>

  1. 在 Vue 數據中,你沒有product.sell_price 變量,就像你做的那樣
  {% for product in products %}
     {
      "id": {{product.id}},
      "name": "{{product.name}}",
      "image": "/media/{{product.image}}",
      "price": {{product.sell_price}}
      },
  {% endfor %}

您將擁有product.price ,而不是 Vue 中的product.sell_price 或者您必須將上面的行更改為"sell_price": {{product.sell_price}}

  1. 很快您將面臨item變量的麻煩。 因為您在 django 上下文中有item ,而不是在 Vue 數據中。 您應該像對products所做的那樣將項目添加到 Vue 數據中。

  2. 一般來說,考慮將您的方法從混合 django 模板和 Vue 代碼更改為:

  • Django 向 Vue 傳遞數據
  • Vue 生成所有 html 並執行您的 js 功能

或者

  • 使用 Django Rest 框架( https://www.django-rest-framework.org/ ) 提供 REST API
  • 並僅在前端使用 Vue,從服務器加載數據並通過 REST 調用將更改放入服務器(例如使用 axios)

祝你好運。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM