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 v-model not working in vscode-text-field #486

Closed
davidkjackson54 opened this issue Jun 1, 2023 · 11 comments
Closed

Vue v-model not working in vscode-text-field #486

davidkjackson54 opened this issue Jun 1, 2023 · 11 comments
Assignees
Labels
bug Something isn't working

Comments

@davidkjackson54
Copy link

davidkjackson54 commented Jun 1, 2023

I am using VSCode Toolikit UI with Vue.
I am following the documentation on how to use vscode-text-field and failing to get at the entered data:
It works if I use plan old <input statement in conjunction with v-model
but not when i use vscode-text-input

I suspect something really obvious is missing but I can't see what that might be.

export default defineComponent({
  components:{},
data() {
  return {
    dj: "",
    user: "",
    pass: ""
  };
},
methods: {
  validate() {
    console.log("user " , this.user);    <=== doesn't display anything
    console.log("password " , this.pass);   <=== doesn't display anything
    console.log("dj " , this.dj);   <==== this works and displays the entered data    
    vscode.postMessage({
        command: "hello",
        text: "Input validated",
    })}
  }
})  
</script>

<template>
    <div>
      <h1>Enter credentials</h1>  
        <input type="text" v-model="dj"/>  
        <vscode-text-field type="text" v-model="user" maxlength="8">Userid</vscode-text-field><br><br>
        <vscode-text-field type="password"  v-model="pass">Password</vscode-text-field><br><br>
        <vscode-button v-on:click="validate">Accept</vscode-button>
    </div>
</template>
@davidkjackson54 davidkjackson54 added the bug Something isn't working label Jun 1, 2023
@davidkjackson54 davidkjackson54 changed the title trying to use vscode-text-field and not able to access the data trying to use vscode-text-field and not getting the inputted data back Jun 2, 2023
@davidkjackson54 davidkjackson54 changed the title trying to use vscode-text-field and not getting the inputted data back trying to use vscode-text-field and not getting the inputted data back using Vue Jun 2, 2023
@davidkjackson54
Copy link
Author

davidkjackson54 commented Jun 2, 2023

So, condensing the above:
This works and the resultant input is saved in the variable - dj:
<input v-model="dj"/>
but this fails and nothing is put into the variable - user:
<vscode-text-field v-model="user">Userid</vscode-text-field>

Variables are defined in:

export default defineComponent({
  components:{},
data() {
  return {
    dj: "",
    user: "",
    pass: ""
  };
},

@davidkjackson54
Copy link
Author

davidkjackson54 commented Jun 3, 2023

Further investigation and I find that this "works" but is a bit kludgy: but this is a 'one way' setting of the value rather than using v-model which is 'two way'.
This is basically a long winded form of v-model

<script>
.
methods: {
   handleInput(event: any) {
      this.user = event.target.value;
    }
  }
</script>
<template>
<vscode-text-field 
          maxlength="8"
          @input="handleInput">
          Userid         
</vscode-text-field>
</template>

At this point, I suspect a bug in the use of v-model not working in the VSCode ui toolkit

@davidkjackson54 davidkjackson54 changed the title trying to use vscode-text-field and not getting the inputted data back using Vue Vue v-model not working in vscode-text-field Jun 3, 2023
@davidkjackson54
Copy link
Author

@hawkticehurst any thoughts on this? thanks!

@hawkticehurst
Copy link
Member

Hey @davidkjackson54! Thanks for the poke.

Just wanted to quickly chime in to say I have seen this and it's on my to-do list to circle back to, but that might not happen for a while. I've mentioned this in other issues, but the toolkit has been tightly resourced for the last year or so (myself and one other person split our time between this and several other projects). I'm currently focused on another project for the next few weeks so I hope you understand :)

Also, from a quick pass, I, unfortunately, don't have much to offer at this point since I'm not familiar with how Vue's v-model works. The best suggestion I can offer at this point is to look into how v-model should be configured to work with web components (if you haven't already) since I'd wager that's where the high-level issue is coming from

@davidkjackson54
Copy link
Author

davidkjackson54 commented Jun 15, 2023

Hi @hawkticehurst . According to the Vue documentation vue doc it states that :

<input
  :value="text"
  @input="event => text = event.target.value">

The v-model directive helps us simplify the above to:

template
<input v-model="text">

I find that the long winded method above does work but the 1 liner abbreviated method does not work with vscode-text-field

As I mentioned above, if I add a simple html input field such as:
<input v-model="dj"/>
the value entered is correctly placed into the variable - dj

So the problem is limited to the VSCode UI toolkit use of vscode-text=field

@hawkticehurst
Copy link
Member

Thanks for clarifying/providing a reference to the docs!

I looked over the docs and did another Google search and I am now feeling very confident that this is still an issue with v-model support for web components on Vue's side. In particular, I found this open issue in the Vue repo discussing how v-model is not supported in another web component library called StencilJS.

Reading through the issue thread, there are a lot of people using even more web component libraries (beyond Stencil) with the same problem. Towards the bottom of the thread there's another linked issue discussing the lack of v-model support on custom elements (aka web components), and this issue was resolved by a PR from Evan You that seems to have fixed this problem (maybe?) –– but only for "declared custom elements".

So googling "vue declared custom elements" brought me to this documentation page discussing Vue and Web Components where it seems like you may have to configure the compilerOptions.isCustomElement option to get things working??

Again, I'm not super familiar with Vue so this is my best guess, but at this point, I'm going to suggest you open an issue or use the Discussions tab in Vue's repo to seek help/guidance on how to get v-model support working with web components.

@hawkticehurst
Copy link
Member

I'm also going to go ahead and close this issue since there are so many other web component libraries that are facing the same issue and v-model support for web components definitely falls under Vue's purview to support/fix

If you have any other questions, comments, updates, etc., please feel free to add them to this thread and I'm happy to keep discussing :)

@davidkjackson54
Copy link
Author

Thanks for the detailed research and opening the issue in the vue GitHub pages. I will add to that and hope they will address this.
Aorry for pointing the finger at your code!!

@davidkjackson54
Copy link
Author

Just to close this out.
This does work and thanks to @hawkticehurst for the suggestion.
add compilerOptions to denote that we are using customElements to vite.config.ts.

plugins: [
    vue({
      template: {
        compilerOptions: {
          // treat all tags with a dash as custom elements
          isCustomElement: (tag) => tag.includes("-"),
        },
      },
    }),
  ],

@protozoo
Copy link

protozoo commented Nov 14, 2023

Hi there! I was having the same issue (in my case I'm using "vscode-dropdown", not "vscode-text-field") and using @davidkjackson54 ' snippet from last comment (compilerOptions / isCustomElement) fixed the issue in dev mode (I'm using Vue-CLI with "npm run start").

However, when I build for production ("npm run build") it doesn't work. The dropdown gets displayed as it should, with the correct selected value, but when I click the dropdown and change its value, it doesn't change. Also, no errors or warning in the devtools console or in the build process output.

@davidkjackson54 did you bundle the app and did it work well there?

Interestingly, if I use this approach:

<vscode-text-field"
  :value="text"
  @input="event => text = event.target.value">

it does work. I think I can use this but would prefer the abbreviated "v-model" approach.

Thanks in advance!

@maninak
Copy link

maninak commented Jan 20, 2024

Came here also looking for v-model use with vscode-dropdown and it all works flawlessly/as-expected for me if I do the following:

// vite.config.ts
export default defineConfig({
  plugins: [
    vue({
      template: {compilerOptions: { isCustomElement: (tag) => tag.includes("vscode-") }},
    }),
  ],
})
// script in my .vue file
const selectedRevisionOption = ref(shortenHash(latestRevision.value.id))
// `selectedRevision` is what I actually need further along in my app
const selectedRevision = computed(
  () =>
    patch.value.revisions.find((revision) =>
      revision.id.includes(selectedRevisionOption.value)
    ) as Revision
)
<!-- template in my .vue file -->
<vscode-dropdown id="revision-selector" v-model="selectedRevisionOption">
  <vscode-option v-for="revision in patch.revisions" :key="revision.id">{{
    shortenHash(revision.id)
  }}</vscode-option>
</vscode-dropdown>

There are two things to keep in mind, one of which may be the reason why v-model didn't work for @protozoo :

  1. Make sure the variable used as v-model is a ref() with an initial value set as per the docs
    image
  2. Make sure the initial value for the variable used as v-model matches the innerText of the <vscode-option> you want to set as default, in my case I'm rendering a shortened hash of the revision ids, but was setting the initial value of the ref with the full hash (vs shortening is) which ended up not matching with any of the options.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants