JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 3
  • Score
    100M100P100Q82110F
  • License MIT

A thin abstraction layer over the Vue.js renderer for unobtrusive use

Package Exports

  • @halleymedia/unobtrusive-vue

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@halleymedia/unobtrusive-vue) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Unobstrusive Vue

This package is a thin abstraction layer over the Vue.js v2.6 rendering engine, so it can be used in a completely unobtrusive way, i.e. it won't surface in the JavaScript or HTML code at all. You're now free to take whatever design decisions you want.

Getting started

This project is available as the npm package @halleymedia/unobtrusive-vue.

npm package

A simple demo application is availabe in he sample directory of this project.

Why unobtrusive

If you take a look at the Vue.js v2 documentation, you'll bump into code like this.

var app5 = new Vue({
  el: '#app-5',
  data: {
    message: 'Hello Vue.js!'
  },
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')
    }
  }
})

This way of doing things looks artificial and tightly coupled to Vue.js itself and the DOM. We believe the application logic should be freed from any framework convention. What if we could, instead, express data as simple properties and methods as... well, methods of an ES6 class? Image we could rewrite the previous code like this.

import { component } from '@halleymedia/unobtrusive-vue'
import template from './my-component.html' //use webpack for this, see sample

@component('my-component', template)
export default class MyComponent {
  message = 'Hello application!'

  reverseMessage() {
    this.message = this.message.split('').reverse().join('')
  }
}

Now there's no trace whatsover of any JavaScript framework being used. It's just simple, natural and readable JavaScript code we can easily unit test. Any developer who knows how to write basic ES6 code can now take part in the project without actually having to read the Vue.js manual beforehand.

This package lets the developer do just that. It takes the burden of mapping ES6 classes to Vue.js convetions.

  • Public properties are data. Use these for two-way binding with input elements;
  • Public getters are mapped to computed to Vue.js;
  • Public setters are mapped to component properties (or props as Vue.js calls them);
  • Public methods are... well, mapped to methods;
  • Private members are not mapped at all. Feel free to use them to store internal state of a component.

The View

Use moustache syntax everywhere:

<button type="button" title="{{message}}" onclick="{{reverseMessage()}}">{{message}}</button>

Again, there's no trace of a framework being used.

Use the special attributes render-if when you want to dynamically render an HTML element.

<div render-if="{{loading}}">loading</div>

And use the attribute render-for when you want to repeat an HTML element. The $index and $item variables will be automatically made available in this context.

<ul>
  <li render-for="{{results}}">
    <span>{{$index}}</span>. <span>{{$item}}</span></li>
  </li>
</ul>

That's all you need to know. This package aims at simplicity and it intentionally does without more advanced features of Vue.js. Developers can now spend more time on the project, instead of wasting time on a framework documentation.

Template transformation

Template transformation is done with by the @component decorator at the application startup but it's preferred to do it a compile time. Here's an example on how to do it with webpack (see ./sample/webpack.config.babel.js).

import { templateTransformer } from '@halleymedia/unobtrusive-vue'
//...
module: {
  rules: [
    {
      test: /\.html$/i,
      loader: 'html-loader',
      options: {
        attributes: {
          root: path.resolve(__dirname, '.')
        },
        minimize: {
          removeAttributeQuotes: false
        },
        preprocessor: (content) => templateTransformer.transform(content)
      }
    }
  ]
}

Batteries not included (so you can bring the ones you like)

Vue.js is used here just as a rendering engine. You'll have to bring your own router and event bus, if needed in your application.

Coding style

This project follow the JavaScript Standard Style. Click the banner to learn about it.

JavaScript Style Guide