1

I have a fully functional set of forms that are rendered with PHP and look something like this on the server-side:

<div id="app">
  <form action="https://example.com" method="POST">
    <div class="form-group">
      <input type="text" name="name" value="<?php echo $_SESSION['name']['value'] ?? ''; ?>" />
      <span class="error-message"><?php echo $_SESSION['name']['error'] ?? ''; ?></span>
    </div>
    <button type="submit" name="submit">Submit</button>
  </form>
</div>

I want to know what the approach is to progressively enhance these forms with Vue.js. For example, intercepting form submission and performing an AJAX request, and using Vuelidate in addition to using all the other data binding perks of Vue.

If I were to just mount the instance right onto #app, then it would work, but any vue attributes I wrote in the HTML would end up making the HTML markup invalid if Vue somehow didn't load.

<div id="app">
  <form @submit.prevent="submit" action="https://example.com" method="POST"
  //...
</div>

<script>
  var app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue!'
    }
  })
</script>

// If the script never ran then @submit.prevent="submit" would be in the HTML markup.

My ultimate goal would be to have a form submitted with AJAX by Vue.js that is processed on the server-side with PHP, but also have server-side PHP rendering available in case Vue didn't load.

Do I need to use server-side rendering so that the server can determine whether to render Vue markup or regular HTML? Are there common approaches to this?

Timothy Fisher
  • 1,001
  • 10
  • 27

1 Answers1

0

One thing about web browsers is that they tend to be forward-compatible. Because of this, nonstandard but coherent HTML attributes tend to be ignored in practice. So, it should be fine to have v-model, v-on, v-slot, and v-bind everywhere.

Shorthand syntax (@event, #slot) is a different story. This StackOverflow answer suggests that SGML would have issues with attribute names starting with @, :, or #. HTML version 4 is based on SGML, so I imagine there'd be problems there, too.

The HTML 5 spec seems a lot more lenient, though.

For the purposes of progressive enhancement, I'd recommend sticking with the longform v-slot, v-on, and v-bind attributes. These should be OK.

Other tips that might be useful:

  • If you want to progressively enhance {{ someVariable }} substitutions, then your best bet is to instead use the v-text directive on a <span>.

  • You can enhance normal HTML elements into custom Vue components by using Dynamic Components. e.g.

    <input is="AwesomePhoneNumberInput">