lunarfyre
lunarfyre

Reputation: 1736

Is it possible to add a vue component to a traditional html form?

Is it possible to add a vue input component to a standard html form? I know this is not the ideal way to handle vue forms, but I'm curious about the possibility as a "quick and dirty" way for adding custom elements into pre existing html forms. Here's a hypothetical example:

<form action="/users" accept-charset="UTF-8" method="post">
  <input type="email" name="user[email]" />
  <input type="password" name="user[password]" />
  <my-custom-fancy-vue-component />
  <input type="submit"value="Sign up">
</form>

I'm wondering if the browser can read the value exposed by an input element withen the vue component and send that as a param when the user submit the form. Is there any other way to tell the browser how to access the value from a vue component if for example it doesn't use a native input internally, perhaps using a web component as a wrapper or using shadow dom?

Upvotes: 1

Views: 655

Answers (1)

skirtle
skirtle

Reputation: 29132

Any <input> elements within the form should be included by the browser when the form is submitted. The browser won't care that the <input> is inside a Vue component.

For components that don't already have an <input> (or other suitable form element) you can add a hidden input, <input type="hidden">, to hold the value.

If the component you want to include is a third-party component then you won't be able to add the hidden input directly. However, you could still add it by using a wrapper component. The example below illustrates how you could handle that scenario.

const thirdPartyComponent = {
  template: `
    <button
      @click="onClick"
      type="button"
    >
      Increment {{ value }}
    </button>
  `,
  
  props: ['value'],
  
  methods: {
    onClick () {
      this.$emit('input', this.value + 1)
    }
  }
}

const myCustomFancyVueComponent = {
  template: `
    <div>
      <third-party-component v-model="counter" />
      <input type="hidden" :value="counter">
    </div>
  `,
  
  components: {
    thirdPartyComponent
  },
  
  data () {
    return {
      counter: 4
    }
  }
}

new Vue({
  el: 'form',
  
  components: {
    myCustomFancyVueComponent
  }
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>

<form action="/users" accept-charset="UTF-8" method="post">
  <input type="email" name="user[email]">
  <input type="password" name="user[password]">
  <my-custom-fancy-vue-component></my-custom-fancy-vue-component>
  <input type="submit" value="Sign up">
</form>

Upvotes: 1

Related Questions