Search code examples
vue.jsvuejs3vuetify.jsvuetifyjs3

How to clear the input of Vuetify's v-autocomplete from element in it's #clear slot?


So I have a <v-autocomplete> that I want to be clearable. If I just set the clearable attribute it works BUT I have a custom icon component that I want to display instead of the default clear icon. According to the docs I can use the #clear slot for that. So I used that and placed my icon component in there but clicking on it doesn't clear the input field anymore.

I tried clearing the model with @click on the icon element but it didn't work either.

Here is my code: (I replaced the custom icon component with <button> for the example)

<template>
<v-autocomplete
    ref="searchInput"
    v-model="inputVal"
    clearable
    label="Placeholder"
    :items="items"
    variant="outlined"
    :class="$style['text-input']">
    <template #clear>
        <button type="button" @click="clearInput">X</button>
    </template>
</v-autocomplete>
</template>

<script lang="ts">
type SearchItem = {
    value: number | string
    title: string
}

export type Props = {
    searchFieldPlaceholderText: string
}
</script>

<script setup lang="ts">
import { ref } from "vue"

const inputVal = ref<number | string | undefined>()
const searchInput = ref<any>()

const items: Array<SearchItem> = [
    {
        title: "Item 1",
        value: 1,
    },
    {
        title: "Item 2",
        value: 2,
    },
]
const clearInput = () => {
    inputVal.value = null
    console.log(searchInput)
}
</script>

<style lang="scss" module>
.text-input {
    max-width: 400px;
}
</style>


Solution

  • Yes, I think this is a bug. When using the slot, the onClear handler is not triggered and no click:clear event will fire.

    The #clear slot probably should pass an onClear callback, but it doesn't. Only workaround for now is to implement the clear yourself:

    <template #clear>
      <button @click="inputVal = null">X</button>
    </template>
    

    Using the :clear-icon prop does not have this limitation. You could pass in your component there:

    <script setup>
      import { h } from 'vue'
      import YourCustomIconComponent from '...'
    
      const ClearIconComponent = () => h(YourCustomIconComponent, {icon: 'mdi-close'})
    </script>
    <template>
      <v-autocomplete
        :clear-icon="ClearIconComponent"
        ...
      />
    </template>
    

    see playground