-
Notifications
You must be signed in to change notification settings - Fork 546
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 API updates: more details on mounting behavior + replacement for Vue.prototype #117
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,8 @@ Vue.mixin(/* ... */) | |
Vue.component(/* ... */) | ||
Vue.directive(/* ... */) | ||
|
||
Vue.prototype.customProperty = () => {} | ||
|
||
new Vue({ | ||
render: h => h(App) | ||
}).$mount('#app') | ||
|
@@ -44,6 +46,8 @@ app.mixin(/* ... */) | |
app.component(/* ... */) | ||
app.directive(/* ... */) | ||
|
||
app.config.globalProperties.customProperty = () => {} | ||
|
||
app.mount(App, '#app') | ||
``` | ||
|
||
|
@@ -112,6 +116,18 @@ app.mount(App, '#app', { | |
}) | ||
``` | ||
|
||
### Mounting Behavior Difference from 2.x | ||
|
||
When using the compiler-included build and mounting a root component with no template of its own, Vue will attempt to use the mount target element's content as template. Note the differences between the 3.x behavior and 2.x: | ||
|
||
- In 2.x, the root instance uses target element's `outerHTML` as template and replaces target element itself. | ||
|
||
- In 3.x, the root instance uses target element's `innerHTML` as template and only replaces target element's children. | ||
|
||
In most cases this should have no effect on how your app behaves, with the only side effect being that if the target element contains multiple children, the root instance will be mounted as a fragment and its `this.$el` will be pointing to the starting anchor node of the fragment (a DOM Comment node). | ||
|
||
In Vue 3, due to the availability of Fragments, it is recommended to use template refs for direct access to DOM nodes instead of relying on `this.$el`. | ||
|
||
## Provide / Inject | ||
|
||
An app instance can also provide dependencies that can be injected by any component inside the app: | ||
|
@@ -160,6 +176,21 @@ app.config.isCustomElement = tag => tag.startsWith('ion-') | |
|
||
- This will be a new top-level option in the Vue CLI config. | ||
|
||
## Attaching Globally Shared Instance Properties | ||
|
||
In 2.x, it was possible to inject globally shared instance properties by simply attaching them to `Vue.prototype`. | ||
|
||
In Vue 3, since the global `Vue` is no longer a constructor, this is no longer supported. Instead, shared instance properties should be attached to an app instance's `config.globalProperties` instead: | ||
|
||
``` js | ||
// Before | ||
Vue.prototype.$http = () => {} | ||
|
||
// After | ||
const app = createApp() | ||
app.config.globalProperties.$http = () => {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how would we access this inside the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is essentially a legacy escape hatch and not for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This won't work for legacy apps that use multiple instances and apply There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The "legacy" term I used was incorrect - it should be for "options/this-based usage". Even with With the global API change there is no once-for-all global configs anymore. 2.x multi-root-instance apps will have to be updated to configure each root instance individually. If all root instances share the same config, then it can be extracted into a shared function. |
||
``` | ||
|
||
# Drawbacks | ||
|
||
## Plugin auto installation | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there an interface that can be extended to type new properties?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd say just don't use this if using TS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't this be better for people migrating TS projects using libraries that are not adapted yet (or that may never completely adapt) to the inject/provide?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no way to make this work in TS though. If users insist on using this with TS they'd have to shim the types themselves.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah, I just thinking of exposing an interface that can be extended by users to add their own typings