Важно понимать, как реквизит работает в Vue. Ключевым аспектом здесь является то, что реквизиты используются для одностороннего потока данных . Если вы хотите, чтобы это был двусторонний поток данных, вам нужно вместо этого использовать v-model
.
Сказав это, есть несколько разных способов сделать это. Я предпочитаю использовать вычисленные свойства для подобных вещей! Это довольно чисто, и легко следовать в коде.
Вместо того, чтобы модифицировать опору напрямую, в вашем numeric-text-field
компоненте вы должны вместо этого генерировать событие, когда
значение изменено. Вот как будет выглядеть Turbines.vue
:
<template>
<numeric-text-field class="mx-auto"
label="Head Mass"
units="kg"
:headMass="turbine.head_mass"
v-on:updateHeadMass="updateHeadMass"/>
</template>
<script>
import NumericTextField from '@/components/common/NumericTextField'
export default {
name: 'Turbines',
components: {
NumericTextField
},
data () {
return {
// You should consider initializing your data with the structure that matches what you expect, instead of an empty object
turbine: {
head_mass: ""
}
}
},
methods: {
updateHeadMass(value) {
this.turbines.head_mass = value;
}
}
}
</script>
<style scoped>
</style>
Вы заметите атрибут v-on:updateHeadMass
. Вот как мы слушаем испущенные события от наших дочерних компонентов. Когда выдается даже updateHeadMass
, мы можем вызвать определенную функцию и соответственно обновить наши данные в родительском компоненте. Это приведет к реактивному изменению дочернего компонента, который затем обновляется.
Внутри NumericTextField
Вместо прямого изменения реквизита, используйте вычисляемое свойство, которое генерирует событие, вплоть до родительского компонента при изменении ввода
Вот как может выглядеть ваш NumericTextField
компонент:
<template>
<div>
<label for="headMass">Head Mass</label>
<input type="text" v-model="localHeadMass" name="headMass"/>
</div>
</template>
<script>
export default {
name: "numeric-text-field",
computed: {
localHeadMass: {
get() {
return this.headMass;
},
set(value) {
// Now, anytime we change this property, our parent receives the new value and updates the `headMass` prop!
this.$emit("updateHeadMass", value);
}
}
},
props: {
headMass: {
type: String,
default: "0",
required: true
}
}
};
</script>
<style scoped>
</style>
Если вам не нужен вышеуказанный подход, вместо этого вы можете использовать наблюдателя, подобного этому:
<template>
<div>
<label for="headMass">Head Mass</label>
<input type="text" v-model="localHeadMass" v-on:change="updateHeadMass" name="headMass"/>
</div>
</template>
<script>
export default {
name: "numeric-text-field",
data: () => {
return {
localHeadMass: ""
};
},
props: {
headMass: {
type: String,
default: "0",
required: true
}
},
methods: {
updateHeadMass() {
this.$emit("updateHeadMass", this.localHeadMass);
}
},
watch: {
headMass(value) {
this.localHeadMass = value;
}
}
};
</script>
<style scoped>
</style>