Vue: Cannot seem to set properties on a vm from a directive in Vue 2.0

Created on 4 Nov 2016  路  3Comments  路  Source: vuejs/vue

In Vue 1.0, it was possible to set data on the vm of the component calling the directive:

Vue.directive('my-directive', {
  bind() {
    this.vm.$set('hello', 'world');
    this.vm.hello; // -> "world"
  }
});

This was useful in, for example, pagination directives which would set the current page number and the number of pages.

In Vue 2.0, the functionality seems to be there, but it doesn't work:

Vue.directive('my-directive', {
  bind(el, binding, vnode) {
    Vue.set(vnode.context, 'hello', 'world');
    vnode.context.hello; // -> undefined
  }
});

Is this intentional, or should I send a PR with a failing test case? (or am I just misunderstanding something?)

All 3 comments

In 2.0, a Vue instance's root level reactive properties are static. If it's not declared in the component's data option, you cannot add it dynamically at runtime. In fact you should see a warning in console in your second example.

In your case, your directive should now require the user to declare the property it needs to access and modify.

@yyx990803 Is it possible to make the first and second parameter dynamic? For example when i'm passing them as an argument or binding?

Vue.set(vnode.context.$data.property.subproperty, 'content', _el.val());

@yyx990803 that is unfortunate though. In our dynamic platform we have a dom component which was written like this

<rs-get document-id="some-id" as="someDynamicVariableName">
   <!-- in here we could acess outer scope variables AND someDynamicVariableName -->
   {{someOuterScopeVariable}} {{someDynamicVariableName}}
</rs-get>

Now we would have to add some very technical details to the outer DOM for technical reasons it seems:

<rs-get document-id="some-id">
   <template scope="someDynamicVariableName">
     {{someOuterScopeVariable}} {{someDynamicVariableName}}
   </template>
</rs-get>

the as attribute is only evaluated as a static dom attribute so will not change after parsing the template.
i thought I could use scoped slots but the requirement for the