A Simple way of using Server Side rendered Vue.js 2.0+ natively in Express using streams
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.renderVue('view', {data}, [{vueOptions}])
.
$ npm install --save express-vue
Requires Node V6 or greater, and Vue 2.0 or greater. (Latest Vue.js is included in this project)
If using ES module statments like
export default {}
//or
import foo from "foo";
Or any other ES features you will need to also install babel-core
and babel-preset-env
.
npm i -D babel-core babel-preset-env
Then place a .babelrc
file in your root. here's an example targeting last two versions
{
"presets": [
["env", {
"targets": {
"browsers": ["last 2 versions"]
}
}]
]
}
An example / starter can be found here
This is the minimum required setup.If you don't provide a vueVersion
it will use the latest one when the project was published.If there is no rootPath
it will assume the root is the parent directory of node_modules
.
var expressVue = require("express-vue");
var app = express();
//pass your app through express-vue here
//expressVueOptions is optional and explained later in the docs
//this is a promise, so you can either await it or do this.
expressVue.use(app, expressVueOptions).then(() => {
//the rest of your express routes.
});
In your route, assuming you have a main.vue
router.get('/', (req, res, next) => {
const data: {
otherData: 'Something Else'
};
req.vueOptions: {
head: {
title: 'Page Title',
metas: [
{ property:'og:title', content: 'Page Title'},
{ name:'twitter:title', content: 'Page Title'},
]
}
}
res.renderVue('main.vue', data, req.vueOptions);
})
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.renderwill overwrite it.
key | type | description | required? | default value |
---|---|---|---|---|
rootPath | string | this is the path the library will use as the base for all lookups | optional | the directory that your ../node_modules lives in |
vueVersion | string or object | this is where you specify which version of vue.js's library to use from the CDN | optional | the latest version as of publishing this |
layout | Object | this is the object for customzing the html, body, and template tags | optional | has default value which is in the example below |
vue | Object | this is the global config for vue for example you can set a global title, or a script tag in your head block everything here is global | optional | no default value |
data | Object | this is the global data object, this will be merged in to your .vue file's data block on every route, you can override this per route. | optional | no default value |
Here's an example, with the default layout config included for you to see...
const vueOptions = {
rootPath: path.join(__dirname, '../example/views'),
head: {
title: 'Hello this is a global title',
scripts: [
{ src: 'https://example.com/script.js' },
],
styles: [
{ style: '/assets/rendered/style.css' }
]
},
data: {
foo: true,
bar: 'yes',
qux: {
id: 123,
baz: 'anything you wish, you can have any kind of object in the data object, it will be global and on every route'
}
}
};
expressVue.use(app, vueOptions);
When including components/mixins/etc the directory it looks is going to be relative to the file you're working in currently.assuming the below is running in a folder with a subdirectory components
and a directory mixins
in a parent, it would look like this.when importing .vue files and .js files from node modules you can just import them the normal way you import a module.
<script>
import messageComp from './components/message-comp.vue';
import users from './components/users.vue';
import exampleMixin from '../mixins/exampleMixin';
import externalComponent from 'foo/bar/external.vue';
export default {
mixins: [exampleMixin],
data: function () {
return {
}
},
components: {
messageComp,
users,
externalComponent
}
}
</script>
Please use regular CSS for now, SCSS/LESS/etc are compiled languages, and this is a runtime library for now.In the future I will be creating build tools to handle compiling the .vue files into .js files so that it runs faster,and more efficient at runtime. But for dev mode, it will compile everything at runtime, so you can edit and preview faster.
<style>
.test {
border: 2px;
}
.test a {
color: #FFF;
}
</style>
You can now use Mixins, lets say you have an file called exampleMixin.js
and it looks like this:
examplemixin.js
module.exports {
methods: {
hello: function () {
console.log('Hello');
}
}
}
In your route you would declare it by placing mixins: [exampleMixin]
in your vue object.
<script>
import exampleMixin from '../mixins/exampleMixin';
export default {
mixins: [exampleMixin],
data: function () {
return {
}
}
}
</script>
You can now use this in your .Vue file, like so
<button @click="hello()">Click me and look at console logs</button>
This library takes the wonderful inspiration from vue-head and adapts it towork 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).
const vueOptions = {
head: {
title: 'It will be a pleasure',
// Meta tags
metas: [
{ 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' },
// ...
// Rel
{ rel: 'icon', type: 'image/png', href: '/assets/favicons/favicon-32x32.png', sizes: '32x32' }
// Generic rel for things like icons and stuff
],
// Scripts
scripts:[
{ src: '/assets/scripts/hammer.min.js' },
{ src: '/assets/scripts/vue-touch.min.js', charset: 'utf-8' },
// Note with Scripts [charset] is optional defaults to utf-8
// ...
],
// Styles
styles: [
{ style: '/assets/rendered/style.css' }
{ style: '/assets/rendered/style.css', type: 'text/css' }
// Note with Styles, [type] is optional...
// ...
],
}
}
expressVue.use(app, vueOptions);
This also supports Google Structured datahttps://developers.google.com/search/docs/guides/intro-structured-data
const vueOptions = {
head: {
title: 'It will be a pleasure',
structuredData: {
"@context": "http://schema.org",
"@type": "Organization",
"url": "http://www.your-company-site.com",
"contactPoint": [{
"@type": "ContactPoint",
"telephone": "+1-401-555-1212",
"contactType": "customer service"
}]
}
}
}
If you want to have a custom layout you can, here is the default layout, each part is overridable.
const vueOptions = {
//...
template: {
html: {
start: '<!DOCTYPE html><html>',
end: '</html>'
},
body: {
start: '<body>',
end: '</body>'
}
template: {
start: '<div id="app">',
end: '</div>'
}
}
//...
};
expressVue.use(app, vueOptions);
To use the amazing Vue.js DevTools please set the environment variable VUE_DEV=true
this will also trigger the development version of vue to be included in the head.
Caching is now enabled by default, in dev mode hopefuly you're using something like nodemon/gulp/grunt etc, which restarts the server on file change.. otherwise you will need to stop and restart the server if you change your files.. which is normal.
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');
This is middleware now so support for sails should just work as middleware.
rootPath
to pagesPath
vueVersion
webpack
vue-loader
and css-loader
.babelrc
if you have one@babel
versions @babel/core @babel/preset-env @babel/preset-es2015
expressvue.config.js
expressVue.use(expressApp);
this is a async function, so please either await it or use it in a promise.vue-pronto
which uses Vueify
req.vueOptions
as a global.vueOptions.head
instead of vueOptions.vue.head
res.renderVue
the filename requires an extention now.Express-vue-renderer got too heavy, the architecture became too messy, and it was slow. It needed to get thrown out. Enter vue-pronto it uses vueify under the hood, and is much more modular. this will be much easier going forward to maintain.
There's been some big changes to this object, so before it would look like this
const vueOptions = {
vue: {
head: {
meta: [
{ script: 'https://unpkg.com/vue@2.4.2/dist/vue.js'},
{ name: 'application-name', content: 'Name of my application' },
{ name: 'description', content: 'A description of the page', id: 'desc' },
{ style: '/assets/style.css' }
]
}
}
};
VUE_DEV
.const vueOptions = {
vueOptions: "2.4.2",
head: {
metas: [
{ name: 'application-name', content: 'Name of my application' },
{ name: 'description', content: 'A description of the page', id: 'desc' },
],
styles: [
{ style: '/assets/style.css' }
]
}
};
Routes before were relative to the rootPath
... now that is gone... routes for requires are relative to the file you are currently in.Also node_module
paths are working for both .js and .vue includes
res.renderVue
Changes
res.renderVue
now requires an extension for the file you're using in the route. foo/bar
now foo/bar.vue
Global req.vueOptions
. this is super handy for passing options around between middleware.
vue-pronto
which uses Vueifyres.renderVue
the filename requires an extention now.Apache-2.0 © Daniel Cherubini
express 也是一个框架库和js是一样的,它是node.js官方库,即可理解为类似java的jdk里的库 Hello world 示例 var express = require('express'); var app = express(); app.get('/', function (req, res) { res.send('Hello World!'); }); app.listen
1 问题来源 在使用sqlite3的时候,需要创建数据库表时,这时候很容易出现这个问题!!!提示:SQLITE_CANTOPEN unable to open database file nodejs中内置了变量__dirname,electron-vue中内置了变量__static。在开发阶段的过程中,使用这两个变量来创建文件是没有问题。 例如当我使用path.join(__static,‘pa
快递概述 Express是一个最小且灵活的Node.js Web应用程序框架,它提供了一组强大的功能来开发Web和移动应用程序。 它有助于基于节点的Web应用程序的快速开发。 以下是Express框架的一些核心功能 - 允许设置中间件以响应HTTP请求。 定义路由表,该表用于基于HTTP方法和URL执行不同的操作。 允许基于将参数传递给模板来动态呈现HTML页面。 安装Express 首先,使用N
art-template for express. Install npm install --save art-template npm install --save express-art-template Example var express = require('express'); var app = express(); app.engine('art', require('exp
Serverless Express ⎯⎯⎯ This Serverless Framework Component enables you to take existing Express.js apps and deploy them onto cheap, auto-scaling, serverless infrastructure on AWS (specifically AWS HTT
前后端分离示例 一个前后端分离的案例,前端 vuejs,后端 express, 数据库 mongodb。使用 express 的提供api供前端调用,前端ajax请求进行对数据库的CURD操作。 前言 在学习前端开发的过程中了解到前后端分离这个概念前后分离架构的探索之路我们为什么要尝试前后端分离因此决定小试身手,项目中主要使用到的框架和库. vuejs vue-router muse-ui axi
囊括了perl程序员必需的编写和调试的所有工具,无论是对新手还是对老手都很合适
Simple and fast HTTP-Framework with the touch of expressjs State of this project I created this years ago and I'm no longer actively working with java. If anyone is interested maintaining this (and ha