Phoenix, Brunch and VueJS: Part 2

Phoenix + Vue + Brunch

Phoenix, Brunch and VueJS - Part 2: single file vue components

As soon as the application starts becoming huge, with multiple components, pages and views, the development productivity will decrease.

To help with application complexibility, huge projects and big applications, VueJS has a feature called Single File Components.

Single File Components is the way that VueJS uses to organize, re-use and manage components.

Let’s learn how to setup and use them.

Benefits of Single File Components

VueJS - Single File Component

The benefits of Single File Components are many, we will keep a component style, logic and template together in the same files, making easier to redistribute components and organize our code. Of course, general style rules should have it’ s own file, like a global my-application.css.

VueJS Single File Components are very powerful and flexible, supporting several styling languages like CSS, SCSS, Sass, Less. Their templates can be written using HTML, Jade or even JSX. VueJS doesn’t enforce anything to us, it gives us the power of choose. For custom templates/style engines, we must install their Brunch dependency (normally a NPM package).

For our experiment, we will use simple HTML and CSS in our Single File Components.

Compiling Single File Components

In order to compile Single File Components, we must teach Brunch how to process this new kind of .vue files. Basically, we must install the compiler dependencies: vue-brunch, vueify and babel-plugin-transform-runtime:

phoenix_vue/ $ cd assets
../assets/   $ npm install --save-dev babel-plugin-transform-runtime vue-brunch vueify

We save it as a dev dependency, the final application doesn’t need any compilation logic, this way we save some size. Now, Brunch will know how to treat .vue automatically. Brunch is amazing, isn’t it?

Update: vue2-brunch was deprecated, please use vue-brunch instead!


Let’s create our first Vue Component, open a new file assets/js/vue/hello.vue:

    <input type="text" v-model="name" placeholder="Your name"></input>
    <a href="#" @click.prevent="doSay">Say my name</a>

<style scoped>
  a {
    color: #AA9080;
    background-color: #2020AA;

  export default {
    data () {
      return {
        name: ''
    methods: {
      doSay() {
        var name =;

It is important to note that the vue files must reside in assets/js, I created a new directory vue/ just to separate common Javascript files from our Vue components.

After creating our first Single File Component, let’s expose it in our assets/js/app.js, append these lines:

import 'vueify/lib/insert-css'
import Hello from './vue/hello.vue'

new Vue({ 
  el: '#main',
  components: { Hello }

The code is pretty self explained, we are importing our component from ./vue/hello.vue and then we expose our component to a new Vue instance. Let’s add #main and instantiate our Hello component.

We also need to import vueify/lib/insert-css, allowing Vue to insert css into the DOM.

Open lib/{project}/web/templates/page/index.html.eex and append:

<div id="main">

Update: it is necessary to import vueify/lib/insert-css to enable the inline CSS rules.


Here is the resulting component displayed in our browser:

Phoenix - Our First Single File Component

GitHub Repository

This guide source code was posted at:

Each commit represents one step.

Next step: Vue Router - routing client-side pages

Now we know how to use Single File Components, we could take more advantage of it if we could automatically route our client-side pages into Vue components. This can be done with Vue-Router.

Part 3: Phoenix, Brunch and VueJS: routing with Vue-Router


comments powered by Disqus