express-vue
A Simple way of using Server Side rendered Vue.js 2.0+ natively in Express using
res.render()('view', {data}).
Installation
$ npm install --save express-vue
Requirements
Requires Node V6 or greater, and Vue 2.0 or greater. (Latest Vue.js is included in this project)
Examples
A Super Simple example can be found at express-vue/express-vue-super-simple
A full example can be found at: express-vue/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 separate 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 extension. //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: { head: { title: 'Page Title', head: [ { property:'og:title', content: 'Page Title'}, { name:'twitter:title', content: 'Page Title'}, ] } } }); }).
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: { head: { 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.
CSS inside components/views.
<style lang="css"> .test { border: 2px; } .test a { color: #FFF; } </style>
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: { head: { title: 'Page Title', }, components: ['myheader', 'myfooter'], mixins: [exampleMixin] } }); })
You can now use this in your .Vue file, like so
<button @Click me and look at console logs</button>
Meta).
head: { title: 'It will be a pleasure', // Meta tags meta: [ { 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... // ... ], }
Structured Data
This also supports Google Structured data
head: { title: 'It will be a pleasure', structuredData: { "@context": "", "@type": "Organization", "url": "", "contactPoint": [{ "@type": "ContactPoint", "telephone": "+1-401-555-1212", "contactType": "customer service" }] } }
DevTools
To use the amazing Vue.js DevTools please set the environment variable
VUE_DEV=true
Caching
This has caching, and its highly recomended, if you want to enable caching please use the environment variable
VUE_CACHE_ENABLED=true
To disable caching on keys in your data object use this
app.set('vue', { componentsDir: path.join(__dirname, '/views/components'), defaultLayout: 'layout', cache: { ignoredKeys: ['csrf', 'foo', 'bar'] } });
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 lang="css"> </style>
Typescript support
Typescript declarations are published on NPM, so you don’t need external tools like Typings, as declarations are automatically imported with express-vue. That means all you need is a simple:
import expressVue = require('express-vue');
Sailsjs Support
Thanks to @duffpod for this help.
Generate a Sails project with sails new your-app --no-frontend Install express-vue with npm install express-vue --save Go to the view config of Sails app at your-app/config/views.js and replace the engine: 'ejs', with this:
engine: { ext: 'vue', fn: (function() { return require('express-vue'); })() },
Also need to set the layout: 'layout', to layout: false, as it will be ignored by Sails anyway.
Now we need to create views folder in the Sails app. mkdir your-app/views/ && touch your-app/views/homepage.vue. Note, that your-app/config/routes.js is already pointing the homepage-file to the localhost:1337/. Edit the homepage.vue to add your Vue.js content to it, like:
<template> <div> <h1>Hello, world!</h1> </div> </template> <script> export default { data() { return {} } }; </script>
After all, go to the config/http.js in your project. There will be the middleware object. You need to add the customMiddleware function AFTER it, so everything looks like this:
module.exports.http = { middleware: { }, customMiddleware: function(app) { app.set('vue', { // configure express-vue here // do not use __dirname here, otherwise the path will look like: // /Users/username/your-project/config/components // componentsDir: app.settings.views + '/components', }); } };
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