Work with Vuejs and normal Javascript (vanilla)

Viewed 2425

I need to use Vue and call another function in normal javascript, also need to change some variables in Vue and read them in Javascript after.

The solution on internet is to insert normal javascript functions into a Vue component (meaning move everything to Vue), but some functions are too big or too complicated to refacture to Vue.

So, i need a way to work with variables and functions between Vanilla Javascript and Vue, in the meantime i move everything to Vue.

2 Answers

After a while i found a Solution (Workaround):

The only way possible i know to comunicate between normal javascript, PHP, Laravel and Vuejs, is using html tags as intermediaries, from them you can do all sort of stuff.

You can set any value from vue to a hidden input or a any DOM data, and read after from javascript, you can also trigger DOM events from Vue, and execute them in your regular Javascript.

This is a Workaround, since this is not optimal use of Vuejs, but if you need to use Vue and still use normal javascript, hope this will help you.

For example, to trigger a variable change in vue to Javascript:

In your Vue component:

<template>

    <input type="text" v-model="my_value" onchange="vanillaFunction(this.value)">

</template>

<script>

export default {
    name: 'test-vue',
    data: function (){
        return {
            my_value: 'start',
        }

    },
    created: function () {
        this.my_value = 'finish'
    },
    mounted: function () {
        this.my_value = 'mounted'
    },
    watch: {
        my_value: function (val) {
            $("input#my_value").trigger('change')
        },
    },
};

</script>

In your javascript file:

function vanillaFunction(value){
    console.log('Vue has changed the value to: ' + value)
}

The template only has access to the Vue instance's context. In other words, to what this refers to in your component. If you want to make anything from global context available in the template, redeclare it in computed, using an arrow function returning the global reference:

computed: {
  vanillaFunction: () => vanillaFunction
}

See it working:

Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
  el: '#app',
  computed: {
    window: () => window,
    console: () => console,
    vanillaFunction: () => vanillaFunction
  }
})
<script>
  function vanillaFunction() {
    console.log('Boo!');
  }
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <button @click="vanillaFunction">vanillaFunction</button>
  <button @click="console.log(window.console.warn('You scared me!') || '¯\\_(ツ)_/¯')">console, window</button>
</div>

window, console and vanillaFunction which are declared in global context and not normally available into your template are now directly usable in the template.


An alternative method of making global functions available inside the template is to declare them as methods. However, since methods need to be functions, it only works for functions, whereas computed can declare any global object or class.

See it working as method:

Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
  el: '#app',
  data: () => ({
    my_value: ''
  }),
  methods: {
    vanillaFunction
  }
})
<script>
  function vanillaFunction(value) {
    console.log('Vue has changed the value to: ' + value)
  }
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <input type="text" v-model="my_value" @input="vanillaFunction(my_value)">
</div>


Additional note: don't use this in template.

Related