3

main.js has this code

window.l = function () { }
try {
  window.l = console.log.bind(console)
} catch (e) { }

which works in non-Vue apps. However, when calling

l("test")

from a Vue action/method, it complains it isn't defined.

How can that work?

Reasoning: need to output some debugging data, with as less typing as possible.

2
  • Where did you define window.l? Commented Aug 7, 2017 at 12:41
  • in main.js Should it be somewhere else? Commented Aug 8, 2017 at 14:54

2 Answers 2

4

When you want to add global-level functionalities to Vue, you should generally use mixins or plugins.

For the next examples, I assume you are using vue-cli with the complete webpack template. Moreover, we will use App.vue as a practical reference, but you can apply the same principles to other components...


Mixins

Create a mixin named log.js (in a mixins folder) with the following code:

export default {
  methods: {
    l (...args) { // rest parameters
      console.log(...args) // spread operator
    }
  }
}

Open App.vue, import your mixin and use it:

<script>
  import log from './mixins/log'

  export default {
    name: 'app',
    mixins: [log],
    created () {
      this.l('Foo', 'Bar') // Foo Bar
    }
  }
</script>

Plugins

Create a plugin named log.js (in a plugins folder) with the following code:

export default {
  install (Vue, options) {
    Vue.prototype.$l = console.log.bind(console)
    Vue.l = console.log.bind(console)
  }
}

Open your main.js and declare your global plugin:

import log from './plugins/log'
Vue.use(log)

Open App.vue, import Vue and use your plugin:

<script>
  import Vue from 'vue'

  export default {
    name: 'app',
    created () {
      this.$l('Foo') // Foo
      Vue.l('Bar') // Bar
    }
  }
</script>

You might say: "Hey, why should I have to write this or Vue? I just wanna write l, that's all!". Well... This is actually how Vue has been designed. In order to provide global functionalities (shared by all components), you have to add static properties to the Vue object or prototype properties (Vue.prototype) that are accessible through this in Vue instances.


EDIT

I have just thought about an alternative solution...

You can edit your index.html to add this:

<script>
  var l = console.log.bind(console)
</script>

Then, to avoid ESLint errors, you should also edit your .eslintrc.js file to reference your new global variable:

globals: {
  l: true
}

The file looks like this:

// http://eslint.org/docs/user-guide/configuring

module.exports = {
  root: true,
  parser: 'babel-eslint',
  parserOptions: {
    sourceType: 'module'
  },
  globals: {
    l: true
  },
  env: {
    browser: true,
  },
  // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
  extends: 'standard',
  // required to lint *.vue files
  plugins: [
    'html'
  ],
  // add your custom rules here
  'rules': {
    // allow paren-less arrow functions
    'arrow-parens': 0,
    // allow async-await
    'generator-star-spacing': 0,
    // allow debugger during development
    'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
  }
}

Restart your dev server. Now you should be able to use l in your code:

<script>
  export default {
    name: 'app',
    created () {
      l('It works!')
    }
  }
</script>
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks so much for the detailed answer, including "Hey, why should I have to write this or Vue?" (you read my mind), and the alternative solution (great!). You rock!
1

Assign console.log like this.

window.l=console.log;

2 Comments

using l('test') in another Vue file gives Uncaught ReferenceError: l is not defined at eval (webpack-internal:///67:4) at Object.<anonymous> ( Even the long form (although we don't want that) gives Uncaught TypeError: window.l is not a function
I put this in public/index.html and restarted the server and it worked in a vue file.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.