One more example of abstract component in Vue.js

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!