Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue 3 support #1251

Closed
koljada opened this issue Aug 7, 2020 · 94 comments · Fixed by #1344
Closed

Vue 3 support #1251

koljada opened this issue Aug 7, 2020 · 94 comments · Fixed by #1344

Comments

@koljada
Copy link

koljada commented Aug 7, 2020

Is your feature request related to a problem? Please describe.
It would be great to have a working version for Vue 3.

Describe the solution you'd like
New version with Vue 3 support.

Describe alternatives you've considered

Additional context
At the moment I can't even install the lib:

vue-select@3.10.7" has incorrect peer dependency "vue@2.x"


Edited by @sagalbot: Vue 3 support is available on the beta release channel.

Please see #1597 as the source of truth for the v4 / Vue 3 compatible release. Thanks! - @sagalbot

npm install vue-select@beta
yarn add vue-select@beta
@wolfjagger
Copy link

I have a repo that depends on vue-select that I've been upgrading to vue 3. I forked vue-select (https://github.com/wolfjagger/vue-select) and upgraded as best I could.

Seems to install correctly, and unit tests now pass without too much modification. I don't know the library top-to-bottom, so I didn't comprehensively test manually. I didn't upgrade or remove more packages than necessary, so yarn audit's not great. I did need to install typescript; I think maybe @vue/test-utils needed it?

Unfortunately, there is a problem when using this as a dependency. When I import it in another package and try to mount it, it refuses and throws a bunch of warnings, starting with:

[Vue warn]: Invalid VNode type: Symbol() (symbol) 
  at <VueSelect ref="selectEl" class="select unfocused" modelValue=""  ... >
  ...

I don't know why this is; suspect a vue 3 bug. I see a couple of similar error messages on searching, and this seems very relevant: https://forum.vuejs.org/t/vue-3-invalid-vnode-symbol-fragment-when-using-an-external-component-with-a-slot/105448. May be a bug with slots, which the library relies on a lot.

Anyway, try it out if you want! And if you know or figure out the "Symbol" bug, please reply. :)

This was referenced Nov 4, 2020
@wolfjagger
Copy link

Took me way too long, but found the bug to be from bundling vue into the library. Vue was bundled in, so when the slot was rendered, it used a Symbol(Fragment). Symbols are unique by default, so the vue that was bundled in and the vue that was used in a consuming library created two different Symbols, and they were compared when trying to render. Since they did not show as equal, it refused to render the Fragment properly and emitted this error.

Fix is just adding externals: { vue: 'vue' } to webpack. Bonus is that the bundle size is smaller.

@josh7weaver
Copy link

Is there any roadmap on upgrading to Vue 3 compatibility? I see @wolfjagger has a PR with at least a good start on it. Is the library author open to PR's on this? I'd be interested in helping out as I can.

Vue 3 is supposed to come off the @next branch by the end of the month, so we should probably get this done sooner than later. That said, December can be a busy month with the holidays so I just want to acknowledge that also.

Any indication from the author or someone with merge powers would be appreciated! Love this library.

@sagalbot sagalbot self-assigned this Dec 18, 2020
@sagalbot
Copy link
Owner

@josh7weaver in typical fashion, I've been slow to action on the Vue 3 updates mostly because it's a really good opportunity for a bit of ground up rewriting that needs to happen. If I'm going to update for Vue 3, I'd prefer to group as many breaking changes that need to occur as possible into that release. The current focus system has a lot of issues that affect UX and accessibility, and I'd also like to get the component to a place where it manages no internal state – just props and events. This would lower the footprint of the component, while reducing the amount of bugs that props like reduce bring to the table.

That said, I don't want the component to fall behind when Vue 3 becomes the norm.

I started freelancing full time back in September, so time has been tight. I have a week at the end of the December that I'm not booked on any projects, and as much as I'll be trying to stay off the keyboard then, I'll probably end up taking a look at this.

@sagalbot sagalbot added the vue 3 label Dec 18, 2020
@sagalbot sagalbot mentioned this issue Dec 28, 2020
3 tasks
@sagalbot sagalbot pinned this issue Dec 28, 2020
@sagalbot
Copy link
Owner

I've consolidated the existing PRs into #1344 – you can track progress there. I'll release under the vue-select@next tag until Vue drops next. Hoping to squeeze in all the breaking changes this week while I'm on vacation. Huge thanks to @ParaBolt & @wolfjagger for really getting the ball rolling.

@Christopher-Hayes
Copy link

Christopher-Hayes commented Jan 14, 2021

I'm on Vue3 and have NPM pulling vue-select in from the vue-3-compat branch, and there's a ? in the middle of the line below (left over TypeScript?). My compiler refused to build because of it. I thought it was telling me there was something major screwed up with the build process. After screwing around for a couple of hours, I tried just removing the ? and everything is running smoothly now.

I didn't have this issue with the latest Vue2 NPM module, and the line below was committed 9 months ago. Weird.

this.$refs.dropdownMenu?.children[this.typeAheadPointer] || false;

UPDATE: And it looks like that was needed. As mentioned above, this seems to be a random bit of Typescript in a .js script.
image
Switched out that line for
const optionEl = this.$refs.dropdownMenu ? this.$refs.dropdownMenu.children[this.typeAheadPointer] : false;
and everything seems to be working again.

@sagalbot
Copy link
Owner

@Christopher-Hayes that's actually just plain old JavaScript - the new optional chaining operator . It allows you to access deeply nested object properties safely, returning null if it doesn't exist. I think you still need to specify explicit support with Babel https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining

@Christopher-Hayes
Copy link

@sagalbot oh, no way! I use it all the time in Typescript, I had no idea it was coming to JavaScript. That's awesome, thanks for the explanation.

@terax6669
Copy link

terax6669 commented Jan 17, 2021

I'm on Vue3 and have NPM pulling vue-select in from the vue-3-compat branch, and there's a ? in the middle of the line below (left over TypeScript?). My compiler refused to build because of it. I thought it was telling me there was something major screwed up with the build process. After screwing around for a couple of hours, I tried just removing the ? and everything is running smoothly now.

I have the same problem, installing @babel/plugin-proposal-optional-chaining and adding to babel.config.js did not help

module.exports = {
  plugins: [
    '@babel/plugin-proposal-optional-chaining',
  ],
}

Error seems to originate from Webpack validating the final output after all loaders:

 ERROR  Failed to compile with 1 error                                                                                                           17:50:03

 error  in ./node_modules/vue-select/src/mixins/pointerScroll.js

Module parse failed: Unexpected token (26:32)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|     maybeAdjustScroll() {
|       const optionEl =
>         this.$refs.dropdownMenu?.children[this.typeAheadPointer] || false;
|
|       if (optionEl) {

 @ ./node_modules/vue-select/src/mixins/index.js 3:0-43 5:32-45
 @ ./node_modules/vue-select/src/index.js
 @ ./src/main.ts
 @ multi (webpack)-dev-server/client?http://***:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.ts

@terax6669
Copy link

webpack/webpack#10227

@pounard
Copy link

pounard commented Jan 19, 2021

Hello, I "almost" made it work, I guess, I got that error:

Uncaught TypeError: this.$on is not a function
    created vue-select.js:1
    callWithErrorHandling runtime-core.esm-bundler.js:154
    callWithAsyncErrorHandling runtime-core.esm-bundler.js:163
    callSyncHook runtime-core.esm-bundler.js:5898
    applyOptions runtime-core.esm-bundler.js:5829
    finishComponentSetup runtime-core.esm-bundler.js:6507
    setupStatefulComponent runtime-core.esm-bundler.js:6440
    setupComponent runtime-core.esm-bundler.js:6380
    mountComponent runtime-core.esm-bundler.js:4118
    processComponent runtime-core.esm-bundler.js:4094
    patch runtime-core.esm-bundler.js:3712
    render runtime-core.esm-bundler.js:4794
    mount runtime-core.esm-bundler.js:3019
    mount runtime-dom.esm-bundler.js:1220
    initAutocomplete vue-select.ts:55
    ts vue-select.ts:62

I'm using those versions altogether (writing TypeScript here, not JS):

  • vue-select ^3.11.2:
  • @vue/* 3.0.5
  • @types/vue-select ^2.5.1

My code is (less the init code, that doesn't matter here):

import { createApp } from 'vue'
import vSelect from 'vue-select';

function initAutocomplete(element: HTMLSelectElement): void {
    // Prepare a div below our select and hide the existing select
    const placeholder = document.createElement("div");

    const props = {
        value: null as any,
        options: [] as any[],
        placeholder: element.getAttribute("placeholder"),
        // ... a few other options
    };

    const defaults = [];
    for (let opt of (element.options as unknown as HTMLOptionElement[])) {
        const value = {label: opt.label, id: opt.value};
        props.options.push(value);
        if (opt.selected) {
            defaults.push(value);
        }
    }

    props.value = defaults;

    createApp(vSelect, { props: props }).mount(placeholder);
}

Following many links I ended up on: https://github.com/vuejs/rfcs/blob/master/active-rfcs/0020-events-api-change.md which seem to explain that this.$on was removed in Vue3.

Everything explodes here when reaching: https://github.com/sagalbot/vue-select/blob/master/src/components/Select.vue#L636

Is there a possible workaround (i.e. avoiding calling this method) by configuration ? Did I wrote something wrong in my code ? Should I wait for a Vue3 compatible version ? Should I fork if I need it quickly ?

@Christopher-Hayes
Copy link

@pounard I was getting the same error. Vue-select 3.11.2 doesn't have any Vue3 compatibility updates, right now everything is on the vue-3-compat branch and there's no NPM release for those changes yet, so if you want Vue3 compatibility you'll have to tell NPM to pull in that specific branch directly from GitHub. I forget the exact syntax of the npm install I used, but this is what I have in my package.json:

    "vue-select": "https://github.com/sagalbot/vue-select/tarball/feat/vue-3-compat"

So, if you run npm rm vue-select, add the line above to your dependencies in your package.json, and then run npm install, it should install this branch.
Once you reach that point, you'll may run into the error I mentioned a few replies up, I don't have the special Babel configuration for Optional Chaining, so maybe someone who has that working can help you with that. But, if you just want to get it working quick/dirty, change line 25 of /your_project_root/node_modules/vue-select/src/mixins/pointerScroll.js to:

const optionEl = this.$refs.dropdownMenu ? this.$refs.dropdownMenu.children[this.typeAheadPointer] : false

@terax6669
Copy link

Every package maintainer should be putting this into their readmes right now:

For Vue 3 (WIP):

npm install git+https://github.com/sagalbot/vue-select.git#feat/vue-3-compat

Suggestion to vue-select maintainers: release this as next on npm so people can just npm i vue-select@next

@pounard
Copy link

pounard commented Jan 19, 2021

Thanks @Christopher-Hayes and @terax6669 for answering, I'm trying to find stable components and I'm currently testing @vueform/multiselect which also seem to implement what I need. I'm still in early dev phase of the project I'm working on, so I might re-evaluate this component which seems nice as soon as a @next release exists ! Thanks for everything.

@rrrrando
Copy link

Hey!

Got a beginner question here. When i install from the vue-3-compat branch and try to import like this:

import vSelect from 'vue-select';

webpack gives me this error message:

Module not found: Error: Can't resolve 'vue-select' in 'path/to/app.js'

What am i doing wrong?

@Christopher-Hayes
Copy link

Hey!

Got a beginner question here. When i install from the vue-3-compat branch and try to import like this:

import vSelect from 'vue-select';

webpack gives me this error message:

Module not found: Error: Can't resolve 'vue-select' in 'path/to/app.js'

What am i doing wrong?

I had the same issue, I used a workaround, may not be the best way to do it, but it works for me. Use the import below instead of the usual 'vue-select' (but change the pathing to match your directory structure, I just threw it into my main.ts so I didn't have to think about it importing everywhere)

import vSelect from './../node_modules/vue-select/src/index.js';

@mhmousavi
Copy link

@pounard I was getting the same error. Vue-select 3.11.2 doesn't have any Vue3 compatibility updates, right now everything is on the vue-3-compat branch and there's no NPM release for those changes yet, so if you want Vue3 compatibility you'll have to tell NPM to pull in that specific branch directly from GitHub. I forget the exact syntax of the npm install I used, but this is what I have in my package.json:

"vue-select": "https://github.com/sagalbot/vue-select/tarball/feat/vue-3-compat"

So, if you run npm rm vue-select, add the line above to your dependencies in your package.json, and then run npm install, it should install this branch.
Once you reach that point, you'll may run into the error I mentioned a few replies up, I don't have the special Babel configuration for Optional Chaining, so maybe someone who has that working can help you with that. But, if you just want to get it working quick/dirty, change line 25 of /your_project_root/node_modules/vue-select/src/mixins/pointerScroll.js to:

const optionEl = this.$refs.dropdownMenu ? this.$refs.dropdownMenu.children[this.typeAheadPointer] : false
Originally posted by @Christopher-Hayes in #1251 (comment)

Hi I do this last line in my project and that error gone. but now my v-select doesn't show anything at all on project! but I can see the component in the inspect dev tool!

@sjblasko
Copy link

I've installed the vue-3-compat and have been getting the optional chaining issue. I have installed @babel/plugin-proposal-optional-chaining and added it to babel.config.js and those steps did not help.

module.exports = {
    presets: ["@vue/cli-plugin-babel/preset"],
    plugins: ["@babel/plugin-proposal-optional-chaining"]
};

Error:

Module parse failed: Unexpected token (26:32)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|     maybeAdjustScroll() {
|       const optionEl =
>         this.$refs.dropdownMenu?.children[this.typeAheadPointer] || false;
|
|       if (optionEl) {

 @ ./node_modules/vue-select/src/mixins/index.js 3:0-43 5:32-45
 @ ./node_modules/vue-select/src/index.js
 @ ./node_modules/@vue/cli-plugin-babel/node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib??ref--12-1!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist??ref--0-1!./Vue/App/Pages/Samples/Sample1/Sample1.vue?vue&type=script&lang=js

I can update the pointerScroll.js directly but I am starting to involve other developers and they are also having to manually update the file as well. Has anybody been able to get the Babel Optional Chaining working?

@zluiten
Copy link

zluiten commented Mar 1, 2021

I'm able to use this branch in my Vue 3 project 👍 . But I don't want its css. In the builds of vue-select the css is extracted to a separate file (I think?) and you have to include it manually according to the docs. But when using the source directly the styling is part of the Select.vue file. How do I configure webpack to ignore that? Can anyone point me in the right direction?

I tried to exclude /vue-select/ using the chainWebpack in vue.config.js

module.exports = {
  chainWebpack: (config) => {
    config.module.rule('scss').exclude.add(/vue-select/)
  },
}

But it seems to parse the styling section anyway and then errors out with

You may need an additional loader to handle the result of these loaders.
|
>   @import '../scss/vue-select.scss';
|

Can some webpack expert point me in the right direction? :)

@pounard
Copy link

pounard commented Mar 1, 2021

Can anyone point me in the right direction?

I think that using the build the is the right solution, or you may have to patch your local copy I guess.

@mathiash98
Copy link

mathiash98 commented Nov 30, 2021

@Kalifr use the beta channel for vue-select "vue-select": "^4.0.0-beta.1", works fine for me. Be sure to upgrade to vue: 3.2.x

btw, for anyone overriding default components =>

  • In the vue3 beta version use:
import vSelect from "vue-select";
vSelect.props.components.default = () => ({
  Deselect: CloseIcon, // CloseIcon and CaretDownIcon are vue components with svg inside of them
  OpenIndicator: CaretDownIcon,
});

Instead of:

import vSelect from "vue-select";
vSelect.props.components.default = () => ({
  Deselect: {
    render: (createElement) => createElement(CloseIcon),
  },
  OpenIndicator: {
    render: (createElement) => createElement(CaretDownIcon),
  },
});

@Barrandov
Copy link

How do you connect it via CDN? I am trying to make it work, but it raises the problem.
https://codepen.io/BarrandovPan/pen/wvrdPJy

@kris-sum
Copy link

2. Use the event `@option:selected` in lieu of `@input`

Instead of @input use the event @update:model-value , option:selected only fires when selecting from the dropdown, and doesn't give a null value on clear etc.

@amchconsult
Copy link

Looks like CDN way is not working.
Error:

Uncaught TypeError: Cannot read properties of undefined (reading 'createTextVNode')
    at Module.<anonymous> (index.js:4)
    at o (index.js:4)
    at index.js:4
    at index.js:4
    at index.js:4
    at index.js:4

using app.component("v-select", VueSelect);

Does someone found a fix for it?

thank you

@luisfuertes
Copy link

@connorshea have you been able to solve it?

Uncaught TypeError: Object(...) is not a function

@sagalbot
Copy link
Owner

sagalbot commented Jan 4, 2022

@luisfuertes can you provide more details about that error? When does it occur?

@mathiash98
Copy link

@luisfuertes can you provide more details about that error? When does it occur?

Pretty sure this error is due to not having upgrade vue to 3.2.x

@amchconsult
Copy link

My testing code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>VUE 3 TEST vue-select</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
    <!-- <link href="public/assets/vue-select-4.0.0-beta/dist/vue-select.css" rel="stylesheet"> -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vue-select@4.0.0-beta.2/dist/vue-select.css">
</head>
<body>

<style>
    
</style>

<div id="app">
    <div class="container mt-4">

        <v-select :options="options" v-model="result"></v-select>
        
    </div>
</div>

<!-- <script src="public/assets/vue3/dist/vue.global.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue@3.2.26/dist/vue.global.js"></script>
<!-- <script src="public/assets/vue-select-4.0.0-beta/dist/vue-select.js"></script> -->
<!-- <script src="https://cdn.jsdelivr.net/npm/vue-select@4.0.0-beta.2/dist/vue-select.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue-select@4.0.0-beta.2/dist/vue-select.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>

<script>
    var vm = Vue.createApp({
        components: {
            'v-select': VueSelect
        },
        data(){
            return {
                options: [
                    'foo',
                    'bar',
                    'baz'
                ],
                result:null,
            }
        },
    })
    .mount('#app')
</script>

</body>
</html>

Thank you

@luisfuertes
Copy link

I have "vue": "^3.0.0", I will try to upload the version and I will tell you

@bci24
Copy link

bci24 commented Jan 5, 2022

I want to use vue-select as input with autocomplete. I have set a simple sandbox...

https://codesandbox.io/s/frosty-architecture-64qn7?file=/src/App.vue

I have list of countries and if the country is not in the list it will add it.

The problem is when selecting for ex: "Canada" and click again on input ... it will clear the selected item and open the dropdown (which is the default behavior)

I want to be able to edit the selected value (for example "Canda") to change CA or something else ... to work like an standard input text... when click on input to not clear the selected item.

It is possible to make this?

@sagalbot
Copy link
Owner

@luisfuertes
Copy link

luisfuertes commented Jan 13, 2022

Hi, with vue version updated all work fine, but i have a problem.

I am reading this section of doc https://vue-select.org/guide/values.html#getting-and-setting

This is my code, i use @input="setSelected" and on setup() i return setSelected function.
The problem is setSelected never called. What im doing wrong? Thanks in advanced

(extra data, multiple is true)

<template>
  <div v-bind:class="[{ 'container--disabled': disabled, 'container--error': error }, 'container']">
    <label :for="id ? id : null" class="label" v-if="label">{{ label }}</label>
    <div class="input-container">
      <VueSelect
        class="input-vue-select"
        :id="id"
        :disabled="disabled"
        :options="options"
        :label="labelKey"
        :reduce="v => v[valueKey]"
        @input="setSelected"
        @focus="$emit('on-focus')"
        @blur="$emit('on-blur')"
        :placeholder="placeholder"
        :tabindex="tabindex"
        :multiple="multiple"
      >
      </VueSelect>
      <WarningIcon v-if="error" variant="error" containerClass="warning-icon" />
    </div>
    <span class="info" v-if="info">{{ info }}</span>
    <span class="info error" v-if="error">{{ error }}</span>
  </div>
</template>

<script>
import WarningIcon from '@/assets/icons/warning.vue'
import VueSelect from 'vue-select'
import 'vue-select/dist/vue-select.css'

export default {
  name: 'InputSelect',
  components: {
    WarningIcon,
    VueSelect,
  },
  emits: ['on-change', 'on-blur', 'on-focus'],
  setup(props, { emit }) {
    const setSelected = values => {
      console.log({ values })
      emit('on-change', value)
    }
    return { setSelected }
  },
}
</script>

@luisfuertes
Copy link

luisfuertes commented Jan 14, 2022

If i use v-model="selected" and selected is a child component data ref (selected) all works fine, load initial value and set the selected value.

But if use v-model="value" or :value="value" and value come from parent props, it isnt work. Dont load the current value of value and dont call to @input function

Example case 1 (works)

<template>
  <div v-bind:class="[{ 'container--disabled': disabled, 'container--error': error }, 'container']">
    <label :for="id ? id : null" class="label" v-if="label">{{ label }}</label>
    <div class="input-container">
      <VueSelect
        class="input-vue-select"
        :id="id"
        :disabled="disabled"
        :options="options"
        :label="labelKey"
        :reduce="v => v[valueKey]"
        v-model="selected"
        :placeholder="placeholder"
        :tabindex="tabindex"
        :multiple="multiple"
      >
      </VueSelect>
      <span>{{ value }}</span>
      <WarningIcon v-if="error" variant="error" containerClass="warning-icon" />
    </div>
    <span class="info" v-if="info">{{ info }}</span>
    <span class="info error" v-if="error">{{ error }}</span>
  </div>
</template>

<script>
import WarningIcon from '@/assets/icons/warning.vue'
import VueSelect from 'vue-select'
import { ref } from 'vue'
import 'vue-select/dist/vue-select.css'

export default {
  name: 'InputVueSelect',
  components: {
    WarningIcon,
    VueSelect,
  },
  emits: ['on-change', 'on-blur', 'on-focus'],
  setup(props) {

    const selected = ref(props.value)

    return { selected }
  },
}
</script>

Example case 2 (Not works)


<template>
  <div v-bind:class="[{ 'container--disabled': disabled, 'container--error': error }, 'container']">
    <label :for="id ? id : null" class="label" v-if="label">{{ label }}</label>
    <div class="input-container">
      <VueSelect
        class="input-vue-select"
        :id="id"
        :disabled="disabled"
        :options="options"
        :label="labelKey"
        :reduce="v => v[valueKey]"
        :value="value"
        @input="setSelected"
        :placeholder="placeholder"
        :tabindex="tabindex"
        :multiple="multiple"
      >
      </VueSelect>
      <span>{{ value }}</span>
      <WarningIcon v-if="error" variant="error" containerClass="warning-icon" />
    </div>
    <span class="info" v-if="info">{{ info }}</span>
    <span class="info error" v-if="error">{{ error }}</span>
  </div>
</template>

<script>
import WarningIcon from '@/assets/icons/warning.vue'
import VueSelect from 'vue-select'
import { ref } from 'vue'
import 'vue-select/dist/vue-select.css'

export default {
  name: 'InputVueSelect',
  components: {
    WarningIcon,
    VueSelect,
  },
  emits: ['on-change', 'on-blur', 'on-focus'],
  setup(props, { emit }) {

    const setSelected = values => {
      console.log({ values })
      emit('on-change', values)
    }

    const selected = ref(props.value)

    return { setSelected, selected }
  },
}
</script>

@luisfuertes
Copy link

luisfuertes commented Jan 14, 2022

This is my provisional workaround

<template>
  <div v-bind:class="[{ 'container--disabled': disabled, 'container--error': error }, 'container']">
    <label :for="id ? id : null" class="label" v-if="label">{{ label }}</label>
    <div class="input-container">
      <VueSelect
        class="input-vue-select"
        :id="id"
        :disabled="disabled"
        :options="options"
        :label="labelKey"
        :reduce="v => v[valueKey]"
        :placeholder="placeholder"
        :tabindex="tabindex"
        :multiple="multiple"
        v-model="selected"
      >
      </VueSelect>
      <WarningIcon v-if="error" variant="error" containerClass="warning-icon" />
    </div>
    <span class="info" v-if="info">{{ info }}</span>
    <span class="info error" v-if="error">{{ error }}</span>
  </div>
</template>

<script>
import WarningIcon from '@/assets/icons/warning.vue'
import VueSelect from 'vue-select'
import { ref, watch } from 'vue'
import 'vue-select/dist/vue-select.css'

export default {
  name: 'InputVueSelect',
  components: {
    WarningIcon,
    VueSelect,
  },
  emits: ['on-change', 'on-blur', 'on-focus'],
  setup(props, { emit }) {
    const selected = ref(props.value)
    watch(selected, newSelected => emit('on-change', newSelected))
    return { selected }
  },
}
</script>

And on parent

               <InputVueSelect
                    id="calendars"
                    :options="calendars"
                    valueKey="uuid"
                    labelKey="name"
                    class="calendar-select"
                    :placeholder="t('calendar.calendarsInputPlaceholder')"
                    :selectedValue="values.calendars"
                    :multiple="true"
                    @on-change="v => (values.calendars = v)"
                    :value="values.calendars"
                    :error="errors.calendars"
                  />

@bartenra
Copy link

bartenra commented Jan 21, 2022

For me the input event is not popping up as well.

<template>
  <div>
    <v-select
      :options="['Canada', 'United States']"
      @input="log($event)"
      v-model="val"
    ></v-select>
    {{ val }}
  </div>
</template>

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

const val = ref('');
const log = (e) => console.log(e);
</script>

@raducretu
Copy link

Looks like CDN way is not working. Error:

Uncaught TypeError: Cannot read properties of undefined (reading 'createTextVNode')
    at Module.<anonymous> (index.js:4)
    at o (index.js:4)
    at index.js:4
    at index.js:4
    at index.js:4
    at index.js:4

using app.component("v-select", VueSelect);

Does someone found a fix for it?

thank you

+1

@amchconsult
Copy link

amchconsult commented Jan 26, 2022

You can see my example here.
https://github.com/sagalbot/vue-select/issues/1251#issuecomment-1005597589
But it is not working properly.

@raducretu
Copy link

You can see my example here.
https://github.com/sagalbot/vue-select/issues/1251#issuecomment-1005597589
But it is not working properly.

The code you provided prompts the same error:
Screenshot 2022-01-26 at 14 53 27

@sagalbot
Copy link
Owner

@luisfuertes sorry about that - the docs need to be versioned and updated. The input event is no longer emitted, use update:modelValue instead. https://v3.vuejs.org/guide/migration/v-model.html#overview

@luisfuertes
Copy link

luisfuertes commented Jan 27, 2022

@sagalbot can i use modelValue instead value and update:modelValue instead input props? to receive value from parent component and update it on parent?

@sagalbot
Copy link
Owner

@luisfuertes yep!

@sagalbot
Copy link
Owner

I'm going to close this issue in favour of #1597 where it's easier to find consolidated information about the v4 / Vue 3 compatible release, including a checklist for the merge to master, as well as a wishlist of things I hope to accomplish before that happens. Thanks to everyone who's contributed to the conversation!

@sagalbot sagalbot unpinned this issue Feb 20, 2022
@pierresh
Copy link

Looks like CDN way is not working. Error:

Uncaught TypeError: Cannot read properties of undefined (reading 'createTextVNode')
    at Module.<anonymous> (index.js:4)
    at o (index.js:4)
    at index.js:4
    at index.js:4
    at index.js:4
    at index.js:4

using app.component("v-select", VueSelect);
Does someone found a fix for it?
thank you

+1

Hello,

I get the same error just by loading the latest vue-select@beta from the CDN <script src="https://unpkg.com/vue-select@beta"></script>

vue-select@beta:1 Uncaught TypeError: Cannot read properties of undefined (reading 'createTextVNode')
    at vue-select@beta:1:2226
    at vue-select@beta:1:22681
    at vue-select@beta:1:22687
    at vue-select@beta:1:228
    at vue-select@beta:1:237

Has anyone found a solution for this?

@amchconsult
Copy link

Looks like CDN is not working. I have tried many ways but not luck.

@renepardon
Copy link

renepardon commented Jun 1, 2022

Hey guys,
works good so far but I have a problem with "multiple"/"taggable". Debugging on the Vue Dev console I see the selected values are set but they are not being displayed. If I then select one again, only this one is selected:

How I call my component:

<AnsibleTagsSelect v-model="form.tags"
                   :playbook-default-tags="selectedPlaybook?.tags"
                   :selected="selectedPlaybook?.tags"/>

Custom select component:

<script lang="ts">
import {computed, defineComponent, ref, watch} from "vue";
import vSelect from 'vue-select'
import 'vue-select/dist/vue-select.css';

interface ITag {
  label: string
  value: string
}

export default defineComponent({
  name: 'AnsibleTagsSelect',

  emits: ['change'],

  components: {vSelect},

  props: {
    playbookDefaultTags: {
      type: Array,
      default: []
    },
    selected: {
      type: Array,
      default: []
    }
  },

  setup: function (props, {emit}) {
    const allAnsibleTags: Array<ITag> = [
      {label: 'common', value: 'common'},
      {label: 'users', value: 'users'},
      {label: 'ssh', value: 'ssh'},
      {label: 'firewall', value: 'firewall'},
      {label: 'nginx', value: 'nginx'},
      {label: 'redis', value: 'redis'},
      {label: 'mariadb', value: 'mariadb'},
      {label: 'meilisearch', value: 'meilisearch'},
      {label: 'php', value: 'php'},
      {label: 'nodejs', value: 'nodejs'},
      {label: 'supervisor', value: 'supervisor'},
      {label: 'laravel', value: 'laravel'},
    ]

    const selected = ref(props.selected)
    const filteredTags = computed<Array<ITag>>(() => {
      let tags: Array<ITag> = []

      allAnsibleTags.forEach((tag) => {
        if (props.playbookDefaultTags.includes(tag.value)) {
          tags.push(tag)
        }
      })

      return tags
    })

    watch(selected, () => {
      console.log('selected changed', selected.value)
    })
    watch(filteredTags, () => {
      // Reset selected values if filtered tags changed
      selected.value = props.selected.map((tag: any) => tag)

      console.log('selected.value 2', selected.value)
    })

    const selectionChanged = (values: Array<string>) => {
      selected.value = values
      emit('change', values)
    }

    return {
      selected,
      filteredTags,
      selectionChanged,
    }
  },
})
</script>

<template>
  <v-select :model-value="selected"
            :options="filteredTags"
            :reduce="item => item.value"
            autocomplete="off"
            label="label"
            multiple
            taggable
            v-on:update:modelValue="selectionChanged"
  ></v-select>
</template>

Here is the console output:
Bildschirmfoto 2022-06-01 um 07 08 17

So initially no "playbook" is selected. As soon as I select one, the corresponding tags should be set already as selected and they are, but not being displayed as selected. Maybe you can point me to the solution?

I also figured that if I select one, it still appears in the list as selectable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.