This guide is currently a work in progress. If you'd like to help out, check out the Contribution Guide to get started!

Introduction

Both Vue and Ember offer solutions to the same types of problems. Both try to offer a good amount out of the box, and aim to have a solution or pattern for most situations. The goal is to abstract away the unimportant differences between apps and reduce friction when switching projects.

Vue allows integration with external services through Vue Plugins. For example, Vue Router, Vuex, and Vue-Apollo are all implemented as a Vue Plugins.

Ember's architectural pattern for dealing with third party services is the Ember Service. Services are used for a lot more than just 3rd party library integrations. A Service is a singleton; it lives for the duration of the application.

Components

Both Ember and Vue use components as the foundational building block for the user interface, and Ember and Vue components have a lot in common. There are a couple important differences between components in the two frameworks you should know about, though!

Before going further, you should familiarize yourself with Ember's Components! Check out the Ember Guides on Components for a deep dive.

The first major difference is that all Vue components are defined using an object literal syntax (whether via Vue.component() or a .vue file), whereas Ember offers class-backed components (which use a JavaScript class) and template-only components (which do not use JavaScript at all).

Another major difference between Vue and Ember components are how the rendered HTML is defined. Both Vue and Ember use templates. Vue templates can be defined in a string when using the Vue.component() method, or in a <template> block when using .vue single-file components. Ember templates are defined in an .hbs file. These templates are executed in a different way as well. The Vue template compiler transforms templates into render functions, so that at runtime a custom JavaScript function is executed. Ember’s Glimmer rendering engine compiles templates into a set of virtual machine opcodes that are executed. There are a number of advantages to this, including performance benefits. One practical implication of this is that Vue templates can contain arbitrary JavaScript, whereas Ember components cannot.

Some of the reasons for using templates that compile to VM instructions rather than to JavaScript are discussed in this video from ReactiveConf. There are other reasons as well, but they are beyond the scope of this guide.

Component Slots

When you want to pass content to a component to be included in that component, Vue provides the slot element.

<!-- components/navigation-link.vue -->
<a v-bind:href="url" class="nav-link">
  <slot></slot>
</a>
<!-- invocation.vue -->
<navigation-link url="/profile">
  Your Profile
</navigation-link>

Ember provides the same functionality with the yield syntax:

<!-- components/navigation-link.hbs -->
<a href={{@url}} class="nav-link">
  {{ yield }}
</a>
<!-- invocation.hbs -->
<NavigationLink @url="/profile">
  Your Profile
</NavigationLink>

When you want your component to pass data to the slot templates provided at the call site, you can use Vue's scoped slots: