Justin Duke

Creating a password validator component in Vue

Sometimes you procrastinate one feature by writing another. Even if that other feature is pretty small and inconsequential. 1

For me, that other feature — if you can even call it a feature — was password strength testing for Buttondown.

Read more →

Globally accessible Vue properties

So, Buttondown uses django-js-reverse, which is a fantastic way to handle naming URLs and consolidate routing logic. It means that if I’ve got a bunch of views registered in Django like this…

urls = [
    url(r'^export_data/', miscellany.export, name='export-data'),
    url(r'^resend-confirmation-email', miscellany.resend_confirmation_email, name='resend-confirmation-email'),
    url(r'^confirm-registration/(?P<confirmation_id>.+)', miscellany.confirm_registration, name='confirm-registration'),
    # And so on.
 ]

I can access those in a globally scoped object on the frontend, where keys are the URL names and the values are their corresponding endpoints:

> Urls.export_data()
"/api/emails/export_data/"

This is great for utility methods and such, but Vue’s single file components don’t have access to global variables (or, rather, variables declared on window.) This is for good reason — explicit rather than implicit! — but still means if I want to reference this object in the template code itself:I have to expose it as a computed property:

computed: {
    Urls() { return Urls; }
}

Sure, that’s only three lines, but it’s a pain in the ass feels unnecessarily repetitive. Thankfully, Vue offers a better way, which they refer to as instance properties:

There may be data/utilities you’d like to use in many components, but you don’t want to pollute the global scope. In these cases, you can make them available to each Vue instance by defining them on the prototype.

All you have to do is add Urls (or your object of choice) to Vue’s prototype method:

Vue.config.productionTip = false;
Vue.prototype.Urls = Urls;

// Do the rest of your setup.
new Vue({
  el: '#app',
  router,
  store,
});

And ta-da! All components now have access to Urls, so you can access it like so:

<a :href="Urls.export_data()">Export data</a>

Permalink

What Vue needs next

Note This is gonna sound like a negative essay. Which it kinda is. But it's very much not a condemnation of Vue!

Vue is great. You should try Vue.

If I had written What Vue Doesn't Need it would be an incredibly long post! This is just things I wish were better about it.

I’ve been using Vue a lot recently on a few test projects, and most notably on Buttondown.

Buttondown’s frontend is 100% Vue: around twenty screens (which are themselves components) and around thirty miscellaneous components, tied together with Vuex and Vue-Router.

Overall, Vue is a really great tool, and the first word I’d use to describe it is pragmatic. Almost everything feels and acts sensible; there are tremendously few times that I am confused or surprised by how it works, which is legitimately novel (and wonderous) after the hours and days and weeks I’ve spent pulling my hair out dealing with random React and Webpack arcana.

Still, there are some bugaboos that I think arise from Vue’s current niche as a “lightweight” approach to creating a functional SPA, in much the same way that Flask carved out a niche as being a lightweight alternative to Django.

Read more →
© 2017 Justin Duke • All rights reserved • I hope you have a nice day.