Basics: Component building in Meteor + VueJS

Switched it to

Meteor.startup(() => {
  Vue.use(VueMeteorTracker);

  new Vue({
      router: router.start(),
      render: h => h(AppLayout),
  }).$mount('app');
});

and it works! Thank you!

Just curious, why do you get to set the property on Vue, before creating the Vue Instance?

No idea. As weā€™re already giving some examples, hereā€™s something you may want to have implemented in the future. The way to synchronize Vue-router with Vuex store, so that recent router data is available for you as Vuex submodule:

import { Meteor } from 'meteor/meteor'
import { Vue } from 'meteor/akryum:vue'
import Vuex from 'vuex'
import Router from 'vue-router'
import { sync } from 'vuex-router-sync'

import VuexStore from '/imports/vuex/store'
import { routes } from '/imports/routes/main'

import App from '/imports/ui/App.vue'

Vue.use(Router)

const store = new Vuex.Store(VuexStore)

const router = new Router({
   routes,
   mode: 'history', 
})

sync(store, router)

Meteor.startup(() => {
  new Vue({
    router,
    store,
    render: h => h(App),
  }).$mount('app')
})
1 Like

Thanks @gusto, also it looks like youā€™re not using akryum:vue-router2, but just vue-router, any reason, any differences?

Lol. That was completely by chance. I just followed the code in some tutorial and didnā€™t even notice that it is not the akryum:vue-router2 Iā€™m importing. Anyways, it works fine.

The difference most possibly is that Iā€™m now not able to write my routes in /client folder, as it is described in akryum:vue-router docs and forced to do them all in /imports. That was a nice feature that I saw in example apps but couldnā€™t implement in my code for some reason and it makes sense now that you pointed it out.

Vue.use(plugin) installs plugins into vue. You need to install the plugins before starting the Vue apps/widgets, otherwise the modifications made by the plugins wonā€™t be applied to the already created Vue instances.

2 Likes

Thank you @akryum. Is it possible to also use native vue-router without akryum:vue-router2?

I started a new thread about this here.

Yes, but you canā€™t use any of the helpers defined in akryum:vue-router2, like Router.configure.

Yeah I think an article on Meteorā€™s Medium blog would be a great place to start. That could put Meteor + Vue on the map in a bigger way, and then more people will try it to figure out best practices! The post can just list some of the different ways to get started.

2 Likes

@gusto What does this file look like for you?

import VuexStore from '/imports/vuex/store'

Thank you very much for this @akryum. I saw in the docs where we can use an empty Vue instance as a central event bus for communication between components: https://vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication

But what about using Vuex2 for this ā€“ is it overkill? Will you transform your example https://jsfiddle.net/Akryum/t2xzt7mr/ to use vuex2 instead?

right below the docs you linked it says

In more complex cases, you should consider employing a dedicated state-management pattern.

so thatā€™s really up to you and how complex your application is or will be

Right. I want to use vuex and Iā€™m asking for an example of vuex using the same scenario as the last one. :slight_smile:

I think it may be overkill just to validate forms.

@aadams you can easily make that using the way I introduced in Vuex+Accounts example + possibly get() and set() for computed variable that I wrote an example for earlier, you can also find that part in the Vuex docs.

But trying to put every little bit of the state into Vuex will end up being more boilerplate than itā€™s worth.

It looks like:

export default({
  modules: {},
  state: {},
  mutations: {}
})

with whatever state I need inside

1 Like

Thanks for the advice @akryum & @gusto. Can we turn the question around, under what circumstances should we use vuex? :slight_smile:

``> I need to pass state between ā€œtemplatesā€ (at a higher ā€œpageā€ level). Like the template level of Blaze, and the state would be pass around like what I used to use Session for ā€“ and ID or the like.

`` > I need to pass data between components (I can use and empty Vue instance for this). So what I would use ReactiveVars for before.

`` > I need to retrieve many documents from Mongo, and perform many calculations on fields, and then store this information for consumption by the lager ā€œtemplatesā€. There is a lot of data in one Session I pass around to some of the templates. This to me is what I think makes the most sense for using vuex.

So if Iā€™m going to need to use for that large dataset, why not learn how to use it now? Maybe I donā€™t store client side validation variables inside it, but eventually Iā€™m going to need it.

Oh-well, Iā€™ll try simple form control validation with a shared Vue instance and pick up vuex later. :slight_smile:

@akryum, Iā€™m wondering, are you instantiating a new Vue instance for each <component-name>.vue file, and tying the name of that instance to the file name (unless a name property is specified inside the control) with the vue-component lib?

If so, then are you binding the <script>data</script> attribute within the <component-name>.vue file to said new Vue instance?

If you mean Vue component definition, then yes. If you donā€™t define a name, akryum:vue-component will do it for you based on the filename. Plus, if you put your Vue files outside of imports, it will register them automatically with Vue.component().

1 Like

Now thatā€™s what I call Meteor Magic.

Yes, I mean for each componentā€¦

Itā€™s just, please correct me, but when reviewing the Guide and API, it seems that each component is actually a new Vue instance, and these instances communicate via events, such as v-model, $emit, and $on. And the data attribute binds to the markup. But itā€™s all centered about the new Vue instance.

But when building these component .vue files, Iā€™m not making new Vue instances each time, just the one in my app.js file like so:

Meteor.startup(() => {
  const app = new Vue({
    router: router,
    render: h => h(AppLayout),
  }).$mount('app');
});

So I was wondering if you were actually doing this for us under the covers so to speak. :slight_smile:

Well not me, thatā€™s how Vue works under the hood. It calls the new Vue() for you everywhere you use a component, in templates for example.

2 Likes