Vue.js is designed to be incrementally-adoptable, so many developers will be attempting to include it in existing projects. This may mean that you are printing your variables, which are being passed from a controller, in the HTML itself via a templating engine.

The Vue way to handle this would be to rewrite your code so that your data is retrieved via an API and initialised in your view model, but often a total re-write is impractical or just doesn’t fit your project and you need to get the variable from your HTML to your view model; the angular equivalence would be ngInit.

Vue doesn’t actually provide any native functionailty for this, so we need to add it ourselves, and the simplest way is through a directive:

Vue.directive('init', {
  bind: function(el, binding, vnode) {
    vnode.context[binding.arg] = binding.value;
  }
});

 

OK, that’s a little abstract, so first, let’s look at how to use this:

<div v-init:myVar="'fooBar'">

What this says is initilise the variable myVar with the value ‘foo’. A more practical example may be passing in a slug url to the view model so we can make ajax calls to retrieve further information:

<div v-init:slug="'my-awesome-blog-post'">

So how does this actually work?

Well a vue directive can take 3 paramaters:

1) The element the directive is bound to.
2) The binding – the actual values we are passing through to the directive
3) The virtual node

Here we get the view model by using vnode.context and set the variable passed as the argument (“slug” in our case) using binding.arg and set it to the value passed to the binding (“my-awsome-blog”) using binding.value, so we end up with:

/* 
Set the passed property to the passed value
on the view model.
*/
vnode.context[binding.arg] = binding.value;

 

One last thing, the value passed is javascript, not a string literal, so if you need to pass a string (like we did in this case) you must wrap it in quotes so it isn’t evaluated as an expression.

Here’s the JSFiddle to show the directive in action

Advertisements