Vue 3 двусторонняя привязка с полем выбора

#vue.js

Вопрос:

Я пытаюсь создать двустороннюю привязку между моим родителем (создать форму пользователя) и дочерним компонентом (многоразовое поле выбора).

Родительский компонент

 <template>
    <Selectbox :selectedOption="selectedRole" :options="roles" />
    <span>SelectedRole: {{ selectedRole }}</span>
</template>

<script>
    import Selectbox from '@/components/formElements/Selectbox.vue';

    export default {
        components: {
            Selectbox,
        },
        async created() {
            await this.$store.dispatch('roles/fetchRoles');
            this.selectedRole = this.roles[0].value;
        },
        data() {
            return {
                selectedRole: null,
            };
        },
        computed: {
            roles() {
                return this.$store.getters['roles/roles'].map((role) => ({
                    value: role.id.toString(),
                    label: role.name,
                }));
            },
        },
    };
</script>
 

Я передаю роли как параметры, а переменную selectedRole как selectedOption.

Дочерний компонент

 <template>
    <select :value="selectedOption" @input="(event) => $emit('update:selectedOption', event.target.value)">
        <option v-for="option in options" :value="option.value" :key="option.value">{{ option.label }}</option>
    </select>
</template>

<script>
    export default {
        props: {
            options: {
                type: Array,
                required: true,
            },
            selectedOption: {
                type: String,
                required: false,
            },
        },
    };
</script>
 

Выбранная опция присваивается значению вместе. Когда выбрано другое значение, я хочу обновить переданное значение в родительском компоненте. Поэтому я использую $emit функцию, но сейчас она не работает.

Я также попытался использовать v-модель для объединения значений и изменения атрибутов, но безуспешно.

 <select v-model="selectedOption">
 

Каков правильный путь?

Код: Codesandbox

Ответ №1:

Я предполагаю, что это та обработка, которой вы хотите добиться: https://codesandbox.io/s/practical-orla-i8n3t?file=/src/components/Selectbox.vue

Если вы используете v-model субкомпонент, вы должны правильно обращаться с ним в субкомпоненте.

 <custom-select v-model="value" />

<!-- IS THE SAME AS -->

<custom-select
   :modelValue="value"
   @update:modelValue="value = $event"
/>
 

Поэтому , если вы используете v-model , свойство с именем modelValue передается подкомпоненту. Если modelValue изменения (что означает, что выбран другой параметр в списке выбора), вы должны выдать событие изменения, указывающее, что modelValue оно было изменено: $emit('update:modelValue') . v-model автоматически обновляет его значение, если происходит это событие.

Источник: https://learnvue.co/2021/01/everything-you-need-to-know-about-vue-v-model/

Комментарии:

1. Это оно. Спасибо! Для дальнейших читателей. Можно переименовать значение модели во что-то другое, добавив :name в v-модель: <Selectbox v-model:selectedOption="selectedRole" :options="roles" />

2. Мило, не знал, что