16

How do you access the Vue instance from a directive?

I have this HTML

<div id='vueApp' v-init='my initial data from server-side'>

and this script

var app = new Vue({
    el: '#vueApp',
    data: {
        myData: null
    }
});

Vue.directive('init', function(el, binding) {
    app.myData = binding.value;
});

It throws this error:

Failed to resolve directive: init

1 Answer 1

28

Your particular error is because the directive is created after the Vue.

For this particular directive, you could access the Vue through vnode.context.

Vue.directive('init', {
  bind(el, binding, vnode){
    vnode.context.myData = binding.expression;
  }
});

const app = new Vue({
    el: '#vueApp',
    data: {
        myData: null
    }
});

Example.

You might also consider using vnode.context.$root.

Post Comment Edit

You could also just do this:

const initialData = {
    someData: "Hello Vue!"
};

const app = new Vue({
    el: '#vueApp',
    data: {
        myData: intialData
    }
});
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you! This works, but now I can't modify myData. I also got "[Vue warn]: You may have an infinite update loop in a component render function. " Should I be using props like jfadich said?
@Aximili We could probably work through it the issues (use Vue.set for example instead straight up setting it equal), but I would say that this is an unusual way to initialize your Vue. What you might consider is simply data: { myData: <your data>}. I edited the answer with an example.
@Aximili for future reference, I corrected the directive, so you won't get the warning.
Thanks Bert Evans. I need to put the value in the HTML as it comes from server-side. The reason for this is to save an unnecessary AJAX call when a page is first loaded.
@Aximili You're welcome. For what it's worth, most server side frameworks will let you render JSON inside script tags, so you should be able to render the initial data to script as well as to an attribute.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.