Vue rendering engine for Express.js. Use .Vue files as templates using res.render()
JavaScript Vue
Latest commit 1ea263c Jan 20, 2017 @danmademe 3.5.1

README.md

Version Build Status Dependency Status Coverage Status

express-vue

A Simple way of using Server Side rendered Vue.js natively in Express using res.render()

If you want to use vue.js and setup a large scale web application that is server side rendered, using Node+Express, but you want to use all the fantastic tools given to you by Vue.js. Then this is the library for you.

The idea is simple use Node+Express for your Controller and Models, and Vue.js for your Views.. you can have a secure server side rendered website without all the hassle. Your Controller will pass in the data to your View through res.render('view', {data}).

Installation

$ npm install --save express-vue

Examples

A Super Simple example can be found at danmademe/express-vue-super-simple

A full example can be found at: danmademe/express-vue-example

Usage

var expressVue = require('express-vue');

var app = express();
app.set('views', __dirname + '/app/views');
//Optional if you want to specify the components directory seperate to your views, and/or specify a custom layout.
app.set('vue', {
    //ComponentsDir is optional if you are storing your components in a different directory than your views
    componentsDir: __dirname + '/components',
    //Default layout is optional it's a file and relative to the views path, it does not require a .vue extention.
    //If you want a custom layout set this to the location of your layout.vue file.
    defaultLayout: 'layout'
});
app.engine('vue', expressVue);
app.set('view engine', 'vue');

In your route, assuming you have a main.vue

router.get('/', (req, res, next) => {
    res.render('main', {
        data: {
            otherData: 'Something Else'
        },
        vue: {
            meta: {
                title: 'Page Title',
                head: [
                    { property:'og:title' content: 'Page Title'},
                    { name:'twitter:title' content: 'Page Title'},
                ]
            }    
        }
    });
})

To use Data binding into the vue files you need to pass data in through the data object as above. express-vue will automatically add anything you put here to the root element of your Vue components. You do not need to have anything in data in your .vue file, but if you did what you put in res.render will overwrite it.

Remember to always write your data objects in your .vue files as functions!

Components

To add components to your .vue files you can either write them in manually.. or pass them in through res.render

router.get('/', (req, res, next) => {
    res.render('main', {
        data : {
            otherData: 'Something Else'
        },
        vue: {
            meta: {
                title: 'Page Title',
            },
            components: ['myheader', 'myfooter']
        }

    });
})

This will trigger the library to look in the componentsDir folder for any component matching, it MUST be an array

Then in your .vue file you can just use the element directive and it will work out of the box

<template>
    <div>
        <myheader></myheader>
        <h1>{{otherData}}</h1>
        <myfooter></myfooter>
    </div>
</template>

Note: This isn't available in the layout.vue file yet, only the .vue files you specify in your express route.

mixins

You can now use Mixins, lets say you have an file called exampleMixin.js and it looks like this:

examplemixin.js

export default {
    methods: {
        hello: function () {
            console.log('Hello')
        }
    }
}

In your route you would declare it by placing mixins: [exampleMixin] in your vue object.

import exampleMixin from '.exampleMixin';
router.get('/', (req, res, next) => {
    res.render('main', {
        data : {
            otherData: 'Something Else'
        },
        vue: {
            meta: {
                title: 'Page Title',
            },
            components: ['myheader', 'myfooter'],
            mixins: [exampleMixin]
        }

    });
})

You can now use this in your .Vue file, like so

<button @click="hello()">Click me and look at console logs</button>

Meta

This library takes the wonderful inspiration from vue-head and adapts it to work here. Just add a meta array into your head object, with support for both content and property types. (Note we don't support shorthand here, and no support for google+ just yet, that will come soon).

meta: {
    title: 'It will be a pleasure',
    // Meta tags
    head: [
        { name: 'application-name', content: 'Name of my application' },
        { name: 'description', content: 'A description of the page', id: 'desc' } // id to replace intead of create element
        // ...
        // Twitter
        { name: 'twitter:title', content: 'Content Title' },
        // ...
        // Facebook / Open Graph
        { property: 'fb:app_id', content: '123456789' },
        { property: 'og:title', content: 'Content Title' },
        // ...
        // Scripts
        { script: '/assets/scripts/hammer.min.js' },
        { script: '/assets/scripts/vue-touch.min.js', charset: 'utf-8' },
        // Note with Scripts [charset] is optional defaults to utf-8
        // ...
        // Styles
        { style: '/assets/rendered/style.css' }
        { style: '/assets/rendered/style.css', type: 'text/css' }
        { style: '/assets/rendered/style.css', type: 'text/css', rel: 'stylesheet' }
        // Note with Styles, [type] and [rel] are optional...
        // ...
    ],
}

DevTools

To use the amazing Vue.js DevTools please set the environment variable VUE_DEV=true

Requirements

Requires Node V4 or greater

Optional

If you want to have a custom layout you can, here is an example layout.vue file which you can place relative to your views path.

It's required to set the {{{app}}} and {{{script}}} tags where you want the layout body and script to go. If you want to set a title or other meta data, you can add them to the vue metadata object, you can look at the above examples for how to do that.

Finally you'll need to set the link to your copy of vue.js in the script... (this will become automatic soon)

<template>
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
            <script src="assets/scripts/vue.js" charset="utf-8"></script>
        </head>
        <body>
            {{{app}}}
            {{{script}}}
        </body>
    </html>
</template>

<script>
</script>

<style>
</style>

Todo

  • Have the style sections do something!

Changelog

v3 has seriously changed the object you pass into the vue file.. so please if migrating from an earlier version (and you should). Take the time to look at the new object.

Sorry for the breaking change, but I'm only one person.

License

Apache-2.0 © Daniel Cherubini