├── README.md ├── package.json └── vue-meteor-data.js /README.md: -------------------------------------------------------------------------------- 1 | #Vue Meteor Data 2 | 3 | ##Easy subscriptions and reactive queries for Vue and Meteor 4 | 5 | When a view is created, the mixin iterates through your reactive data and wraps it individually in Vue's vm.$watch. Then each of these wrappers are wrapped in Meteor's Tracker.autorun. 6 | 7 | 8 | ####Installation 9 | ```javascript 10 | var VueMeteorData = require ('vue-meteor-data') 11 | Vue.mixin(VueMeteorData) 12 | ``` 13 | 14 | 15 | ####Usage example 1 16 | ```javascript 17 | module.exports = { 18 | reactiveData : { 19 | tasks: function () { 20 | return Tasks.find().fetch() 21 | } 22 | }, 23 | created: function(){ 24 | this.subscribe('tasks/all') 25 | } 26 | } 27 | ``` 28 | 29 | 30 | ####Usage example 2 31 | ```javascript 32 | module.exports = { 33 | created: function(){ 34 | this.subscribe('tasks/all') 35 | this.autorun(function(){ 36 | this.$set('tasks', Tasks.find().fetch()) 37 | }.bind(this)) 38 | } 39 | } 40 | ``` 41 | 42 | 43 | ####Usage example 3 with VueRouter 44 | ```javascript 45 | module.exports = { 46 | reactiveData : { 47 | tasks: function () { 48 | return Tasks.find(this.$route.params.id).fetch() 49 | } 50 | }, 51 | created: function(){ 52 | this.subscribe('tasks/all') 53 | } 54 | } 55 | ``` 56 | 57 | 58 | ####Usage example 4 59 | ```javascript 60 | module.exports = { 61 | reactiveData : { 62 | tasks: function (vm) { 63 | console.log(vm === this) //returns true 64 | } 65 | } 66 | } 67 | ``` 68 | 69 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-meteor-data", 3 | "version": "1.0.6", 4 | "description": "Easy subscriptions and reactive queries for Vue and Meteor", 5 | "main": "vue-meteor-data.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/Grottolabs/vue-meteor-data.git" 9 | }, 10 | "keywords": [ 11 | "vue", 12 | "meteor", 13 | "reactivity", 14 | "subscriptions", 15 | "collections" 16 | ], 17 | "author": { 18 | "name": "Jakob Rosenberg" 19 | }, 20 | "license": "ISC", 21 | "bugs": { 22 | "url": "https://github.com/Grottolabs/vue-meteor-data/issues" 23 | }, 24 | "homepage": "https://github.com/Grottolabs/vue-meteor-data#readme", 25 | "readmeFilename": "README.md", 26 | "_id": "vue-meteor-data@1.0.4", 27 | "scripts": {}, 28 | "_shasum": "cc9f65b09f2353f834e01de6227d6626173816d6", 29 | "_from": "vue-meteor-data@*", 30 | "gitHead": "e0e67c219dacfdecec80bf415ba7e742d182bf94" 31 | } 32 | -------------------------------------------------------------------------------- /vue-meteor-data.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Easy subscriptions and reactive queries for Vue and Meteor 3 | * 4 | * Installation: 5 | * var VueMeteorData = require ('vue-meteor-data'); 6 | * Vue.mixin(VueMeteorData) 7 | * 8 | * Usage example 1: 9 | * module.exports = { 10 | * reactiveData : { 11 | * tasks: function () { 12 | * return Tasks.find().fetch() 13 | * } 14 | * }, 15 | * 16 | * created: function(){ 17 | * this.subscribe('tasks/all'); 18 | * } 19 | * } 20 | * 21 | * Usage example 2: 22 | * module.exports = { 23 | * created: function(){ 24 | * this.subscribe('tasks/all'); 25 | * this.autorun(function(){ 26 | * this.$set('tasks', Tasks.find().fetch()) 27 | * }.bind(this)) 28 | * } 29 | * } 30 | */ 31 | var Vue = require('vue') 32 | 33 | module.exports = { 34 | 35 | created: function () { 36 | var vm = this; 37 | this._trackerHandles = []; 38 | 39 | /** 40 | * Wrap all queries in Tracker.autorun 41 | * Usage example: 42 | * reactiveData: { 43 | * tasks: function (component) { 44 | * this.subscribe('myPubliation'); 45 | * return Tasks.find().fetch() 46 | * } 47 | * } 48 | */ 49 | var reactiveData = this.$options.reactiveData 50 | if (reactiveData) { 51 | for (var key in reactiveData) { 52 | var reactiveFunction = reactiveData[ key ].bind(vm); 53 | Vue.util.defineReactive(vm, key, null); 54 | (function(key, reactiveFunction){ 55 | vm.autorun(function () { 56 | vm.$set(key, reactiveFunction(vm)); 57 | }); 58 | })(key, reactiveFunction); 59 | } 60 | } 61 | }, 62 | 63 | destroyed: function () { 64 | //Stop all reactivity when view is destroyed. 65 | this._trackerHandles.forEach(function (tracker) { 66 | tracker.stop(); 67 | }) 68 | }, 69 | 70 | 71 | methods: { 72 | /** 73 | * Subscription that automatically stop when view is destroyed 74 | * Usage example: 75 | * created: function(){ 76 | * this.subscription("myPublication") 77 | * } 78 | * @returns {*} 79 | */ 80 | subscribe: function () { 81 | var handle = Meteor.subscribe.apply(this, arguments); 82 | this._trackerHandles.push(handle); 83 | return handle; 84 | }, 85 | 86 | 87 | /** 88 | * Autorun - automatically stops when view is destroyed 89 | * 90 | * Usage example: 91 | * created: function(){ 92 | * var handle = this.autorun(function(){ 93 | * this.myvar = myReactiveFunction(); 94 | * }.bind(this); 95 | * ... 96 | * handle.stop(); 97 | * } 98 | * @param reactiveFunction 99 | * @returns {{_meteor: Tracker.Computation, _vue: Function, stop: handle.stop}} 100 | */ 101 | autorun: function (reactiveFunction) { 102 | var vm = this; 103 | 104 | var handle = { 105 | _meteor: {}, //placeholder 106 | _vue : function () { 107 | }, //placeholder 108 | stop : function () { 109 | this._meteor.stop(); 110 | this._vue(); 111 | } 112 | }; 113 | 114 | 115 | handle._meteor = Tracker.autorun(function () { 116 | 117 | //calls watcher.teardown() to avoid creation of duplicate watchers 118 | handle._vue() 119 | 120 | handle._vue = vm.$watch(reactiveFunction) 121 | 122 | }); 123 | 124 | this._trackerHandles.push(handle); 125 | 126 | return handle; 127 | } 128 | 129 | } 130 | 131 | } 132 | --------------------------------------------------------------------------------