Init: Meteor & Blaze + VueJS

Continuing the discussion from Another Bye-Bye post:

Thanks for this. But would it possible to use the akryum:vue package in an existing Blaze/FlowRouter application?

My goal would be to migrate screens over to Vue when I can. As for new screens, would I would use Vue only.

I know there is some issues with Vue and FlowRouter (and it is recommended to use VueRouter), but I can’t abandon FlowRouter right now. Also, these issues with FlowRouter should be negated because I don’t pass parameters over the URL and do not use nested URL either.

Response to the beginning post from @M4v3R:

Thanks.

I’d rather have a clean break for new screens, so instead of wrapping Vue components inside a templates like your example here:

Template.vue_demo.rendered = function() {
  var vm = new Vue({
    el: '#vue-demo',
    template: '<div><widget></widget></div>',
    components: {
      Widget
    }
  });
}

I’d rather FlowRouter call a Vue only page. What would this look like?

That would be tricky to accomplish, because you need to mount the Vue component to some existing HTML element. In this example there is a root component which is hooked up to <body> element, and then FlowRouter loads specific components (here it’s done lazily with the use of Webpack, but it doesn’t need to be this way).

To be honest I think it would overcomplicate things to include Vue in your existing Blaze app if you want to do it this way. It’s much easier when you start fresh and use Vue exclusively, but I understand that it’s not always possible.

@akryum had some ideas:

If the route is a Blaze one, just do as you do now with Blaze. Else, use a root Vue component containing a <component :is="def"> to dynamically change the display component definition.
Let’s say you have two Vue components, Page1.vue and Page2.vue. You can add two routes that have some special info that tells they are vue routes. Then, you can display the root component mentioned above and then change the def property depending on the route to display either Page1.vue or Page2.vue.

// Reset (so the vue page is not displayed on Blaze pages
FlowRouter.triggers.enter(() => {
  renderVuePage(null);
});

// Example Vue Page
import Page1 from 'Page1.vue'
FlowRouter.route('/page1', {
    action: function(params) {
        renderVuePage(Page1);
    }
});

// Vue instance to store reactive data globally
export const routerInfo = new Vue({
  data: {
    def: null
  }
})

function renderVuePage(def) {
  routerInfo.def = def
}

Root Vue:

<template>
  <div class="vue-page" v-if="def">
    <component :is="def"></component>
  </div>
</template>

<script>
import { routerInfo } from '/routes'

export default {
  computed: {
    def () {
      return routerInfo.def
    }
  }
}
</script>
1 Like

I have one big application right now, but I could break it into two. One side is admin, the other is users. I could break out the admin side for now and rewrite it in Vue and Meteor.

The main obstacle with this is that the admin currently have the ability to “impersonate” a user – basically with the press of a button on a user’s overview page, the admin can log in the application as that user – and see exactly what they see. I don’t see how I could do something like this if I have two separate applications.

@akryum, I see you’ve also built a Vue + Apollo lib https://github.com/Akryum/vue-apollo. Isn’t Apollo still under extreme development? Aren’t its API in constant flux at the moment? How comfortable would you be basing a client facing, production product, on Apollo + Vue 2.0 and your library?

Not that it matters, but I would be splitting my application out into two projects – one side would be admin and the other side would be the old Meteor+Blaze+FlowRouter. And could I set something up where the admin could log into the other site as the user?

Also, why Apollo over straight GraphQL + Vue?

Also, is there a way to use Apollo or GraphQL AND keep reactivity like I’m use to in Meteor?

That’s how I would do it. If you look at akyrum’s meteor-vue-component repo you’ll see that all it does is build .vue files into a single JS Vue component so that you can import it like this

import Post from '/imports/ui/Post.vue';
Vue.component('post', Post);

These can easily be imported anywhere in your Meteor app and rendered when you want. If you look at the Vue dynamic component docs, you’ll see that you still need to import a component to be able to use it dynamically. So using your approach above it would look like this

<template>
  <div class="vue-page" v-if="def">
    <component :is="def"></component>
  </div>
</template>

<script>
import { routerInfo } from '/routes'
import { RouteView1 } from './routes/route-view-1';
import { RouteView2 } from './routes/route-view-2';

export default {
  components: {
     RouteView1,
     RouteView2
  },
  computed: {
    def () {
      return routerInfo.def
    }
  }
}
</script>

and routerInfo.def would have to equal "routeView1", "routeView2" etc

1 Like

Thanks for the feedback @efrancis. For a green field project with Meteor + VueJS + meteor-vue-component + vue-meteor-tracker.

``> Should I remove Blaze templates? Did you keep Blaze templates package in order to have access to Meteor Accounts?

``> What Router are you using?

``> What obstacles have you faces over a regular Meteor + Blaze + FlowRouter project so far?

Hi, In my point of view

  • I will exactly delete the Blaze if i am you because it look like i am using both rendering engine to do same thing. For Meteor accounts, i am not worry about it because most of the time im not using accounts-ui for login purpose with or without blaze. i will just add accounts-password and create my own ui.

  • I am using vue-router right now and work without problem right now.

  • i cant give you my opinion because i am not using Meteor + Blaze + FlowRouter.

Hope it help you.

1 Like

The biggest obstacle for people used to working with Blaze will probably turn out the lack of a good alternative for Autoform package. There are forms validation packages available, but none of them does the amount of magic Autoform did.

Probably it’s working fine if you keep Blaze, but you lose hot module reload, time-travel debugging and it obviously won’t work with Vue-devtools (Chrome extension) and Veex (Vue Native).

React folks got used to live without Autoform, so I will too.

Speaking of which, what do you use for forms in Vue? Do you use any alternative library, do you do everything by yourself?

This was my next addition to this fp-admin repo. Well, I mean I would build a form, with reactive validation, etc. I think if I can get a good/stable pattern for client side reactive form validation I’ll be fine. I use Autoform now, but don’t mind ditching it as long as I can get said validation working. The real gem is SimpleSchema (which I use a lot). Can we use SimpleSchema with VueJS or is there a substitute?

Also, I’m going to be working through the Accounts Login link you sent as well.

I’m not really using any of that yet, maybe I’ll build up to it in Vue. Right now I’m trying to build out a Meteor + VueJS foundation I can work with long term.

Yes, we can use either SimpleSchema or Astronomy with VueJS.

Another obstacle that I notice is the amount of Vue related projects in which Github issues are all in Chinese. Some of them are very interesting, but what happens when I get stuck because of some issue and won’t be able to check if there is some temporary solution for that, or even be able to confirm it actually is a bug?

1 Like

Has anyone used https://vuejs.org/v2/api/#props to do type checking, custom validation, and default values?

I rarely pass stuff through the props because I keep the state in Vuex, but the stuff you mentioned is working for me and it’s nice to use, the console messages are very helpful.

I’ll be playing with smart/dumb components approach in Vue soon, so probably will utilize this more often.

The real question is, why not use vue directly?:slight_smile:

Depends, what do you mean by using Vue directly? In what context?

If you mean using Vue directly instead of trying to take advantage of Simple Schema, the answer would be - because you won’t use Vue on the server side. You can’t take advantage of your Vue code on the server, but you can take advantage of your server side code on your client. And that’s better than writing same thing twice.