Skip to content

Instantly share code, notes, and snippets.

@christiannwamba
Created November 24, 2017 11:27
Show Gist options
  • Save christiannwamba/fac3bb51023d019011a01aa835d431e4 to your computer and use it in GitHub Desktop.
Save christiannwamba/fac3bb51023d019011a01aa835d431e4 to your computer and use it in GitHub Desktop.

The announcement of Vue v2.5 came with much buzz to the Vue community and many improvements to Vue. One of these is the improved support for functional components in Vue. In this article, we will be cleaning up Vue components without state and instances (this) with functional components.

What are Functional Components?

Functional components are an alternative to the widely used Vue components. They use either render functions or are JSX components without state and instance. This means they have no data property or an instance of this. Functional components are functions.

Functional components are cleaner and easier to render. This is how a simple functional component looks:

https://gist.github.com/00d85ffb8851ec401952be8cd59e92e7

Note: Props in functional components may not be specified, in which case all props are received from the component’s node.

When using functional components, the context argument is introduced to make-up for the lost state and instance.

One may wonder why we have children as well as slot. This is because context.children refers to all child elements of the node whereas slots().foo refers to all slots with the name foo, and slots().default refers to all child element except named slots. These give us the flexibility to choose ways to target child elements. Let’s look at a simple conversion from a stateful component to a stateless on using functional component.

Conversion from Stateful to Stateless

Let’s create a simple generic header, which can be used throughout a Vue instance. Headers are from h1 through to h6. From a stateful component perspective:

https://gist.github.com/7a6399bdbd82dd23a0126f0c36f5f34e

See a codepen demo here https://codepen.io/Chuloo/pen/aLexEe

In our stateful header, the createElement() function is used to create the header passing it arguments of the level props and the $slots.default instance for any child node. Since we have no data from this component, let’s make this cleaner by making it a functional component, thereby eliminating all instances of this and introducing the context argument to handle props.

https://gist.github.com/feefc104ad8c7c6fa2818b62c2da5f51

See a codepen demo here https://codepen.io/Chuloo/pen/boXZxw

Notice how this.level is replaced with context.props.level and this.$slots.default is replaced with context.children.

Single-File Functional Components

From Vue v2.5, functional components defined by single-file components can have the functional attribute in the template tags. This denotes the component as a functional one, eliminates the need to specify the functional property in <script> and the component is treated outright as a functional component.

Also, functional components have CSS in scope as well as hot-reloading features. I built a simple Vue project using the webpack-simple template to show a sample functional component.

It is assumed that you have node and npm installed.

Vue ships with a wonderful CLI for building applications fast, using npm install Vue with:

https://gist.github.com/4502fad144f76e8f266ddac141c6119b

A new project with the webpack-simple template is created using:

https://gist.github.com/f93d32bc47368968ae3853a50d693270

A simple Vue project is created and the command:

https://gist.github.com/6e89463140e8b0b072570de6a084bbf9

serves the Vue project on a development server on Localhost:8080.

In the project folder, we create a file named Header.vue in /src/components/ and edit it to:

https://gist.github.com/9f4c6dcc889ed04792cb7214328faa7b

This is our functional component. Note the absence of the props object? This is because the props object is passed explicitly from the components node. In App.vue located in /src/ wipe all the data provided by our template and edit it to:

https://gist.github.com/c3349ae8abdc999756f34bbce4a61ecd

This is our parent Vue template, the app is built here.

Now run:

https://gist.github.com/87f024b0cbee50c83861dd5e19f899f6

The browser displays:

The app can be styled anyway, either the component is styled and the scoped attribute is used on the style tags as seen above to ensure that the styling is scoped to solely the component in view.

Conclusion

Functional components are used because they are lighter and cheaper to render by the browser. Instead of using JSX or render functions, they are stateless and have no instance. With the release of v2.5 of Vue, functional components can now possess scoped styling as well as hot-reloading features as we have seen in the simple demo above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment