首页 > 解决方案 > 我在 Vuejs 中有太多观察者,我的代码不可扩展

问题描述

有没有办法让这段代码更短/可扩展:(只是在这里添加很多代码来演示我必须为每个项目编写的数量)

    hoodiesml: false,
    hoodiemed: false,
    hoodielrg: false,
    hoodiexlrg: false,
    hoodiexxlrg: false,

    hoodiesmlqty: 0,
    hoodiemedqty: 0,
    hoodielrgqty: 0,
    hoodiexlrgqty: 0,
    hoodiexxlrgqty: 0,

    hoodiesmltot: 0,
    hoodiemedtot: 0,
    hoodielrgtot: 0,
    hoodiexlrgtot: 0,
    hoodiexxlrgtot: 0,

    shirtsml: false,
    shirtmed: false,
    shirtlrg: false,
    shirtxlrg: false,
    shirtxxlrg: false,

    shirtsmlqty: 0,
    shirtmedqty: 0,
    shirtlrgqty: 0,
    shirtxlrgqty: 0,
    shirtxxlrgqty: 0,

    shirtsmltot: 0,
    shirtmedtot: 0,
    shirtlrgtot: 0,
    shirtxlrgtot: 0,
    shirtxxlrgtot: 0,

    hatsml: false,
    hatmed: false,
    hatlrg: false,
    hatxlrg: false,
    hatxxlrg: false,

    hatsmlqty: 0,
    hatmedqty: 0,
    hatlrgqty: 0,
    hatxlrgqty: 0,
    hatxxlrgqty: 0,

    hatsmltot: 0,
    hatmedtot: 0,
    hatlrgtot: 0,
    hatxlrgtot: 0,
    hatxxlrgtot: 0,
}
},
watch: {

hoodiesml() {
    let app = this
    if (app.hoodiesml === false) {
        app.hoodiesmlqty = 0
        console.log('hoodiesml qty set to 0')
    }

    else if (app.hoodiesml === true) {
        app.hoodiesmlqty = 1
    }
},

hoodiesmlqty() {
    let app = this
    let tot = 0
    tot = app.hoodiesmlqty * app.hoodieCost
    app.hoodiesmltot = tot
    console.log('some hoodiesmlqty changed ' + tot)
    app.merchtotal()
},


hatsml() {
    let app = this
    if (app.hatsml === false) {
        app.hatsmlqty = 0
        console.log('hatsml qty set to 0')
    }

    else if (app.hatsml === true) {
        app.hatsmlqty = 1
    }
},

hatsmlqty() {
    let app = this
    let tot = 0
    tot = app.hatsmlqty * app.hatCost
    app.hatsmltot = tot
    console.log('some hatsmlqty changed ' + tot)
    app.merchtotal()
},

shirtsml() {
    let app = this
    if (app.shirtsml === false) {
        app.shirtsmlqty = 0
        console.log('shirtsml qty set to 0')
    }

    else if (app.shirtsml === true) {
        app.shirtsmlqty = 1
    }
},

shirtsmlqty() {
    let app = this
    let tot = 0
    tot = app.shirtsmlqty * app.shirtCost
    app.shirtsmltot = tot
    console.log('some shirtsmlqty changed ' + tot)
    app.merchtotal()
},

这仅向观察者显示每件商品 5 种尺寸中的 2 种尺寸。也可能有超过 3 个项目。

我正在使用 Django,我想把它全部留在数据库端,但我从这个页面处理付款。

这个过程是我直接从这个页面把总金额交给贝宝快递。

工艺流程:

用户填写表格(在总价中增加成本)。他们点击结帐,这就是我检查错误的地方。如果没有错误,结帐按钮将在模式中可见。在结帐按钮上方,我有他们可以购买不同尺寸的活动商品。当他们向下滚动并单击贝宝结帐按钮时,我必须准备好总数。这就是为什么我有观察者。

我的问题

有没有办法让观察者观察多个属性。即让它观察帽子的所有数量和尺寸,如果有变化,我会调用一种方法,我可以在其中传递数量和成本。这样我就可以只有一种方法和一个观察者?

标签: vue.jsvuejs2

解决方案


亲自,

我不会定义/硬编码每个项目,而是使用对象/项目的属性来定义状态,例如,type可以是从连帽衫到独角兽的任何东西,其他值(如size可能被 false 禁用等)然后你所做的一切用户界面正在更新模型/项目。

另外,我会将这些项目抽象为一个组件以供咯咯笑。

Vue.component('cart-item', {
  template: '#cart-item',
  props: ['data', 'index'],
  data() {
    return {
      item: {
        type: this.data.type,
        price: this.data.price,
        size: this.data.size,
        qty: this.data.qty
      }
    }
  },
  methods: {
    updateOrder(e) {
      this.$emit('on-update', this.item, this.index)
    }
  }
});

//
var vm = new Vue({
  el: '#app',
  computed: {
    cartTotal: function() {
      let total = 0
      this.items.forEach(item => {
        total = total + item.qty * item.price
      })
      return total
    }
  },
  data() {
    return {
      items: [{
        type: 'T-shirt',
        price: 9.99,
        size: '',
        qty: 0
      }, {
        type: 'Unicorn Plush Toy',
        price: 3.99,
        size: false,
        qty: 0
      }]
    }
  },
  methods: {
    updateCart(value, index) {
      this.items[index] = Object.assign(this.items[index], value);
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.14/vue.min.js"></script>

<div id="app">
  <h1>Order Form</h1>

  <cart-item v-for="(item, index) in items" :data="item" :index="index" @on-update="updateCart"></cart-item>

  <p>Total cart cost: ${{ cartTotal }}</p>

  <pre>{{ items }}</pre>
</div>

<template id="cart-item">
   <div>
     <strong>{{ item.type }}</strong><br>
     <strong>{{ item.price }}</strong><br>
     <div v-if="item.size !== false">
     <label>Size</label>
     <select v-model="item.size" @change="updateOrder">
       <option>sml</option>
       <option>med</option>
       <option>lrg</option>
       <option>xlrg</option>
     </select>
     </div>
     <label>Qty</label>
     <input type="text" v-model="item.qty" @input="updateOrder"/>
   </div>
</template>


推荐阅读