在 VueJs3 中,为什么我不能从 vue 对象访问数据属性? (它在 Vue2 中有效)
In VueJs3 why can't I access data properties from the vue object? (it worked in Vue2)
背景
我使用 Vue 2 已经很长时间了,目前正在探索 Vue 3 以了解转换我们现有网站需要做些什么。因为这是一个转换,所以我计划使用 Vue 3 的选项界面。在大多数情况下,转换似乎应该是相当轻松的。但是我遇到了一个我觉得很费解的 Vue3 行为。
Vue 2 示例
在 Vue 2 中,如果我有以下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script src="https://unpkg.com/vue@2.5.16/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>
页面加载时,警报如下所示:
这表明在创建 vue 对象后,我可以访问数据属性,就好像它们直接挂在 vue
对象上一样。这是预期的,因为它记录了行为。
但是,Vue 3 对我来说表现不同
这是一段类似的 Vue3 代码,其中包含一些您可能会注意到的额外代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue@3.0.5/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>
加载此页面并显示第一个警告框时,app.count
未定义。
为了进一步探索这一点,您可以在代码中看到我在 created
方法中将 _app
变量的值设置为 this
的值。我显示了第二个负载警报,显示 _app.count
。果然可以正常工作并显示正确的值:
这很有趣。是 Vue 3 数据属性无法直接从 vue 对象访问还是我的代码有问题?如果是设计使然,这似乎是 Vue 2 的一个非常大的变化。所以我希望它不是。
所以问题来了: 为什么我不能在 var app = Vue.createApp
之后通过 app.count
访问 count
?
您还可以在安装应用程序之前访问 属性 :
app._component.data().count
在 Vue 2 中,new Vue()
returns 根组件。
在 Vue 3 中,createApp()
returns application instance, and the root component is returned from the application instance's mount()
:
var app = Vue.createApp({
data() {
return {
count: 101,
}
}
})
var root = app.mount('#appTemplate')
console.log(root.count) // => 101
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue@3.0.5/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 = Vue.createApp({
data: function() {
return {
count: 101
}
},
methods: {
increment: function() {
this.count++;
}
},
created: function(){
_app = this;
}
}
);
var root = app.mount("#appTemplate");
alert("root.count is:" + root.count);
</script>
</body>
</html>
或者,您可以将 mount()
调用链接到 createApp()
:
var app = Vue.createApp().mount('#appTemplate')
console.log(app.count) // => 101
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue@3.0.5/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 = Vue.createApp({
data: function() {
return {
count: 101
}
},
methods: {
increment: function() {
this.count++;
}
},
created: function(){
_app = this;
}
}
).mount("#appTemplate");
alert("app.count is:" + app.count);
</script>
</body>
</html>
背景
我使用 Vue 2 已经很长时间了,目前正在探索 Vue 3 以了解转换我们现有网站需要做些什么。因为这是一个转换,所以我计划使用 Vue 3 的选项界面。在大多数情况下,转换似乎应该是相当轻松的。但是我遇到了一个我觉得很费解的 Vue3 行为。
Vue 2 示例
在 Vue 2 中,如果我有以下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script src="https://unpkg.com/vue@2.5.16/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>
页面加载时,警报如下所示:
这表明在创建 vue 对象后,我可以访问数据属性,就好像它们直接挂在 vue
对象上一样。这是预期的,因为它记录了行为。
但是,Vue 3 对我来说表现不同
这是一段类似的 Vue3 代码,其中包含一些您可能会注意到的额外代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue@3.0.5/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>
加载此页面并显示第一个警告框时,app.count
未定义。
为了进一步探索这一点,您可以在代码中看到我在 created
方法中将 _app
变量的值设置为 this
的值。我显示了第二个负载警报,显示 _app.count
。果然可以正常工作并显示正确的值:
这很有趣。是 Vue 3 数据属性无法直接从 vue 对象访问还是我的代码有问题?如果是设计使然,这似乎是 Vue 2 的一个非常大的变化。所以我希望它不是。
所以问题来了: 为什么我不能在 var app = Vue.createApp
之后通过 app.count
访问 count
?
您还可以在安装应用程序之前访问 属性 :
app._component.data().count
在 Vue 2 中,new Vue()
returns 根组件。
在 Vue 3 中,createApp()
returns application instance, and the root component is returned from the application instance's mount()
:
var app = Vue.createApp({
data() {
return {
count: 101,
}
}
})
var root = app.mount('#appTemplate')
console.log(root.count) // => 101
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue@3.0.5/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 = Vue.createApp({
data: function() {
return {
count: 101
}
},
methods: {
increment: function() {
this.count++;
}
},
created: function(){
_app = this;
}
}
);
var root = app.mount("#appTemplate");
alert("root.count is:" + root.count);
</script>
</body>
</html>
或者,您可以将 mount()
调用链接到 createApp()
:
var app = Vue.createApp().mount('#appTemplate')
console.log(app.count) // => 101
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue@3.0.5/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 = Vue.createApp({
data: function() {
return {
count: 101
}
},
methods: {
increment: function() {
this.count++;
}
},
created: function(){
_app = this;
}
}
).mount("#appTemplate");
alert("app.count is:" + app.count);
</script>
</body>
</html>