Can't use library function in template

There are a bunch of utility functions which are common to many components, so I created a library for them, called utils.js, like this:

export default { 

     foo(){}
      
     bar(){}

}

I import this in my components, with import utils from 'src/utils.js'. Now in my component functions I can use these shared functions with e.g, let x = utils.foo(99). Works fine. But if I try to use something like {{utils.foo(99)}} in a template I get an error when I run it telling me ‘Property or method “utils” is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option’.

It’s not a big deal as I can create a same name function within the component and simply proxy to the library function from there. I was just curious as to why I couldn’t use the library function directly, though, when I can within one of the component’s function.

Just importing at the “Javascript level” does not mean its immediately available on the template level.

You’d have to bind it to your components data properties

import utils from 'src/utils'
export default {
   data () {
    return {
       utils: utils // (utils being imported above)
    }
  }
}

Now you can access the variable utils inside your template. However, doing this will make Vue “walk” that object an attempt to “reactify it” putting getters and setters on things you just imported there (utils). This may or may not be fine, it all depends. For things like this, you most likely want to wrap those utility functions, with component methods that are also accessible within your template instead

2 Likes

Great explanation, thanks. What I’ve actually done now is to move the functions into mixins instead, and then I can simply use the mixins I require. I’ve not yet fully sorted out in my head what belongs in a mixin and what belongs in shared libraries with Vue, but I’m getting there.

I feel that the solutions which I found so far are a desperate option, from the chapter JUST TO MAKE IT WORK, somehow.
When we settle on a solution we need to think about, performance and scalability. For small projects it’s fine but when you have a util folder that holds hundreds of functions, this will make your objects heavy. In JS we don’t deal with the memory directly but your browser does it for you.

I faced this problem myself, and the solutions I used are below:

FOR SMAL COMPONENTS:

  • import the util function from where it is and just add it as a method

ex:
import {utilsFunction} from “@/utils”;

methods: {

utilsFunction

}

At this point utilsFunction will be available in template

FOR BIGGER COMPONENTS
FYI: if the utils folder is to big you may need to use this approach

  • import the util function from where it is
  • create a wrapper function around
  • put the utils function inside the wrapper function

ex:
import {utilsFunction} from “@/utils”;

methods: {

utilsFunctionWrapper(params) {
return utilsFunction(params)
}

}
At this point utilsFunction will be available in template