Skip to content

Instantly share code, notes, and snippets.

@nitaku
Last active February 1, 2017 16:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nitaku/08ea8fb868ce5bd7661f90fca1881faf to your computer and use it in GitHub Desktop.
Save nitaku/08ea8fb868ce5bd7661f90fca1881faf to your computer and use it in GitHub Desktop.
Vue.js custom render

A Vue.js custom render function is used to display a customizable box containing text or list sections.

list_component =
props:
value:
type: Array
required: true
template: '''
<div>
<ol>
<li v-for="item in value" :class="{emph: item.emph}">{{item.text}}</li>
</ol>
</div>
'''
text_component =
props:
value:
type: String
required: true
template: '''
<div>{{value}}</div>
'''
sections_component =
props:
value:
type: Array
required: true
render: (createElement) ->
children = @value.map (d) ->
createElement("#{d.type}-section", {
props:
value: d.value
})
return createElement('div', {class: 'sections'}, children)
components:
'text-section': text_component
'list-section': list_component
app = new Vue
el: '#app'
data:
sections1: [
{type: 'text', value: 'This is a text section'},
{type: 'list', value: [
{text: 'important', emph: true},
{text: 'not important', emph: false},
{text: 'important', emph: true}
]},
{type: 'text', value: 'Footer'}
],
sections2: [
{type: 'text', value: 'A'},
{type: 'text', value: 'B'},
{type: 'text', value: 'C'},
{type: 'list', value: [
{text: 'one!', emph: true},
{text: 'two', emph: false}
]}
]
components:
'sections': sections_component
body, html {
padding: 0;
margin: 0;
height: 100%;
}
.emph {
font-weight: bold;
}
.sections > * {
padding: 6px;
}
.sections > *:not(:last-child) {
border-bottom: 1px solid #CCC;
}
.sections {
width: 300px;
border: 1px solid #CCC;
margin: 12px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue.js custom render</title>
<link type="text/css" href="index.css" rel="stylesheet"/>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<sections :value="sections1"/>
<sections :value="sections2"/>
</div>
<script src="index.js"></script>
</body>
</html>
// Generated by CoffeeScript 1.10.0
(function() {
var app, list_component, sections_component, text_component;
list_component = {
props: {
value: {
type: Array,
required: true
}
},
template: '<div>\n <ol>\n <li v-for="item in value" :class="{emph: item.emph}">{{item.text}}</li>\n </ol>\n</div>'
};
text_component = {
props: {
value: {
type: String,
required: true
}
},
template: '<div>{{value}}</div>'
};
sections_component = {
props: {
value: {
type: Array,
required: true
}
},
render: function(createElement) {
var children;
children = this.value.map(function(d) {
return createElement(d.type + "-section", {
props: {
value: d.value
}
});
});
return createElement('div', {
"class": 'sections'
}, children);
},
components: {
'text-section': text_component,
'list-section': list_component
}
};
app = new Vue({
el: '#app',
data: {
sections1: [
{
type: 'text',
value: 'This is a text section'
}, {
type: 'list',
value: [
{
text: 'important',
emph: true
}, {
text: 'not important',
emph: false
}, {
text: 'important',
emph: true
}
]
}, {
type: 'text',
value: 'Footer'
}
],
sections2: [
{
type: 'text',
value: 'A'
}, {
type: 'text',
value: 'B'
}, {
type: 'text',
value: 'C'
}, {
type: 'list',
value: [
{
text: 'one!',
emph: true
}, {
text: 'two',
emph: false
}
]
}
]
},
components: {
'sections': sections_component
}
});
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment