Skip to content

Applications, root components and Vue instances #345

Closed
@skirtles-code

Description

@skirtles-code

Apologies if I'm jumping the gun but here are some thoughts I had while reading the beta docs. They're all closely related so I've put them all in a single issue.

The Quick Summary is a brief outline of some specific problems. The Deeper Dive section attempts to explain and elaborate.

Quick Summary

  1. Link
    In various places there are examples like Vue.createApp(HelloVueApp). I think the App suffix is potentially confusing and it would be better to write these examples as Vue.createApp(HelloVue) instead.
  2. Link
    I think the line const app = Vue.createApp() is supposed to be const app = Vue.createApp(App). That said, as I mentioned in point 1 above, I would argue it'd be better to call App something else in the examples.
  3. Link
    The API Reference for the provide method of the Application API is documenting the wrong thing. Currently it's documenting the provide option from the Component Options API.
  4. Link
    The migration example app.provide({ [ThemeSymbol]: theme }) won't work. It would need to be app.provide(ThemeSymbol, theme) instead. I'm unclear whether this is a documentation problem or a library bug. The original RFC suggested that passing an object to app.provide would be supported but that isn't how it's currently implemented.
  5. Link
    The use of the word 'root' seems misleading in the line 'That means they can be used in the template of any root Vue instance created after registration.'. Instead, perhaps it could be something like: 'Once registered they can be used in the template of any component within the current application.'?
  6. Link
    The current Vue 3 documentation seems to be using the term Vue instance interchangeably to describe both an application instance and a component instance. I think a clear distinction should be made between the two. My suggestion would be to avoid using the term Vue instance altogether.

Deeper Dive

Applications and Root Components

Consider the following example (my example, not one from the docs):

const rootComponentOptions = {
  data: () => ({ count: 1 })
}

const app = Vue.createApp(rootComponentOptions)
const vm = app.mount('#app')

There are 3 important and distinct objects created here:

  • rootComponentOptions, which contains the configuration options for the root component instance.
  • app, which is an application instance.
  • vm, which is the root component instance.

I think it's important for the documentation not to blur the lines between these 3 things.

There is some historical baggage here. Most Vue 2 applications have an entry-point component called App.vue, so it
seems natural to write Vue.createApp(App) in Vue 3. While that may not be wrong, I think it would be clearer for the
examples to avoid using the word App for the argument when calling createApp.

I'm not suggesting trying to explain the subtle distinctions right at the start of the documentation, that would likely
overwhelm new users. However, I think it would be better for the early examples to use non-committal names rather than
names that might be actively misleading. For example, something like Vue.createApp(TodoList).

Imagine for a moment that you're a new Vue user. Then consider the following line:

const app = Vue.createApp(options)

What would you guess that options is, assuming you didn't already know? I think most people would guess that options
is an object containing configuration options for the application. But it isn't, it's the root component options.

Of course users shouldn't be guessing, they should read the documentation. My point is that the natural assumption about
options is wrong, so the documentation has to be extra careful not to reinforce that potential misunderstanding.

Now consider the following two examples:

Vue.createApp({
  components: { MyButton },
  directives: { MyDirective },
  mixins: [ MyMixin ],
  provide: { name: 'John Doe' }
}).mount('#app')
Vue.createApp({})
  .component('MyButton', MyButton)
  .directive('MyDirective', MyDirective)
  .mixin(MyMixin)
  .provide('name', 'John Doe')
  .mount('#app')

If you didn't know better you might assume that those are effectively the same thing: two different ways of configuring
the same application. To compound the potential for confusion, if our hypothetical Vue newbie were to try this with a
very simple application then there's a good chance that it would work either way. The difference between configuring the
root component and configuring the application can be quite subtle when you only have a couple of components.

One thing that might help would be for the API Reference for each of these options/methods to mention the other one and
note the difference between them.

Vue Instances

In Vue 2 it was clear what a 'Vue instance' was. I'm not sure it's so clear in Vue 3.

Some of the documentation seems to be using the term Vue instance to refer to both an application instance and a
component instance.

A quick search through the vue-next source code suggests that the term component instance is being used in warning
messages.

My suggestion would be to remove the term Vue instance from the documentation and instead use component instance
or application instance depending on which is appropriate in the given circumstances. Both of these terms are already in use in the documentation and they seem less ambiguous to me.

Metadata

Metadata

Labels

discussionTopics to discuss that don't have clear action items yetenhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions