Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass Javascript Variable to Vue

How can i pass a Javascript Variable to a Vue Component?

I have this jQuery function which generates the menu and pushes all the Values inside the array menu:

var menu = [];

$(document).ready(function(){
    $('.service-desc-wrap h2,.cta-button').each(function(){
        if($(this).hasClass('cta-button')) {
            if($(this).attr('title') && $(this).attr('href')) {
                var linkTitle = $(this).attr('title');
                var href = $(this).attr('href');
                data = [
                    title = linkTitle, 
                    href = href,
                ]
                menu.push(data);
                $('#menu, #menuMobile').append('<a class="menuText" href="'+href+'">'+linkTitle+'</a>')
            };
        } else {
            var tag = $.slugify($(this).text());
            $(this).attr('id',tag);
            var linkTitle = $(this).text();
            if($(this).attr('title')) {
                var linkTitle = $(this).attr('title');
            };
                data = [
                    title = linkTitle, 
                    href = tag,
                ]
                menu.push(data);
            $('#menu, #menuMobile').append('<a class="menuText" href="#'+tag+'">'+linkTitle+'</a>')
        }
    }); 
}); 

I want to pass the array to a Vue Component called

<service-menu-component></service-menu-component>

The jQuery Function and the Component are inside a blade.php file, i'm using Laravel as a backend.

like image 333
Steve Avatar asked Nov 03 '25 02:11

Steve


1 Answers

Any Vue component has access to the global scope (a.k.a window object), in which $ performs. You don't have to do anything special about it. In simpler words, if a variable has been declared in global scope at the time your Vue component is created - Vue can access it. But Vue won't react to later mutations performed on the contents of that variable. Not out of the box, anyway.

In Vue, that behavior is called reactivity. If that's what you want, you could use Vue.observable():

  • declare a const, holding a reactive reference (store.menu in this example - name it to whatever makes sense to you)
  • use a computed in your Vue component, returning the reactive reference
  • at any point, (before or after Vue instance's creation) modify the reference from anywhere (including outside Vue component/instance) and the Vue instance will get the change

Proof of concept:

Vue.config.productionTip = false;
Vue.config.devtools = false;
// you don't need the above config, it just suppresses some warnings on SO

// declare store, with whatever contents you want:
const store = Vue.observable({menu: []}); 

// optionally push something to menu:
// works before Vue instance was created
store.menu.push({foo: 'bar'});

$(function() {
  // optionally push something to menu 
  // also works after Vue instance was created - i.e: 3s after $(document).ready()
  setTimeout(function() {
    store.menu.push({boo: 'far'});
  }, 3000)
})

new Vue({
  el: '#app',
  computed: {
    menu() {
      // this injects the store's menu (the reactive property) in your component
      return store.menu
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.12/vue.js"></script>
<div id="app">
  <pre v-text="menu"></pre>
</div>

The computed doesn't have to be on the root Vue element (it can be inside your <service-menu-component> component). The above is just a basic implementation, to demo the principle.

like image 128
tao Avatar answered Nov 04 '25 18:11

tao