Laravel-mix: Not able to use lodash or jquery inside interpolations in .vue files in a Laravel 5.4 project

Created on 18 Feb 2017  路  14Comments  路  Source: JeffreyWay/laravel-mix

  • Laravel Mix Version: 0.8.1
  • Node Version : 7.5.0
  • NPM Version 4.1.2
  • OS: macOS Sierra (10.12.3)

Description:

When I try to use any lodash function inside an interpolation I get the following error in the console:

[Vue warn]: Property or method "_" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option. 
(found in component <example> at /Users/jpbalda/Projects/laravel54/resources/assets/js/components/Example.vue)
warn @ app.js:32248
warnNonPresent @ app.js:33166
get @ app.js:33207
render @ app.js:31713
Vue._render @ app.js:33943
updateComponent @ app.js:34336
get @ app.js:34661
Watcher @ app.js:34653
Vue._mount @ app.js:34335
Vue$3.$mount @ app.js:37905
Vue$3.$mount @ app.js:40276
init @ app.js:33467
createComponent @ app.js:35901
createElm @ app.js:35844
createChildren @ app.js:35969
createElm @ app.js:35877
patch @ app.js:36332
Vue._update @ app.js:34362
updateComponent @ app.js:34336
get @ app.js:34661
Watcher @ app.js:34653
Vue._mount @ app.js:34335
Vue$3.$mount @ app.js:37905
Vue$3.$mount @ app.js:40276
Vue._init @ app.js:35108
Vue$3 @ app.js:35156
(anonymous) @ app.js:11202
__webpack_require__ @ app.js:20
(anonymous) @ app.js:40331
__webpack_require__ @ app.js:20
(anonymous) @ app.js:66
(anonymous) @ app.js:69
app.js:32248 [Vue warn]: Error when rendering component <example> at /Users/jpbalda/Projects/laravel54/resources/assets/js/components/Example.vue: 
warn @ app.js:32248
Vue._render @ app.js:33950
updateComponent @ app.js:34336
get @ app.js:34661
Watcher @ app.js:34653
Vue._mount @ app.js:34335
Vue$3.$mount @ app.js:37905
Vue$3.$mount @ app.js:40276
init @ app.js:33467
createComponent @ app.js:35901
createElm @ app.js:35844
createChildren @ app.js:35969
createElm @ app.js:35877
patch @ app.js:36332
Vue._update @ app.js:34362
updateComponent @ app.js:34336
get @ app.js:34661
Watcher @ app.js:34653
Vue._mount @ app.js:34335
Vue$3.$mount @ app.js:37905
Vue$3.$mount @ app.js:40276
Vue._init @ app.js:35108
Vue$3 @ app.js:35156
(anonymous) @ app.js:11202
__webpack_require__ @ app.js:20
(anonymous) @ app.js:40331
__webpack_require__ @ app.js:20
(anonymous) @ app.js:66
(anonymous) @ app.js:69
app.js:31713 Uncaught TypeError: Cannot read property 'toUpper' of undefined
    at Proxy.render (app.js:31713)
    at VueComponent.Vue._render (app.js:33943)
    at VueComponent.updateComponent (app.js:34336)
    at Watcher.get (app.js:34661)
    at new Watcher (app.js:34653)
    at VueComponent.Vue._mount (app.js:34335)
    at VueComponent.Vue$3.$mount (app.js:37905)
    at VueComponent.Vue$3.$mount (app.js:40276)
    at init (app.js:33467)
    at createComponent (app.js:35901)

Steps To Reproduce:

  1. I did a fresh laravel 5.4 install using laravel new laravel54.

  2. Ran npm install.

  3. Modified welcome.blade.php like so:

<!DOCTYPE html>
<html lang="{{ config('app.locale') }}">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>

        <!-- Fonts -->
        <link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css">
        <link rel="stylesheet" type="text/css" href="{{ asset('css/app.css') }}">

        <!-- Scripts -->
        <script>
            window.Laravel = <?php echo json_encode([
                'csrfToken' => csrf_token(),
            ]); ?>
        </script>
    </head>
    <body>
        <div id="app">
            <example></example>
        </div>
    </body>
    <script type="text/javascript" src="{{ asset('js/app.js') }}"></script>
</html>
  1. Also modified Example.vue (notice the _.toUpper function call inside the interpolation):
<template>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-default">
                    <div class="panel-heading">Example Component</div>

                    <div class="panel-body">
                        {{ _.toUpper('Message') }}
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        mounted() {
            console.log('Component mounted.')
        }
    }
</script>
  1. Ran npm run dev.

  2. Refreshed the browser and boom! I get the error mentioned above.

Same thing happens if I try to use jQuery in the interpolation.

I tried something similar in jsfiddle and it works without a problem.

My quick and dirty solution so far has been to wrap the lodash function call in a method, like this:

<template>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-default">
                    <div class="panel-heading">Example Component</div>

                    <div class="panel-body">
                        {{ myMethod("Message") }}
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        mounted() {
            console.log('Component mounted.')
        },
        methods: {
            myMethod(value) {
                return _.toUpper(value);
            }
        }
    }
</script>

Any ideas @JeffreyWay ??

Most helpful comment

Hey, do Vue.prototype._ = _ to use lodash as _ in templates. But I recommend you to define your own filters/methods that use lodash methods instead

All 14 comments

@jpbalda as far as I understand it this it the vue behavior not something that is related to laravel-mix
{{ }} expect some vue property, but you can use a computer property or normal property with a filter to do it.
Where dose the message coming from? I dont assume that you hard Code "Message"

Hi @stefanpolzer

I don't think it's vue's intended behavior, I'm using it like that in a couple of personal projects (one is using laravel-elixir and the other is pulling vue from a cdn) and they work without problems.

Please have a look at this example where I use _.toUpper function inside the interpolation.

It's my understanding that vue will evaluate any valid javascript expression between the mustaches {{ }}. For instance, you can do something simple like this {{ 55.4 + (8 * Math.random()) }} and it should work. {{ }} are not meant to be used exclusively with the vue instance's properties, methods, filters, etc.

Regarding your question about "Message", it's just a dummy text to illustrate how I'm unable to use a lodash function inside the interpolation.

@jpbalda could it be that you did not include the lodash modle window._ = require('lodash');
as it says in the first line:
[Vue warn]: Property or method "_" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.

@stefanpolzer it's included, as mentioned in my example I'm using a laravel fresh install which includes lodash by default. And, as I also mentioned, my "solution" so far to make this work has been to use the lodash function in a method in the vue instance, which means that lodash is in fact included.

@jpbalda what you have is a globle Component like this example the Componet have its own environment.
What you have is more like this example

@stefanpolzer in your second example you have a syntax error which is why it's not working. In the template you are using single quotes and then inside using single quotes again.

I have corrected your example with double quotes and it works as expected. Have a look.

I don't think this is related to Mix. You can get the same result, if you use vue-cli.

https://www.dropbox.com/s/wpr6zqdu5ujo9e3/Screenshot%202017-02-19%2016.06.56.png?dl=0

I assume it's related to how .vue file components are compiled.

Hi @JeffreyWay

I haven't used vue-cli.

I don't understand why this works in a project I have in laravel 5.3 using gulp and laravel-elixir, and now I'm trying to update the same project to laravel 5.4 and laravel-mix but I'm not able to make it work. :weary:

I'll try to play with different vuejs version and see if I can track it down. Now I'm afraid to do npm update on my laravel 5.3 project. :sob:

Thanks!

Hey, do Vue.prototype._ = _ to use lodash as _ in templates. But I recommend you to define your own filters/methods that use lodash methods instead

@jpbalda @stefanpolzer @JeffreyWay

i used v-text and passed a function in v-text.
And inside the method i was able to use _ (lodash), which returned the value in v-text.

This solution worked perfectly

Check out vue-lodash!!
It's a wrapper for using lodash in vue.
You can call it using

Vue._.function

or

this._.function

in any of the .vue file :)

I think what are you doing isn't the correct way. You should use it on the Computed Property, not directly in the template like that.

@posva

Hey, do Vue.prototype._ = _ to use lodash as _ in templates. But I recommend you to define your own filters/methods that use lodash methods instead

Thanks, works well!!

Hey, do Vue.prototype._ = _ to use lodash as _ in templates. But I recommend you to define your own filters/methods that use lodash methods instead

This answer is accepted (y)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jpmurray picture jpmurray  路  3Comments

Cheddam picture Cheddam  路  3Comments

wendt88 picture wendt88  路  3Comments

dtheb picture dtheb  路  3Comments

Micaso picture Micaso  路  3Comments