0

I'm relatively new to Vue.js, trying to create a Vue component based on this custom select menu and am looking to add an ionicon to each list item.

Normally, I can create the icon in Vue.js with the following line (with the relevant imported icons):

<component class="icon" :is="name-of-icon"></component>

However, the custom select menu I'm trying to replicate hides the default select element and dynamically adds its own elements with custom CSS styling.

As a result of this, the following is not a solution as it requires me to use the default select styling:

<option v-for="option in options" :value="option">
    <component class="icon" :is="icon"></component 
    <p>{{ option }}</p>
</option>

Instead, I tried to add the icon using jQuery when it is styled. Putting the jQuery from the aforementioned pen into a method, style():

<template>
    <select>
        <option v-for="option in options" :value="option">
            {{ option }}
        </option>
    </select>
</template>
<script>
    import MdPersonIcon from 'vue-ionicons/dist/md-person.vue'

    export default {
        name: 'custom-select',
        components: {MdPersonIcon},
        methods: {
            style() {
                $('select').each(function () {

                    // rest of code from pen here

                    for (let i = 0; i < numberOfOptions; i++) {
                        let option = $('<li />', {
                            rel: $this.children('option').eq(i).val()
                        });
                        let text = $this.children('option').eq(i).text();
                        let $icon = $('<component>', {
                            'class': 'icon',
                            ':is': 'md-person-icon',
                        });
                        let $label = $('<p>', {
                            text: text
                        });

                        $icon.appendTo(option);
                        $label.appendTo(option);
                        option.appendTo($list);
                    }

                    // rest of code from pen here
                });
            }
        },
        mounted() {
            this.style();
        }
    }
</script>
<style>
    /* rest of CSS from the pen here */
    .icon {
        padding: 8px 8px 8px 0;
        margin: 0;
    }
</style>

And usage of component being (where options is a String array):

<custom-select :options="options"></custom-select>

Creating an icon normally and then inspecting it produces something like:

<div class="ion profile-icon" data-title="Md Person Icon" data-name="md-person-icon" data-v-fc38bec4="">
    <svg viewBox="0 0 512 512" class="ion__svg">
        <path d="some long string"></path>
    </svg>
</div>

The component was replaced with the ionicon. However, inspecting the element shows that the component was not replaced:

<component class="icon" :is="md-person-icon"></component>

I'm not quite sure why this is happening.

I am aware that I should not be trying to mix jQuery and Vue but I currently cannot think of another way to create a custom select menu Vue component.

1 Answer 1

1

You have to transfer elements created by jQuery to Vue, cuz what jQuery add in runtime wont bind and not detectable by Vue, here is sample that I see your jquery code doing

<template>
  <ul>
    <li for="option in options" :key="option.rel" :rel="option.rel">
      <component class="icon" :is="option.icon" />
      <p>{{ option.text }}</p>
    </li>
  </ul>
</template>
<script>
 export default {
   data(){
    return {
      options:[
         {rel:'hide', text:'-- Month --', icon: 'md-person-icon'},
         {rel:'january', text:'january', icon: 'md-person-icon'},
         {rel:'february', text:'february', icon: 'md-person-icon'},
         ...
      ],
    }
  }
}
</script>
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the answer, could you give an example using the select tag? And with this solution, I don't need to include my added jQuery solution?
Codes that i wrote in template tag is what your jQuery code add to page so dont need what codes you added in style method, what i saw in your Codepan is that set display : none for select tags and use ul li instead. you cant add icon to select element, inspect your codepen to see select is hidden
If I'm understanding correctly, I can just skip the creating the select element and just display the actual thing I want to show?
Exactly! From what I see, select tag is source for jQuery elements builder, while we use data property for this purpose in vue wont need it anymore

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.