观看儿童组件vue.js的道具

时间:2019-12-07 01:21:13

标签: vue.js

我有两个部分“数字输入”和“购物篮输入”。我如何从篮子输入中的数字输入(值)观看道具?

数字输入部分:

<template lang="pug">
    .field
        .number-input
            button.number-input__btn(@click.prevent="minus")
                i.i.i-minus
            input(type="number" v-model="value"  @input="valuecheck")
            button.number-input__btn(@click.prevent="plus")
                i.i.i-plus
</template>
<script>
export default {
    name: "number-input",
    props: {
        value: {
            type: Number,
            default: 1
        },
        min: {
            type: Number,
            default: 1
        },
        max: {
            type: Number,
            default: 999999999
        },
        current: {
            type: Number,
            default: 1
        }
    },
    methods: {
        plus() {
            if(this.value < this.max)  this.value++;
        },
        minus() {
            if(this.value > this.min) this.value--;
        },
        valuecheck() {
            if(this.value > this.max) this.value = this.max
        }
    },
    watch: {
        value: function() {
            if(parseInt(this.value) > parseInt(this.max)) this.value = this.max
        }
    }
}
</script>

购物篮输入

<template lang="pug">
    .basket-item
        a.basket-item__image(href="")
            img(:src="image", :alt="title")
        .basket-item__info
            span.basket-item__caption {{ code }}
            a.basket-item__title(href="") {{ title }}
            span.basket-item__instock(v-if="instock && instock > 0") В наличии ({{ instock }} шт)
            span.basket-item__instock(v-else) Нет в наличии
        .basket-item__numbers
            number-input(min="1" max="99" :value="numberofitems")
        .basket-item__lastcol
            .column-price(v-if="price")
                b {{ numberofitems * price }} ₽
                span(v-if="numberofitems > 1") {{ numberofitems }} × {{ price }} ₽
            button.basket-item__remove Удалить товар
</template>
<script>
export default {
    name: 'basketitem',
    props: {
        image: {
            type: String,
            required: true
        },
        title: {
            type: String,
            required: true
        },
        code: {
            type: String,
            required: true
        },
        instock: {
            type: Number
        },
        price: {
            type: Number
        },
        numberofitems: {
            type: Number,
            default: 1
        }
    },

}
</script>

在购物篮输入中,我需要观看数字输入(值)并将其写在numberofitems属性中。 我正在尽力而为,但是我对vue的了解太低了(

1 个答案:

答案 0 :(得分:0)

道具是仅传递数据in one way的机制-这意味着您可以将值从父级传递给子级,但是不允许子级更改该值。如果这样做,Vue会警告您。

使用事件的方法。该原理被普遍称为“道具下降,事件上升”。

  1. 您通过道具将价值传递给了孩子
  2. 当Child想要更改值时,它会发出具有新值的事件,而不是直接更改它
  3. 父组件需要处理该事件并更改其内部值(更改将通过prop传播到子项中)

您可以阅读各种实现方法,例如here

计算属性可以帮助您解决此问题:

<template>
  <input type="number" v-model="internalValue" />
</template>
<script>
export default {
  props: {
    value: {
      type: Number,
      default: 1
    }
  },
  computed: {
    internalValue: {
      get:  function() {
        return this.value
      },
      set: function(newValue) {
        this.$emit('valueChanged', newValue)
      }
    }
  }
}
</script>

在您的父组件中:

<template>
  <mycomponent :value="value" @valueChanged="value = $event"/>
  <mycomponent :value="value" @valueChanged="onValueChanged"/>
</template>
<script>
export default {
  data: {
    value: 0
  },
  methods: {
    onValueChanged(newValue) {
      this.value = newValue;
    }
  }
}
</script>

注释

  • 对于更大,更复杂的应用程序,最好使用某些具有共享全局状态的解决方案,例如Vuex
  • 您的Basket-input组件遇到了同样的问题,因为它通过prop接收了numberofitems