Background
I've been using Vue 2 for a long time and am currently exploring Vue 3 to see what converting our existing website will entail. Because this is a conversion I plan to use the options interface for Vue 3. For the most part it seems like the conversion should be fairly painless. But I have encountered one Vue3 behavior that I find very puzzling.
Vue 2 Example
In Vue 2 if I have the following code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
</head>
<body>
<h1>Vue2 app.variable example</h1>
<!-- vue template -->
<div id="appTemplate">
<div style="margin-bottom:20px">Count: <span v-text="count"></span></div>
<button v-on:click="increment()">Increment</button>
</div>
<script type="text/javascript">
//Vue2 Example
var app = new Vue({
el: '#appTemplate',
data: {
count: 101
},
methods: {
increment: function() {
this.count ;
}
},
created: function(){
_app = this;
}
});
alert("app.count is:" app.count)
</script>
</body>
</html>
When the page loads, the alert looks like this:
This demonstrates that after the vue object is created I can access the data properties as though they hang directly off of the vue
object. This is as expected since it's documented behavior.
However, Vue 3 Behaves Differently for Me
Here is a block of analogous Vue3 code with a bit of extra code you will probably notice:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.global.js"></script>
</head>
<body>
<h1>Vue3 app.variable example</h1>
<!-- vue template -->
<div id="appTemplate">
<div style="margin-bottom:20px">Count: <span v-text="count"></span></div>
<button v-on:click="increment()">Increment</button>
</div>
<script type="text/javascript">
//Vue3 OptionsAPI
var _app;
var app = Vue.createApp({
data: function() {
return {
count: 101
}
},
methods: {
increment: function() {
this.count ;
}
},
created: function(){
_app = this;
}
}
);
app.mount("#appTemplate");
//It's really odd that we can't access the property this way:
alert("app.count is:" app.count);
//but this works.
alert("_app.count is:" _app.count);
</script>
</body>
</html>
When this page loads and the first alert box is shown, app.count
is undefined.
To explore this a bit more you can see in the code that I set the value of an _app
variable to the value of this
in the created
method. And I show a 2nd alert on load that displays _app.count
. And sure enough that works and displays the correct value:
So that's pretty interesting. Is it by design in Vue 3 data properties can't be accessed directly from the vue object or is something wrong with my code? It seems like a really big change from Vue 2 if it's by design. So I'd like to hope that it's not.
So here is the question: Why can't I access count
via app.count
after the var app = Vue.createApp
?
CodePudding user response:
In Vue 2, new Vue()
returns the root component.
In Vue 3, createApp()
returns the application instance, and the root component is returned from the application instance's mount()
:
var app = Vue.createApp({
data() {
return {
count: 101,
}
}
})