Skip to content

meteor-mogul/vue-meteor-tracker

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vue integration for Meteor

npm npm vue1 vue2

Declarative subscriptions and meteor reactive data (subscriptions, collections, tracker...)

Example project

Installation

meteor npm install --save vue-meteor-tracker

Install the plugin into Vue:

import VueMeteorTracker from 'vue-meteor-tracker';
Vue.use(VueMeteorTracker);

Note: if you are using the Meteor akryum:vue package, you don't need to install the plugin.

⚠️ You may need to polyfill Object.assign.

Usage

In your Vue component, add a meteor object :

new Vue({
  meteor: {
    // Meteor specific options
  }
});

Subscriptions

Add an object for each subscription in a $subscribe object. The object key is the name of the publication and the value is either an array of parameters or a function returning an array of parameters. These subscription will be stopped when the component is destroyed.

meteor: {
  // Subscriptions
  $subscribe: {
    // Subscribes to the 'threads' publication with no parameters
    'threads': [],
    // Subscribes to the 'threads' publication with static parameters
    'threads': ['new', 10], // The 10 newest threads
    // Subscribes to the 'posts' publication with dynamic parameters
    // The subscription will be re-called when a vue reactive property changes
    'posts': function() {
      // Here you can use Vue reactive properties
      return [this.selectedThreadId] // Subscription params
    }
  }
}

You can also use the $subscribe(name, ...params) method in you component code:

ready () {
  // Subscribes to the 'threads' publication with two parameters
  this.$subscribe('thread', 'new', 10);
}

The $subReady object on your component contains the state of your subscriptions. For example, to know if the 'thread' subscription is ready, use this reactive expression:

console.log(this.$subReady.thread);

Or in your template:

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

You can also change the default subscription method by defining the Vue.config.meteor.subscribe function:

// You can replace the default subcription function with your own
// Here we replace the native subscribe() with a cached one
// with the ccorcos:subs-cache package
const subsCache = new SubsCache({
  expireAfter: 15,
  cacheLimit: -1
});

Vue.config.meteor.subscribe = function(...args) {
  return subsCache.subscribe(...args);
};

Reactive data

You can make your component data properties update from any Meteor reactive sources (like collections or session) by putting an object for each property in the meteor object. The object key is the name of the property (it shouldn't start with $), and the value is either a function or an object with the following attributes:

  • params() (optional), a function returning an object, which can use any Vue reactive property,
  • update([params]), a function with optional params argument, that returns the value to update the corresponding data property of the component. Here you can use Meteor reactive sources, but no Vue reactive property getters. The params argument is the object returned by the params() function described above.

Here is an example:

new Vue({
 data() {
   return {
     selectedThreadId: null,
     // We can init the property value in the data() component hook
     threads: [],
     selectedThread: null
   };
 },
 meteor: {
   // Subscriptions
   $subscribe: {
     // We subscribe to the 'threads' publication
     'threads': []
   },
   // Threads list
   // This will update the 'threads' array property on the Vue instance
   // that we set in the data() hook earlier
   // You can use a function directly if you don't need
   // parameters coming from the Vue instance
   threads () {
     // Here you can use Meteor reactive sources
     // like cursors or reactive vars
     // as you would in a Blaze template helper
     // However, Vue reactive properties will not update
     return Threads.find({}, {
       sort: {date: -1}
     });
   },
   // Selected thread
   // This will update the 'selectedThread' object property on component
   selectedThread: {
     //// Vue Reactivity
     // We declare which params depends on reactive vue properties
     params () {
       // Here you can use Vue reactive properties
       // Don't use Meteor reactive sources!
       return {
         id: this.selectedThreadId
       };
     },
     // Optionally we can watch the parameters for changes in nested
     // objects using the 'deep' option
     deep: true,
     //// Meteor Reactivity
     // This will be refresh each time above params changes from Vue
     // Then it calls Tracker.autorun() to refresh the result
     // each time a Meteor reactive source changes
     update ({id}) {
       // Here you can use Meteor reactive sources
       // like cursors or reactive vars
       // Don't use Vue reactive properties!
       return Threads.findOne(id);
     },
   },
 },
});

You can skip the data initialization (the default value will be null):

new Vue({
 data() {
   return {
     selectedThreadId: null,
   };
 },
 meteor: {
   // Subscriptions
   $subscribe: {
     'threads': []
   },
   // Threads list
   threads () {
     return Threads.find({}, {
       sort: {date: -1}
     });
   },
   // Selected thread
   selectedThread: {
     params () {
       return {
         id: this.selectedThreadId
       };
     },
     update ({id}) {
       return Threads.findOne(id);
     },
   },
 },
});

You can then use the reactive data in the template since it's standard Vue component properties:

<!-- Thread list -->
<thread-item v-for="thread in threads" :data="thread" :selected="thread._id === selectedThreadId" @select="selectThread(thread._id)"></thread-item>

<!-- Selected thread -->
<thread v-if="selectedThread" :id="selectedThreadId"></thread>

Or anywhere else in you Vue component:

computed: {
  count () {
    return this.threads.length;
  }
}

Activating and deactivating meteor data

You can deactivate and activate again the meteor data on the component with this.$startMeteor and this.$stopMeteor:

export default {
  meteor: {
    // ...
  },

  methods: {
    activate () {
      this.$startMeteor()
    },

    deactivate () {
      this.$stopMeteor()
    },
  },
}

You can also prevent meteor data from starting automatically with $lazy:

export default {
  meteor: {
    $lazy: true,
    // ...
  },
}

Freezing data

This option will apply Object.freeze on the Meteor data to prevent Vue from setting up reactivity on it. This can improve the performance of Vue when rendering large collection lists for example. By default, this option is turned off.

// Disable Vue reactivity on Meteor data
Vue.config.meteor.freeze = true;

Next steps


LICENCE ISC - Created by Guillaume CHAU (@Akryum)

About

Use Meteor Tracker reactivity inside Vue components

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%