【问题标题】:Watch props from children component vue.js从子组件 vue.js 观看道具
【发布时间】:2020-03-31 23:35:30
【问题描述】:

我有两个组件“数字输入”和“篮子输入”。我如何在篮子输入中观看来自数字输入(值)的道具?

数字输入组件:

<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 的了解太少了(

【问题讨论】:

    标签: vue.js


    【解决方案1】:

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

    绕过它来使用事件。该原则被广泛称为“props-down,events-up”。

    1. 您通过 prop 将值传递给 Child
    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

    【讨论】:

      猜你喜欢
      • 2021-03-19
      • 1970-01-01
      • 2017-08-17
      • 2021-09-30
      • 1970-01-01
      • 1970-01-01
      • 2019-03-27
      • 2019-06-13
      • 2019-05-31
      相关资源
      最近更新 更多