Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 2 #2

Merged
merged 7 commits into from
Oct 26, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
test/*.js
dist/*.js
test/*
dist/*
3 changes: 3 additions & 0 deletions .flowconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[ignore]
.*/node_modules/vue/src/*.
.*/dist/*.
76 changes: 46 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ var expressVue = require('express-vue');

var app = express();
app.set('vue', {
rootPath: __dirname + '/',
layoutsDir: 'app/components/',
componentsDir: 'components/',
defaultLayout: 'layout'
});
app.engine('vue', expressVue);
Expand All @@ -28,32 +30,62 @@ In your route, assuming you have a main.vue
router.get('/', (req, res, next) => {
res.render('main', {
title: 'Page Title',
otherData: 'Something Else'
data {
otherData: 'Something Else'
}
});
})
```

To use Data binding into the vue files you need to use this syntax `'$parent'.attribute`
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!

So If you had {{title}} it would be `'$parent'.title`
## Components

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

```js
data () {
return {
title: '$parent'.title
}
},
router.get('/', (req, res, next) => {
res.render('main', {
title: 'Page Title',
data {
otherData: 'Something Else'
}
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

```vue
<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.

## Example

A full example can be found at: [danmademe/express-vue-example](https://github.com/danmademe/express-vue-example)

## Requirements

It requires you to have a file called layout.vue file similar to this in the `app/components/` directory

It's required to set the `{{{body}}}` and `{{{script}}}` tags where you want the layout body and script to go.
It's required to set the `{{{app}}}` and `{{{script}}}` tags where you want the layout body and script to go.
`{{{title}}}` is set in your res.render using the data attribute `{title: 'A Vue Example'}`, look to the example above for more info

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

Expand All @@ -64,34 +96,18 @@ Finally you'll need to set the link to your copy of vue.js in the script... (thi
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>{{title}}</title>
<script src="assets/vue.js" charset="utf-8"></script>
<title>{{{title}}}</title>
<script src="assets/scripts/vue.js" charset="utf-8"></script>
</head>
<body>
<div class="content">
<div class="content-inner">
{{{body}}}
</div>
</div>
{{{app}}}
{{{script}}}
<script>app.$mount('#app')</script>
</body>
</html>
</template>

<script>
export default {
el: 'head',
data () {
return {
title: '$parent'.title
}
},
computed: {},
ready () {},
attached () {},
methods: {},
components: {}
}
</script>

<style>
Expand Down
30 changes: 30 additions & 0 deletions dist/defaults.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Types = function Types() {
_classCallCheck(this, Types);

this.COMPONENT = 'COMPONENT';
this.SUBCOMPONENT = 'SUBCOMPONENT';
this.LAYOUT = 'LAYOUT';
};

var Defaults = function Defaults() {
var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

_classCallCheck(this, Defaults);

this.rootPath = obj.rootPath || __dirname + '/../';
this.layoutsDir = obj.rootPath + obj.layoutsDir || '/app/routes/';
this.componentsDir = obj.rootPath + obj.componentsDir || '/app/components/';
this.defaultLayout = obj.defaultLayout || 'layout';
this.options = obj.options || undefined;
};

exports.Types = Types;
exports.Defaults = Defaults;
89 changes: 22 additions & 67 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,84 +3,39 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
var fs = require('fs');
var bodyRegx = /(<template>)([\s\S]*?)(<\/template>)/gm;
var scriptRegex = /(export default {)([\s\S]*?)(^};?$)/gm;
var dataRegex = /(\'\$parent\').(\w*)/gm;
var layoutRegex = /{{{body}}}/igm;
var defaults = {
layoutsDir: '/app/components/',
defaultLayout: 'layout',
options: undefined
};

function expressVue(filePath, options, callback) {
var _defaults = require('./defaults');

defaults = options.settings.vue;
defaults.layoutPath = defaults.layoutsDir + defaults.defaultLayout + '.vue';
defaults.options = options;
var _parser = require('./parser');

Promise.all([layoutParser(defaults.layoutPath), templateParser(filePath)]).then(function (data) {
var layout = data[0];
var template = data[1];
var html = layout.replace(layoutRegex, template);
var _utils = require('./utils');

callback(null, html);
}, function (error) {
callback(new Error(error));
});
}
function expressVue(componentPath, options, callback) {

function bodyParser(body) {
var bodyString = body.match(bodyRegx)[0];
if (bodyString) {
bodyString = bodyString.replace(bodyRegx, '$2');
}
return bodyString;
}
var defaults = new _defaults.Defaults(options.settings.vue);
var types = new _defaults.Types();
defaults.layoutPath = defaults.layoutsDir + defaults.defaultLayout + '.vue';
defaults.options = options;

function scriptParser(script) {
var scriptString = script.match(scriptRegex)[0];
if (scriptString) {
scriptString = scriptString.replace(scriptRegex, '({$2})').replace(dataRegex, function (match, p1, p2) {
return JSON.stringify(defaults.options[p2]);
});
}
return scriptString;
}
var componentArray = [(0, _parser.layoutParser)(defaults.layoutPath, defaults, types.LAYOUT), (0, _parser.componentParser)(componentPath, defaults, types.COMPONENT)];

function layoutParser(layoutPath) {
return new Promise(function (resolve, reject) {
fs.readFile(layoutPath, function (err, content) {
if (err) {
reject(new Error(err));
if (defaults.options.components) {
for (var component in defaults.options.components) {
if (defaults.options.components.hasOwnProperty(component)) {
var componentFile = defaults.componentsDir + defaults.options.components[component] + '.vue';
componentArray.push((0, _parser.componentParser)(componentFile, defaults, types.SUBCOMPONENT));
}
var contentString = content.toString();
var body = bodyParser(contentString);
var script = scriptParser(contentString);

var layout = body.replace('{{{script}}}', '<script>new Vue(' + script + ')</script>');
}
}

resolve(layout);
});
Promise.all(componentArray).then(function (components) {
var html = (0, _utils.renderHtmlUtil)(components, defaults);
callback(null, html);
}, function (error) {
callback(new Error(error));
});
}

function templateParser(template) {
return new Promise(function (resolve, reject) {
fs.readFile(template, function (err, content) {
if (err) {
reject(new Error(err));
}
var contentString = content.toString();
var body = bodyParser(contentString);
var script = scriptParser(contentString);

var template = body + '<script>new Vue(' + script + ')</script>';

resolve(template);
});
});
}
expressVue.componentParser = _parser.componentParser;

exports.default = expressVue;
Loading