DEV Community

Cover image for Migrate vue-select to a Vue 3 compatible library
Syazwan
Syazwan

Posted on Edited on

Migrate vue-select to a Vue 3 compatible library

vue-select's stable release (3.20.4) is Vue 2 only. The Vue 3 version has been at 4.0.0-beta.6 since November 2022.

If it's one of the things holding back your Vue 3 upgrade, you can replace it before the upgrade. Swap it while you're still on 2.7, then upgrade Vue later without touching your selects again.

This walkthrough uses Vue Pick, which runs on both 2.7 and 3 with the same props.

Vue Pick in multiselect mode with two chips selected and the list open

Install

npm install vue-pick
🏆 Live Soccer TV: szwn/migrate vue select to a vue compatible library mc - Jadwal Siaran Langsung 🏆 Live Soccer TV: szwn/migrate vue select to a vue compatible library mc - Jadwal Siaran Langsung
// main.js, in place of "vue-select/dist/vue-select.css"
import "vue-pick/style.css"
🏆 Live Soccer TV: szwn/migrate vue select to a vue compatible library mc - Jadwal Siaran Langsung 🏆 Live Soccer TV: szwn/migrate vue select to a vue compatible library mc - Jadwal Siaran Langsung
import { VPick } from "vue-pick/vue2" // while on Vue 2.7
import { VPick } from "vue-pick"      // after the upgrade
🏆 Live Soccer TV: szwn/migrate vue select to a vue compatible library mc - Jadwal Siaran Langsung 🏆 Live Soccer TV: szwn/migrate vue select to a vue compatible library mc - Jadwal Siaran Langsung

When you move to Vue 3, that import path is the only line that changes.

Check what v-model holds

This is the step that causes bugs if you skip it. vue-select puts the whole option object in v-model, unless you pass reduce.

If you use reduce, name the field with value-key:

<!-- before -->
<v-select v-model="countryId" :options="countries" :reduce="(c) => c.id" />

<!-- after -->
<v-pick v-model="countryId" :options="countries" value-key="id" searchable clearable />
🏆 Live Soccer TV: szwn/migrate vue select to a vue compatible library mc - Jadwal Siaran Langsung 🏆 Live Soccer TV: szwn/migrate vue select to a vue compatible library mc - Jadwal Siaran Langsung

If you don't, add value-format="object" so your data keeps the same shape:

<v-pick v-model="country" :options="countries" value-key="id" value-format="object" searchable clearable />
🏆 Live Soccer TV: szwn/migrate vue select to a vue compatible library mc - Jadwal Siaran Langsung 🏆 Live Soccer TV: szwn/migrate vue select to a vue compatible library mc - Jadwal Siaran Langsung

Turn search and clear back on

vue-select is searchable and clearable by default. Vue Pick isn't, which is why both examples above add searchable clearable.

In multiple mode, Vue Pick also stays open after each pick. Add :close-on-select="true" if you want the old behavior.

Plain string options like ["Apple", "Banana"] need to become objects once:

const options = fruits.map((f) => ({ label: f, value: f }))
🏆 Live Soccer TV: szwn/migrate vue select to a vue compatible library mc - Jadwal Siaran Langsung 🏆 Live Soccer TV: szwn/migrate vue select to a vue compatible library mc - Jadwal Siaran Langsung

v-model still holds the plain string.

Letting an agent do the bulk of it

The full prop, event and slot mapping is in the vue-select migration guide. The page also has a prompt you can paste into Claude Code, Cursor or Copilot. It points the agent at a plain-text copy of the guide and leaves a TODO wherever there's no match, instead of guessing.

The copy-paste agent prompt on the vue-select migration guide

If you wrap vue-select in your own component, migrate the wrapper first. Every page that uses it moves over at once.

Top comments (0)