Guide to accessing child prop reference in Vue 3 using Element Plus UI library

I am encountering an issue with a dropdown component labeled 'dropdown'

When selecting an item, I need to retrieve the selected label (not just the value)

Currently, when using dropdown.value, I receive an object containing a key and its corresponding value. Inside this object, there is 'selectedLabel', which is the value I want to access.

However, attempting to access dropdown.value.selectedLabel returns blank, and dropdown.value.selectedLabel.value is undefined.

https://codesandbox.io/s/element-plus-demo-forked-2n982?file=/src/App.vue

Please refer to the image below for a visual representation of the template and the logs received: https://i.sstatic.net/aliEj.jpg

<template>
  <div class="dropdown-component">
    <div class="label">{{name}}</div>
    <div class="select-container">
      <el-select
        ref="dropdown"
        v-model="selectedValue"
        filterable
        @change="$emit('OPTION_SELECTED', selectedOptionData())"
        :placeholder="placeholderText"
      >
        <el-option
          v-for="(item,index) in options"
          :key="index"
          :label="getLabel(item)"
          :value="getValue(item)"
        >
        </el-option>
      </el-select>
    </div>
  </div>
</template>

<script>
import { ref, defineComponent, watchEffect, computed } from 'vue'
import { getAPIObjFor } from '@/lib/ymm/YMMApi'

export default defineComponent({
  props: {
    labelKey: String,
    valueKey: { type: String, default: '' },
    name: String,
    next: String,
    groupState: Object
  },

  emits: ['OPTION_SELECTED'],

  setup (props) {
    console.log('Initing Dropdown-', props.name)

    const options = ref([])
    const selectedValue = ref('')
    const activeQueryParam = ref('')
    const dropdown = ref(null)
    const apiQueryObj = getAPIObjFor(props.name)

    const getOptionData = async ({ apiQuery, apiRequest }) => {
      // keep log
      console.log('%c' + props.name + ' query:', 'color:orange', apiQuery)
      activeQueryParam.value = apiQuery
      options.value = await apiRequest(apiQuery)
    }

    const getLabel = (_item) => {
      return _item[props.labelKey]
    }

    const getValue = (_item) => {
      const valueKey = props.valueKey === '' ? props.labelKey : props.valueKey
      return { value: _item[valueKey], label: getLabel(_item), x: 'x' }
    }

    const selectedOptionData = () => {
      console.log('selected dropdown', dropdown.value, dropdown.value.clearIcon, dropdown.value.selectedLabel)
      const { name } = props
      const { value, label } = selectedValue.value
      const selectedData = {
        [`${name}`]: {
          value,
          label,
          next: props.next
        }
      }
      return selectedData
    }

    const placeholderText = computed(() => {
      return `Select a ${props.name}`
    })

    watchEffect(() => {
      const query = apiQueryObj(props.groupState)
      if (query && query.apiQuery !== activeQueryParam.value) {
        selectedValue.value = ''
        getOptionData(query)
      }
    })

    return { options, getValue, getLabel, selectedValue, selectedOptionData, placeholderText, dropdown }
  }
})
</script>

<style lang="scss" scoped>

.dropdown-component {
  max-width: 500px;
  display: flex;
  flex-direction: row;
  justify-content: space-between;

  .select-container {
    max-width: 400px;
    display: flex;
    min-width: 20px;
    flex-grow: 1;
  }

  .el-select {
    width: 100%;
  }
}

</style>

Answer №1

If you're encountering issues with the selectedLabel property being blank in el-select, try using the selected property instead.

The selected property stores an array of selected options, with the most recent selection at the end. Keep in mind that this property is updated after the change event, so you may need to wait for the next tick before accessing it.

import { nextTick } from 'vue'
//...

const selectedOptionData = async () => {
  await nextTick()
  const selected = dropdown.value.selected.at(-1).currentLabel
  console.log('selectedLabel', selected)
  //...
}

To make this work, ensure that your @change event handler is set as asynchronous:

<el-select @change="onChange">
export default {
  setup(props, { emit }) {
    const onChange = async () => {
      emit('OPTION_SELECTED', await selectedOptionData())
    }

    return { onChange }
  }
}

For a demonstration and further reference, check out this demo.

Keep in mind that the change event also triggers when a tag is removed.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What sets apart Selenium's mouseMove() function from the physical movement of a mouse?

Imagine I have element A and element B on a webpage. Using tools like Selenium or PhantomJS, I can manipulate the mouse via coordinates. By identifying the position of element A (a link) and element B (a submit button), I can create a bezier curve or mimi ...

Transfer only certain directories located within the primary directory

Imagine having a main-folder, which contains folders of type my-folder-x. Within these my-folder-x folders, there are subfolders and files. -main-folder -my-folder-a -build-folder -demo-folder dummy.js dummy.css my.json -dummy-folder - ...

Issue with adding dynamic keys to state in Next.js using Zustand for state management not resolving

I've been experimenting with dynamically adding a key to a state in zustand. I've attempted various methods such as 1. const store = (set, get) => ({ keyAttrib: {key1: "value1", key2: 2}, update: (key, value) => { let new ...

Excessive API requests can occur when Redux dispatches an action multiple times

Utilizing the Jikan API for anime, my objective is to showcase promo thumbnails of new anime shows. This involves two separate API calls: one to retrieve the latest anime shows: export const get_new_anime = () => `${base_url}search/anime?q&order_b ...

Wait for the reaction from react router history to go back

After clicking the submit button in a form, I need to navigate backwards using history.goBack. However, if there is no previous page in the history, I want to redirect to a screen displaying a thank you message using history.replace. const handleSubmit = ( ...

I seem to be having trouble using my markers on my istamap

function initialize() { var mapProp = { center:new google.maps.LatLng(51.508742,-0.120850), zoom:5, mapTypeId:google.maps.MapTypeId.ROADMAP }; var map = new google.maps.Map(document.getElementById("googleMap"),mapProp); var marker = new ...

Error in VueJS: Variable not defined

I've hit a roadblock with this problem and could use some assistance. After searching for similar issues, I was unable to find a suitable solution. The problem is straightforward: my components are unable to access my variables.scss file unless it&apo ...

Leveraging TypeScript's declaration file

Greetings! I am currently facing an issue while utilizing a declaration file in my TypeScript project. Here is the declaration file that I am working with: // Type definitions for Dropzone 4.3.0 // Project: http://www.dropzonejs.com/ // Definitions ...

Tips for adding a Search Bar to the header in a React Native application

I've been working on creating a header for my app in React Native that includes the screen title, a back button, and a search bar spanning the width of the screen. However, I've encountered some challenges along the way. Initially, I began with ...

JavaScript Image Swap

I tried implementing this script but it didn't work for me. I'm not sure what to do next, so I'm reaching out for help. The script is at the top of the page, followed by a picture with an id that I'd like to change when a button below i ...

Learn how to create an endless scrolling effect on a static webpage using only pure JavaScript

Looking to achieve an Infinite Page Scroll Effect similar to Twitter without relying on jQuery or any other library, using pure JavaScript. I'm new to JavaScript and need assistance with implementing this effect in search results displayed within a La ...

Exploring the Challenges of Testing Vue Components with Slots Using Cypress

I am still learning about component testing with Cypress, and I have been exploring the documentation and examples to perform some basic component tests in my project. Recently, I encountered a situation where I needed to test a simple component that takes ...

What is the best way to include a required condition in a select element in vue.js 2?

This is how my Vue component looks: <template> <select class="form-control" v-model="selected" required @change="changeLocation"> <option v-for="option in options" v-bind:value="option.id" >{{ option.name }}</option>&bs ...

Measuring the success of Vuejs app

Seeking performance metrics for a Vue application. Interested in metrics for the entire app as well as specific components. I am aware of using Vue.config.performance = true; to enable performance monitoring through dev tools, and I have considered utiliz ...

Obtain JSON data using jQuery

Hey there! I am currently working on understanding how to retrieve data using json/JQuery with the code below. After storing a php variable in a json variable (var ar), I confirmed its contents through console.log, although when I used document.write it d ...

POST method error 400 encountered

Whenever I execute my ajax jquery function, I encounter a 400 error Here is my code. All Postman tests pass successfully, but when the web app runs, it fails. I'm not sure if it's a coding issue or something related to HTML5. Can anyone offer as ...

How to Search for Multiple Values in a v-data-table Using Vuetify?

<v-card-title> <v-text-field v-model="search" label="Search Product Name" single-line hide-details ></v-text-field> </v-card-title> <v-data-table :headers="head ...

When a single object is entered, JSON returns 'undefined', however, it works successfully when using the .map() function

Utilizing Axios to fetch data from DeezerAPI, I initially rendered information using .map() and everything worked smoothly when passing it to a Component. However, when attempting to access a single JSON object, I encountered an 'undefined' error ...

Develop a schema for an array of arrays in NodeJS using mongoose

Looking to establish a database schema for storing the following data: { name : "xyz", admin : "admin", expense : [ jan: [{expenseObject},{expenseObject}], feb: [[{expenseO ...

Using Vue.js, transitions are implemented selectively on certain views

In my vuejs application, I have set up transitions between pages in App.vue. Here is an example of how it looks: <template> <div class="container mb-auto"> <router-view v-slot="{Component}" > <transition ...