[Vuejs]-Vuejs can't use lodash inside template but it works on code

2πŸ‘

βœ…

Extending on my comment: I usually discourage using third party util/helper methods inside VueJS template. This is, of course, a personal choice, but it is way simpler to let VueJS handle the rendering directly (and also guards against possible reactivity issues down the road). Therefore, you can simply use a computed property (or a method, if you need to pass arguments) to generate the string, which is inserted into the template.

Example:

computed: {
  addressName() {
    return _.get(this.user, 'address.name');
  }
}

Then, in your template, you can simply use {{ addressName }} to render the string. Should you require more dynamic use with more flexibility and abstraction, you can use methods instead. For example, if your path is going to be dynamic, you can then create a method that retrieves data from this.user with a provided path argument:

methods: {
  userData(path) {
    return _.get(this.user, path);
  }
}

In your template you can simply use {{ userData('address.name') }}.

πŸ‘€Terry

1πŸ‘

That’s probably because the rendering (so the call of the property β€œ_”) is done before his instantiation.

In your case, you may have to set window._ in the created lifecycle callback that is called before the rendering.

But my recommendation is to set this in a β€œdata” property of your component and even to only import and set the functions you need.

For exemple:

import clone from 'lodash/clone'
πŸ‘€Victor Castro

0πŸ‘

For those who prefer lodash to be available globally in all files, and/or use lodash.mixins.

I decided to use the app.provide and inject it into components where I wanna use lodash in the template. The only problem I has was that I couldn’t use _, I had to settle on $_.


file structure

.
β”œβ”€β”€ src
β”‚   β”œβ”€β”€ components
β”‚   β”‚   └── BaseBtn.vue
β”‚   └── utils
β”‚       β”œβ”€β”€ global
β”‚       β”‚   └── plugins.js
β”‚       └── plugins
β”‚           └── lodash.js
└── main.js

main.js

import { createApp } from 'vue'
import { createPinia } from 'pinia'

import '@/utils/plugins/lodash'
import App from './App.vue'
import router from './router'
import registerGlobalPlugins from '@/utils/global/plugins'

import './assets/scss/index.scss'

const app = createApp(App)

app.use(createPinia())
app.use(router)
registerGlobalPlugins(app)

app.mount('#app')

src/utils/plugins/lodash.js

import _ from 'lodash'

export const lodashMixin = {
  /** Converts obj keys to camelCase */
  $camelCaseKeys (object) {
    return _.mapKeys(object, (_value, key) => _.camelCase(key))
  },

  /** Pauses code for x milliseconds */
  $pause (milliseconds) {
    return new Promise((resolve) => setTimeout(resolve, milliseconds))
  },
}

_.mixin(lodashMixin)
window._ = _

export const lodashPlugin = {
  install (app) {
    app.provide('$_', _)
  },
}

src/components/BaseButton.vue

<template>
  <button>
    {{ $_.sample(['this', 'is', 'an', 'example']) }}
  </button>
</template>

<script>
export default {
  inject: ['$_'],

  methods: {
    async handleClick () {
      await _.$pause(500) // this will work due to import in main.js
      await this.$_.$pause(500) // this should also work via the inject
    }
  }
}
</script>
πŸ‘€4uroraskye

Leave a comment