Basics: Getting started w Meteor + VueJS

Got it! So after installing all the various $ meteor add <lib>'s I should do $ meteor npm install in order to pull over all the relivant dependencies from npm. :slight_smile:

Thanks a lot!

1 Like

Thanks @gusto, glad it helped.

I actually copied the code from the already working app that Akryum had for older package versions.

I’m fairly new to Vue, but if I got your question right, I think you need to discern between globally registered components (like in your example code) and local scoped components (like Akryum did on his code)

I’ll be gladly corrected though :slight_smile:

2 Likes

Thanks. Reviewing your router file I noticed you create a router instance like so:

// Create router instance
const router = new Router({
  mode: 'history',
  scrollBehavior: nativeScrollBehavior,
});

why do that instead of just this (which works also):

Router.configure(router => {
    router.addRoutes([{
        path: "/",
        name: "Index",
        components: {
            default: Index,
        }
    }, {
        path: "/page",
        name: "Page",
        components: {
            default: Page,
        }
    }, ]);
});

Is it so you can configure router behavior like scrollBehavior?

This code is actually recommend by owner of this package, Akryum. However, i just change it to imports folder for separation of my code. Maybe you can ask Akryum on this matter. Sorry.

@ackzell yes, that’s the main difference between them. But in Meteor app, where there’s no (production-ready) solution for dynamically loaded components (yet) and we get all of them at the same time, is there some other thing that would work in favour of one of these options?

I’m wondering about such stuff (and other matters) in the context of best practices for Vue+Meteor community, that would become a basis for Vue chapter of Meteor Guide in the future.

That said, the “Akryum used it so people will tend to follow his example” is an actually reasonable argument, so I’ll update my code and see how that works for me.

Anyone know where I can find an example of a VueJS component subscribing to a publish method and doing an autorun in something akin to an OnCreated, then querying mini-mongo and consuming the data within the component?

Or is this the way things are done in Meteor + Vue? Subscribe to the Publish method and consume via Mini-Mongo at the lowest possible (component) level?

Actually i have the code but most of my code are using this documentation:

Vue Meteor Tracker

1 Like

Akryum’s meteor-vue2-example does exactly that. Check out this particular file: https://github.com/Akryum/meteor-vue2-example/blob/master/imports/ui/Chat.vue

Note that you don’t need to use autorun for most use cases in Vue, especially for Meteor stuff because Akryum’s package runs it through autorun by default. If you do need it for Vue related stuff, check out watchers feature.


Btw, do you guys use Vuex? Do you use Akryum’s Vuex1 package (Akryum states that it doesn’t work with Vue2 in some cases) or Vuex2 through npm? Did you have any issues with it?

1 Like

Okay, I almost have this wired up, but am getting an undefined when the data is correct on the client AFAICT:

Page.vue:

<template>
  <div>
    <input v-model="newPerson" @keyup.enter="addPerson" placeholder="Enter new Person Name" />

    <div v-if="!$subReady.people">
      Loading...
    </div>

    <div class="people" v-for="ppl in peoples">
      <span class="content">{{ ppl.person }}</span>
      <button @click="removePerson(ppl._id)">x</button>
    </div>
  </div>
</template>


<script>
  export default {
    name: 'Page',
    data: () => ({
      newPerson: '',
    }),
    meteor: {
      subscribe: {
        'people': [],
      },
      peoples() {
        let ppl = People.find({}, {
          sort: { date: -1 },
        });
        debugger;
        return ppl;
      },
    },
    methods: {
      addPerson() {
        debugger;
        Meteor.call('addPerson', this.newPerson);
        this.newPerson = '';
      },
      removePerson(_id) {
        Meteor.call('removePerson', _id);
      },
    },
  };
</script>

Above, the newPerson input is working, as the data is being input into mongo.

As for displaying people on the client, the peoples() method is returning the results from the mini-mongo query People.find(), but it displays undefined instead.

The methods:

Meteor.methods({
  addPerson(person) {
    debugger;
    People.insert({
      person,
      date: new Date(),
    });
  },
  removePerson(_id) {
    People.remove(_id);
  },
});

The publish:

Meteor.publish('people', function() {
  return People.find({});
});

In Vue Devtools it shows:

$route: Object
 fullPath: "/page"
 meta: Object (empty)
 name: "Page"
 params: Object (empty)
 path: "/page"
 query: Object (empty)
newPerson: ""
peoples: null

Doing a fetch on the cursor in the console while debugging the peoples() method shows:

is there some other thing that would work in favour of one of these options?

No idea to be honest. But it is not only about the time at which they get loaded, what I understand is more like the scope in which those components live and interact with others. Isn’t it?

And yes, that code has a little (or a lot) of

“Akryum used it so people will tend to follow his example”

I consider myself more on the learning side of the fence rather than trying to show people how to use Vue+Meteor.

I believe almost all of us are. Vue as a frontend for Meteor is still a relatively new concept, even if Vue is mature already.

Are there any Vue+Meteor apps in production already?

And is the “Apollo+Vue” even a valid title for this thread? :wink:

Which version of Vue are you using? I believe it to be an issue between Akryum’s packages and Vue higher than 2.1.6. Switching back to 2.1.6 does solve the same problem for me. Remember about meteor npm install.

do you get any error in console?

Good news, meteor-vue2-example by Akryum works fine again. :slight_smile:

@aadams with Vue 2.1.8, the potential trick is to add peoples: [] to data(). Try that please.

1 Like

@skynightz93 no errors. I wish there was, I might have a chance to solve it myself if errors are displayed.

Yes, I’m on vue: ^2.1.8 .

The commands I used to set up my environment are above, and in that I specified the version, $ meteor npm install --save vue@^2.1.6, so I don’t know how I got to 2.1.8.

How do I remove the version I have and install a specific version?

Here’s the full repo as reference.

One way is to create a shrinkwrap file npm shrinkwrap to lock all the versions at what you already have installed and working.

Another is to remove the ^ and/or ~ characters from the versions on your package.json file when you install again the npm dependencies.

2 Likes

I don’t notice this issue anymore in Akryum’s example project (as he updated it today) and in mine too, so you have two options to try.

  1. Keep Vue at 2.1.8 and add property declaration peoples: [] in data() - this will potentially solve the problem
  2. Change ^2.1.8 to 2.1.6 and do meteor npm install - in this version don’t add the property in data()

One of them should be enough, hopefully the first one.

By the way, if you don’t want the button, the alternative for keyup.enter event on input is submit.prevent on form element.

1 Like

I changed the code to the following, where I added peoples: [] to data: () yet still got the undefined.

<script>
  export default {
    name: 'page',
    data: () => ({
      newPerson: '',
      peoples: []
    }),
    meteor: {
      subscribe: {
        'people': [],
      },
      peoples() {
        let ppl = People.find({}, {
          sort: { date: -1 },
        });
        debugger;
        return ppl;
      },
    },
    methods: {
      addPerson() {
        debugger;
        Meteor.call('addPerson', this.newPerson);
        this.newPerson = '';
      },
      removePerson(_id) {
        Meteor.call('removePerson', _id);
      },
    },
  };
</script>

I’m going to now try to downgrade vue versions.

I changed to version 2.1.6 and didn’t change the code, and it now works… Is this a bug somewhere? Here’s the code that works on vue version 2.1.6 but not 2.1.8:

<template>
  <div>
    <input v-model="newPerson" @keyup.enter="addPerson" placeholder="Enter new Person Name" />

    <div v-if="!$subReady.people">
      Loading...
    </div>

    <div class="people" v-for="ppl in peoples">
      <span class="content">{{ ppl.person }}</span>
      <button @click="removePerson(ppl._id)">x</button>
    </div>
  </div>
</template>


<script>
  export default {
    name: 'page',
    data: () => ({
      newPerson: '',
      peoples: []
    }),
    meteor: {
      subscribe: {
        'people': [],
      },
      peoples() {
        let ppl = People.find({}, {
          sort: { date: -1 },
        });
        debugger;
        return ppl;
      },
    },
    methods: {
      addPerson() {
        debugger;
        Meteor.call('addPerson', this.newPerson);
        this.newPerson = '';
      },
      removePerson(_id) {
        Meteor.call('removePerson', _id);
      },
    },
  };
</script>

Again, the repo is here: GitHub - aadamsx/fp-admin: meteor + vue

Thanks @gusto!