One more example of abstract component in Vue.js

Michael Lelyakin
Feb 25, 2019 · 3 min read
Image for post
Image for post

Hi, there! I’m a front-end developer and hope that you are a programmer too. How often do you need to implement abstractions in your JavaScript code? Never? Oh, let’s change it!

Do you know something about Intersection Observers API? If yes, great! You can google “Writing Abstract Components in Vue.js” and get a lot of copy-pasted articles about writing lazy-rendered components to achieve performance of rendering page into the DOM. I will not discuss this example here, let’s look at my own example.

Me and my team implement new features too often, some of them is going to production after 2–3 days. To avoid scaring users with amazing features and new bugs we hide it by permissions and show only for administrators. When Admin thinks that this is good time to show it to users — he changes config in permissions panel and opens the rest of functionality.

Ok, let’s writing code.

Let me to introduce you in simple function:

How we can use this function as computed method in Vue templates?

Main idea of that: If user has read-only permission, he can see the field, but it will be disabled. If user has no permission for that, he will see nothing instead of the field. What are the problems in this piece of template?

First one, it’s too difficult to read. We call function userHasPermission two times for each field. Copy-Paste to the fore!

Second one: imagine situation when you need to add additional rules to disable the field. For example, if the team has no any further training, “Next Training Time” field needs to be disabled without looking for any permission. Without solution which I suggest you in this article, perhaps it looks like that:

This code has confusion of responsibility! Ah.. how to solve our problem?

While we associate one concrete permission with one or more fields, we need to have an ability to bind permission and field in one line of code. Imagine that we have an abstract component (like transition or keep-alive ) with name permission-control which can be responsible for permissions-only behavior. It needs to take permission in props and manipulate with their children. Look at the example of usage:

And refactored example with additional rules for the last field:

Both examples look very clearly. New team-member of our project can easily understand business logic of this form. What is the implementation of this useful (I hope) permission-control? Idea based on power of render functions in Vue.js framework and slots functionality. Look at prototype:

Are there any limitations of this piece of code?

You need to wrap only one control by this component, all controls have to support disabled props name and control needs to exists. If you have additional rules to hide control with v-if attribute, you will get the error Can not read property 0 of undefined. Anyway you can avoid this bug, if you put checks of child existing at the top of the render function:

if (!this.$slots.default) {
return null;
}

Abstract.. Vue abstract component… I remember something else knowledge's from other articles about components for intersection observer API...

Yes, you are right! Vue has not-documented keyword abstract: true for abstracted components. But I really don’t know how it changes describes behavior. I see no additional comments in other articles. If I don’t know reason for using this word, I won’t ask you to use it. It’s good thesis to research it in a separate article.

Thanks for reading, mates!

Vue.js Developers

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store