[英]Vue.js 3 : a `v-model` looses reactivity when `data()` converted to `setup()`
Consider this basic example where we have an input
and a p
that shows the value of the input:考虑这个基本示例,其中我们有一个
input
和一个显示输入值的p
:
const App = { data() { return { message: "hello world!" }; } }; Vue.createApp(App).mount('#root');
<script src="https://unpkg.com/vue@next"></script> <div id="root"> <input v-model="message"/> {{ message }} </div>
When you change the input text it is reflected in the content of the p
.当您更改输入文本时,它会反映在
p
的内容中。 But if you replace data()
with setup()
, the changes to input
are no longer reflected in p
:但是,如果您将
data()
替换为setup()
,则input
的更改将不再反映在p
:
const App = { setup() { return { message: "hello world!" }; } }; Vue.createApp(App).mount('#root');
<script src="https://unpkg.com/vue@next"></script> <div id="root"> <input v-model="message"/> {{ message }} </div>
A simple fix is to ref
the message
:一个简单的解决方法是
ref
message
:
const App = { setup() { const message = Vue.ref("hello world!"); return { message }; } }; Vue.createApp(App).mount('#root');
<script src="https://unpkg.com/vue@next"></script> <div id="root"> <input v-model="message"/> {{ message }} </div>
But why we have to do it?但是为什么我们必须这样做呢? Why it doesn't work out of the box?
为什么它不能开箱即用?
I thought it might be because the object returned from data()
is made reactive internally but the object returned from setup()
doesn't because that object might contain not only data but also methods that don't need to be observed but when I check inputEl.__vueParentComponent.setupState
I see that it's a Proxy
.我认为这可能是因为从
data()
返回的对象在内部是反应性的,但从setup()
返回的对象不是因为该对象可能不仅包含数据还包含不需要观察的方法,但是当我检查inputEl.__vueParentComponent.setupState
我看到它是一个Proxy
。 So, why it doesn't work?那么,为什么它不起作用?
return {...}
just exposes that values to the outside of setup function, you should always use ref
or reactive
to make your data reactive : return {...}
只是将这些值暴露给 setup 函数的外部,您应该始终使用ref
或reactive
来使您的数据具有反应性:
setup() {
const message = Vue.ref("hello world!");
return {
message
};
}
You could see the comment here that says // expose to template
:您可以在此处看到
// expose to template
的注释:
<template>
<div>{{ count }} {{ object.foo }}</div>
</template>
<script>
import { ref, reactive } from 'vue'
export default {
setup() {
const count = ref(0)
const object = reactive({ foo: 'bar' })
// expose to template
return {
count,
object
}
}
}
</script>
And according to setup usage with template :并根据模板的设置用法:
If
setup
returns an object, the properties on the object can be accessed in the component's template, as well as the properties of theprops
passed intosetup
如果
setup
返回一个对象,则可以在组件的模板中访问该对象的属性,以及传递给setup
的props
的属性
Conclusion结论
the object returned in setup
function is different than that return from data
property in option api setup
函数中返回的对象与选项 api 中data
属性的返回不同
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.