brue v2.0.7
Brue
Brue allows you to express Vue templating in 100% vanilla javascript resulting in more concise components. Brue componants are indistinguishable from Vue componants and can be used interchangably. Now re-written specifically for Vue 3.x.
Quick comparison
with Brue:
import Brue from 'brue';
import { reactive } from 'vue';
import CustomComponent from './CustomComponent.vue'
export default Brue('incomingProp', props => {
const state = reactive({
double: props.incomingProp * 2
})
const doClick = () => console.log('click');
return $ => { $
.a('div .example')
.b('h1').text('Twice as much')
.b(CustomComponent, { customProp: true })
.b('div .link').text(state.double)
.click(doClick)
}
});
with Vue:
<template>
<div class="example">
<h1>Twice as much</h1>
<custom-component :customProp="true" />
<div class="link" @click="doClick">
{{ state.double }}
</div>
</div>
</template>
<script>
import { reactive } from 'vue';
import CustomComponent from './CustomComponent.vue'
export default {
props: ['incomingProp'],
components: {
CustomComponent
},
setup(props){
const state = reactive({
double: props.incomingProp * 2
})
const doClick = () => console.log('click');
return {
state,
doClick
}
}
}
</script>
Creating components
Brue() accepts the component properties followed by the setup function. The property names can be spread across the arguments or as a single object or array - Brue expects the setup function to be the last argument. If a property is not specified it will be treated like an HTML attribute.
//Any of these work...
Brue('prop1','prop2', props => {
});
Brue(['prop1','prop2'], (props, context) => {
});
Brue(
{
prop1: String,
prop2: Number
},
(props, { slots, attrs, emit}) => {
// ...
}
);
Tree builder - $
The component function passed to Brue needs to return a render function. The first argument of the render function (the tree builder variable $
) is used to construct the virtual DOM node tree. Every $
function returns $
, allowing for continuous chaining. The chain can be suspended to perform loops or execute javascript and then reestablished with $
.
E.g.
$ => { $
.a('ul')
users.map(user => { $
.b('li').key(user.id)
.c('span').text(user.name)
});
}
Defining nodes
.a()
, .b()
, .c()
, etc. (through z) are used to establish a new node (html tag or component), and establish the child-parent relationship. c
nodes are children of b
nodes, etc.
Strings
Strings passed into nodes as arguments can define the element type, class, and/or id of the node:
- no prefix indicates the element type
- . prefix indicates a class
- # prefix indicates the id
$
.a('div')
.b('h1 .headerClass #homeHeader').text('Home')
//same as
.a('div')
.b('h1','#homeHeader', {class: 'headerClass'}).text('Home')
Objects
Objects passed into nodes as arguments will define properties and/or attributes. There's no need to use v-bind
- variables and values can be used directly. Note Since Vue components are objects: if the first argument is an object, Brue will assume you're defining the node type as a vue component.
$
.a('div')
.b(MyComponent, {someProp: true, title: 'Example attribute'})
Node modifiers
Node modifiers are $
functions that can further define characteristics of a node. Any non-alphabet $
function will always modify the last established node.
$
.a('div')
.style({fontSize: '14px'})
.on('click', doSomething)
Text
Text nodes can be defined a number of ways:
// all equivalent:
$.a('div').text('')
$.a('div')
.b().text('Hello')
$.a('div')
.b(String, 'Hello')
The .b(String, 'Hello')
format can make it a little easier to express inline tags (not a Brue strong point):
// <div>Inline <em>tags</em> are a bit verbose</div>
$
.a('div')
.b(String, 'Inline ')
.b('em').text('tags')
.b(String, ' are a bit verbose')
$ API
More to come.
.class({})
Assign classes to the node based on boolean values. The equivalent of v-bind:class
.
.a('div .mynode').class({
active: true,
deleted: false
})
// <div class="mynode active"></div>
.html(str)
Set the contents of the node to pre formatted html. Equivalent to innerHTML. Any inner children or text nodes will be igonored.
.key()
Within a loop specify a unique key to optimize rendering. Vue docs: Maintaining State
.on()
Add an event listener to the node. Accepts either a single listener or an object of listeners. In addition, event modifiers can be added as suffixes (event.mod
) or as optional arguments.
Some examples:
$.a('div')
.on('click', doClick)
//
$.a('div')
.on({
'focus': () => console.log('focus'),
'keydown.ctrl': onCtrlKey
})
//
$.a('div')
.on('contextmenu', rightClickFunc, 'prevent','stop')
Modifiers: | events | mouse | key values | key mods | |---|---|---|---| | stop prevent capture self once passive | leftrightmiddle | enter tab delete esc space up down left right | ctrlaltshiftmetaexact |
.ref()
Assign a reference to the element. Vue docs: Refs
.style({})
Assign styles to the node. The equivalent of v-bind:style
.
.a('.mynode').style({
color: 'red',
fontSize: '14px'
})
.text(str)
Sets the inner text of the node: .a('p').text('Hello')
creates <p>Hello</p>
. If the node has any other children, the text will be inserted after the children. Alternatively, use String
as the first argument of a node: .a('p').b(String, 'Hello')
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago