Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Global mounting/configuration API change #29

Merged
merged 5 commits into from Nov 12, 2019
Merged

Conversation

yyx990803
Copy link
Member

@yyx990803 yyx990803 commented Apr 9, 2019

Before

import Vue from 'vue'
import App from './App.vue'

Vue.config.ignoredElements = [/^app-/]
Vue.use(/* ... */)
Vue.mixin(/* ... */)
Vue.component(/* ... */)
Vue.directive(/* ... */)

new Vue({
  render: h => h(App)
}).$mount('#app')

After

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)

app.config.ignoredElements = [/^app-/]
app.use(/* ... */)
app.mixin(/* ... */)
app.component(/* ... */)
app.directive(/* ... */)

app.mount('#app')

Rendered

@yyx990803 yyx990803 added 3.x This RFC only targets 3.0 and above breaking change This RFC contains breaking changes or deprecations of old API. core labels Apr 9, 2019
@Kocal
Copy link

Kocal commented Apr 9, 2019

Nice, mutating Vue app instances instead of global Vue instance is SO much better! 👍

@jacekkarczmarczyk
Copy link

Is there a reason for initializing app with the component? I'd see rather something like

import { createApp } from 'vue'
import App1 from './App1.vue';
import App2 from './App2.vue';

const app = createApp();
app.use(...);
...

app.mount('#app-1', App1);
app.mount('#app-2', App2);

That would allow to reuse the app object in some cases (but still you can create separate apps if you don't want to share anything)

@ycmjason
Copy link

ycmjason commented May 30, 2019

@jacekkarczmarczyk

But conceptually shouldn't app contains only one "app"?

app.mount('#app-1', App1);
app.mount('#app-2', App2);

This seems rather counter intuitive. Perhaps it's the naming.

If you wish to use the same config in both apps, I reckon you can do something like:

import { createApp } from 'vue'
import App1 from './App1.vue';
import App2 from './App2.vue';

const createMyApp = (component) => {
  const app = createApp(component);

  app.config.ignoredElements = [/^app-/]
  app.use(/* ... */)
  app.mixin(/* ... */)
  app.component(/* ... */)
  app.directive(/* ... */)

  return app
};

createMyApp(App1).mount('#app-1');
createMyApp(App2).mount('#app-2');

In this case you gain more flexibility too over what config to use on each app.

@MichMich
Copy link

Are the app methods chainable? It would be great if we could write:

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)

app.config.ignoredElements = [/^app-/]
app.use(/* ... */)
  .mixin(/* ... */)
  .component(/* ... */)
  .directive(/* ... */)
  .mount('#app')

And since I don't use the igoneElements feature, this could be simplified to:

import { createApp } from 'vue'
import App from './App.vue'

createApp(App)
  .use(/* ... */)
  .mixin(/* ... */)
  .component(/* ... */)
  .directive(/* ... */)
  .mount('#app')

@jacekkarczmarczyk
Copy link

jacekkarczmarczyk commented May 30, 2019

@ycmjason I'm not sure whether an app should handle only one app, but that's also the point of discussion. But you're right that if it can handle more apps than the naming might be a subject to change

In this case you gain more flexibility too over what config to use on each app.

I don't agree with this, because my propsal allows you to use a separate apps/configs or shared one depending on your needs, your solution still doesn't allow to share the config.


Another question (not related to this topic) is where do we put Vuex or Router here?
app.mount('#app', { store }) or createApp(App, { store }) or we don't do it here at all?

@MichMich
Copy link

For me it would make more sense to use:

createApp({ store, router })
  .use(/* ... */)
  .mixin(/* ... */)
  .component(/* ... */)
  .directive(/* ... */)
  .mount('#app', App)

@yyx990803 yyx990803 added the final comments This RFC is in final comments period label Nov 6, 2019
@yyx990803
Copy link
Member Author

This RFC is now in final comments stage. An RFC in final comments stage means that:

  • The core team has reviewed the feedback and reached consensus about the general direction of the RFC and believe that this RFC is a worthwhile addition to the framework.
  • Final comments stage does not mean the RFC's design details are final - we may still tweak the details as we implement it and discover new technical insights or constraints. It may even be further adjusted based on user feedback after it lands in an alpha/beta release.
  • If no major objections with solid supporting arguments have been presented after a week, the RFC will be merged and become an active RFC.

- remove config.productionTip
- replace config.ignoredElements with config.isCustomElement
@yyx990803 yyx990803 merged commit bed289b into master Nov 12, 2019
Copy link

@cuongdevjs cuongdevjs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool

@Akryum
Copy link
Member

Akryum commented Nov 22, 2019

Was thinking this will allow the devtools to inject a proper Vue app into the page instead of hand-made DOM manipulations (for the Component overlay for example).

@lassemettovaara
Copy link

I have some apps where there's no root component, is this sort of setup still possible with the new API? Couldn't figure out how to replicate this with the 3.0 alpha version.

import Vue from "vue";
import MyComponent from "@/MyComponent.vue";
import MyOtherComponent from "@/MyOtherComponent.vue";

Vue.component("my-component", MyComponent);
Vue.component("my-other-component", MyOtherComponent);

new Vue({
  el: "#app"
});
<div id="app">
  <div>
    <p>Some none-Vue stuff here.</p>
    <my-component foo="bar />
  </div>
  <my-other-component :foo="true" />
</div>

@yyx990803 yyx990803 deleted the global-api-change branch January 20, 2020 14:50
@yyx990803 yyx990803 restored the global-api-change branch January 20, 2020 14:50
@yyx990803
Copy link
Member Author

yyx990803 commented Jan 20, 2020

@lassemettovaara no, and I'd say don't do that. Importing a component should not have global side effects (registering global components). I misread your example. Yes, you should be able to simply mount an empty root component with no template:

import { createApp } from 'vue'

createApp().mount({}, '#app')

@lassemettovaara
Copy link

@lassemettovaara no, and I'd say don't do that. Importing a component should not have global side effects (registering global components). I misread your example. Yes, you should be able to simply mount an empty root component with no template:

import { createApp } from 'vue'

createApp().mount({}, '#app')

Thanks, that looks just like I expected it would work.

At the moment (in 3.0.0.-alpha.2) mounting an empty root component without a template just clears the host element on the page and throws a warning about a missing render function. Is this down to this just not being implemented yet, or does it look like a bug?

Screenshot 2020-01-21 at 15 16 11

@yyx990803
Copy link
Member Author

@lassemettovaara if you are using the webpack-based setup, then you are importing the runtime-only build by default, which does not support compiling DOM templates on the fly. I would suggest just migrate to use a root component so that you don't ship the compiler to the browser just for that.

The mentioned usage only works when you are using the full build.

@zero7u
Copy link

zero7u commented May 8, 2020

这种设计非常棒,从设计上支持了多实例,方便前端做模块隔离,一个应用是一个沙盒,对大项目微服务化有了很好的支持,避免巨石的产生。

建议,从接口层面,增加实例间的互动,如通讯、状态共享等特性;从构建层面支持多实例的代码复用,包共享等。


This design is very good. It supports multiple instances from the design, which is convenient for the front-end to do module isolation. An application is a sandbox, which has a good support for micro service of large projects and avoids the generation of boulders.

It is suggested to increase the interaction between instances from the interface level, such as communication, state sharing and other features; support multi instance code reuse, package sharing and so on from the webpack level.

@yyx990803 yyx990803 added feat: global api Changes related to global API and removed final comments This RFC is in final comments period labels Jul 1, 2020
@bencodezen bencodezen mentioned this pull request Jul 6, 2020
25 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.x This RFC only targets 3.0 and above breaking change This RFC contains breaking changes or deprecations of old API. core feat: global api Changes related to global API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants