Kevin T.
Kevin T.

Reputation: 758

How to use use custom Vue plugin

I created a Vue plugin to activate console.logs if a user sets a property in localStorage. The plugin is a wrapper around console.log(). If the user enters 'localStorage.isLoggingData = true', then the plugin will test if that property exists in local storage and the logData function with run

index.js

import logData from '../plugins/logData

  // I want to console.log this inital data coming into the app
  async init ({ state, commit, dispatch }) {
    try {
      const { data } = await messaging.send(ACTION.READY)
      logData(data)

main.js

import logData from '../plugins/logData

// Use logData to optionally view console.log statements
Vue.use(logData)

logData.js

export default {
  install: function (Vue) {
    Vue.prototype.$logData = function (dataToLog) {
      const isLoggingData = localStorage.getItem('isLoggingData')
      if (isLoggingData) {
        console.log(dataToLog)
      }
    }
  }
}

Currently when we have an application error we route to an error page, when I comment out the 'logData(data)' I am routed to the correct page in my app. Am I not creating the plugin or importing it correctly?

Update

index.spec.js

import logData from '../plugins/logger'
import { createLocalVue, shallowMount } from '@vue/test-utils'
import App from '@src/App'

const localVue = createLocalVue()
localVue.use(Vuex)
localVue.use(logData)

const mocks = {
  _vm: {}
}
mocks._vm.$logData = logData

const wrapper = shallowMount(App, {
  mocks,
  localVue
})

I am now told to mock _vm. Is this the correct way to mock it?

Upvotes: 2

Views: 1474

Answers (1)

Turtlefight
Turtlefight

Reputation: 10975

Your init({ state, commit, dispatch }) function looks like it comes from vuex.
You can't access vue methods from vuex actions directly.

You could directly export your logData function in index.js and import that in vuex:

index.js

import { logData } from '../plugins/logData';

// I want to console.log this inital data coming into the app
async init ({ state, commit, dispatch }) {
  try {
    const { data } = await messaging.send(ACTION.READY);
    logData(data);
    // ...
  } catch(e) { /* ... */ }
}

main.js

import logDataPlugin from '../plugins/logData';

// Use logData to optionally view console.log statements
Vue.use(logDataPlugin);

logData.js

export function logData(dataToLog) {
  const isLoggingData = localStorage.getItem('isLoggingData');
  if (isLoggingData)
    console.log(dataToLog);
}

export default {
  install: function (Vue) {
    Vue.prototype.$logData = logData;
  }
}

If you want to have the method only as a vue plugin and not expose it directly you could pass the vue instance to your vuex action to access $logData:

// in your vuex actions:
const actions = {
  async init ({ state, commit, dispatch }, {vm}) {
    vm.$logData("Hello");
  }
};

// call action from vue component:
export default {
   mounted() {
     // pass reference to vue instance to vuex store
     this.init({vm: this});
   },
   methods: {
     ...mapActions(['init'])
   }
}

Upvotes: 1

Related Questions