Nuxt.js: Unable to access Vue instance properties in asyncData

Created on 21 Sep 2017  路  11Comments  路  Source: nuxt/nuxt.js

Using the instance properties approach in a plugin, and after registering that plugin in nuxt.config.js, I'm unable to access those properties in asyncData:

export default {
  async asyncData({ app }) {
    console.log(app.$myVar); // === undefined
    return {};
  }
}

Probably related, I can't access any $variables on app. Here is what app consists of:

// console.log(Object.keys(app));
[ 'router',
  'store',
  '_nuxt',
  'head',
  'data',
  'beforeCreate',
  'created',
  'mounted',
  'watch',
  'methods',
  'components',
  'render',
  'staticRenderFns',
  '_ssrRegister',
  '__file' ]

But of course, the context docs say I should be able to.

The root vue instance that includes all your plugins. For example, when using axios, you can get access to $axios through context.app.$axios

This question is available on Nuxt.js community (#c1521)
help-wanted

Most helpful comment

HI @dfee

We are working on the docs to improve the plugins page and all the possibilities you have with it.

Nuxt.js knows when your plugin export a method, and if so, it will call it with the context as first argument, it also have a 2nd argument which is an inject method (from rc8) to add any object into vue instances context, app and store so you can use it into your store actions/mutations!

So you can do this for plugins/network-interface.js:

export default function (ctx, inject) {
  inject('hello2', 'world')
}

This will add app.$hello2 and this.$hello2 into store actions/mutations + Vue instances (see more https://github.com/nuxt/nuxt.js/blob/dev/lib/app/index.js#L117)

Also, here a pretty nice example of injecting a Vue instance into all vue instances: https://github.com/nuxt/nuxt.js/blob/dev/examples/with-cookies/plugins/cookies.js

All 11 comments

How did you init the app.$myVar before? please share this part of your plugin.

I can not try this right now and only follow the documentation, so bear with me:

// plugins/my-var.js
import Vue from 'vue'

// maybe this
Vue.prototype.$myVar = 'test'

// or this, or both?
export default ({app}) {
  app.$myVar = 'test'
}
// nuxt.config.js
module.exports {
  plugins: [
    { src: '~/plugins/my-var.js' }
  ]
}
// pages/index.vue
export default {
  asyncData({app}) {
    console.log(app.$myVar) // should print test in the console
  }
}

Here is my plugins/network-interface.js:

import io from 'socket.io-client';
import Vue from 'vue'; // eslint-disable-line


class NetworkInterface {
  constructor() {
    this.socket = io('http://localhost:9000/socket.io/');
    this.socket.on('connect', () => {
      console.warn(`connected id: ${this.socket.id}`);
    });
    this.socket.on('disconnect', () => {
      console.warn('disconnected');
    });
    this.install = this.install.bind(this);
  }

  install(Vue) { // eslint-disable-line
    Vue.prototype.$networkInteface = this;
    Vue.prototype.$socket = this.socket;
  }
}

const ni = new NetworkInterface();
Vue.use(ni);

or even a much simpler variant:

import io from 'socket.io-client';
import Vue from 'vue'; // eslint-disable-line
Vue.prototype.$socket = io('http://localhost:9000/socket.io/');

Nice! If your issue is resolved please close it.

@vuchl no, nothing is solved. I've reproduced a very basic application here. The only files that have been changed from vue init nuxt-community/starter-template client are:

  • plugins/network-interface.js
  • pages/index.vue
  • package.json

Hmm. Ok, I've gotten it to work with an export function. I've even found (some of) the relevant documentation on the plugin guide.

However, I'm unclear on when it's necessary to use an export function, and why other plugins don't require this usage.

HI @dfee

We are working on the docs to improve the plugins page and all the possibilities you have with it.

Nuxt.js knows when your plugin export a method, and if so, it will call it with the context as first argument, it also have a 2nd argument which is an inject method (from rc8) to add any object into vue instances context, app and store so you can use it into your store actions/mutations!

So you can do this for plugins/network-interface.js:

export default function (ctx, inject) {
  inject('hello2', 'world')
}

This will add app.$hello2 and this.$hello2 into store actions/mutations + Vue instances (see more https://github.com/nuxt/nuxt.js/blob/dev/lib/app/index.js#L117)

Also, here a pretty nice example of injecting a Vue instance into all vue instances: https://github.com/nuxt/nuxt.js/blob/dev/examples/with-cookies/plugins/cookies.js

I look forward to seeing the updated docs :)

This worked for me when adding the strapi SDK to the prototype, client and serverside:

import Vue from 'vue'
import Strapi from 'strapi-sdk-javascript/build/main'
import { API } from '../constants'

let strapi = new Strapi(API)

Vue.prototype.$strapi = strapi
Vue.prototype.$axios = strapi.axios

export default ({app}) => {
    app.$strapi = strapi
}

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

maicong picture maicong  路  3Comments

vadimsg picture vadimsg  路  3Comments

gary149 picture gary149  路  3Comments

msudgh picture msudgh  路  3Comments

mikekidder picture mikekidder  路  3Comments