javascriptvue.jsvue-componentportalvuejs3

Why not updating value in the parent component which I passed in child component and updating use custom event $emit Vue 3?


Parent component. I have value like startValue in the Main component and passing like props the starValue to Settings component. Everything okay and props passed also good but I can't update the startValue using custom event in the Settings component (child component). Why?

<template>
<div>
  <span>Main</span>
  <SettingsBoard :max="maxValue" :start="startValue" @update="startValue = $event"/>
</div>
</template>

<script>
import {ref} from 'vue'
import SettingsBoard from "@/components/SettingsBoard";

export default {
name: "Main",
  components: {
    SettingsBoard
  },

  setup() {
    const startValue = ref(1)
    const maxValue = ref(2);

    return {
      startValue,
      maxValue
    }
  },

}
</script>

Child component

<template>
  <div>
    <h3>Settings board</h3>
    <div>
      <span>start value</span>
      <label>
        <input :value="start" @input="onChangeStart"  type="number" step="1" min="0">
      </label>
    </div>
    <div>
      <h1>{{start}}</h1>
    </div>
  </div>
</template>

<script>

export default {
  name: "SettingsBoard",
  props: {
    start: {type: Number, required: true},
    max: {type: Number, required: true},
  },
  setup() {

    const onChangeStart = (event) => {
      this.$emit('update: start', event.target.value)
    }




    return {strong text
      onChangeStart,
    }
  },
}
</script>

Solution

  • Use v-model to sync the prop value(s) between the components.

    Parent

    <SettingsBoard :max="maxValue" v-model:start.number="startValue" />
    

    SettingsBoard (child)

    export default {
      name: 'SettingsBoard',
    
      props: {
        start: { 
          // Do [Number, String] to support multiple types, 
          // otherwise you'll have to cast it to number with the .number modifier.
          type: Number, 
          required: true 
        },
        max: { type: Number, required: true }
      },
    
      setup(props, { emit }) {
        const onChangeStart = (event) => {
          // Cast this target.value to number or use .number modifier 
          // since it's expecting a number
          emit('update:start', event.target.value)
        }
    
        return {
          onChangeStart
        }
      }
    }
    

    References: