Consider this basic example where we have an input
and a p
that shows the value of the input:
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
. But if you replace data()
with setup()
, the changes to input
are no longer reflected in 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
:
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
. So, why it doesn't work?
return {...}
just exposes that values to the outside of setup function, you should always useref
orreactive
to make your data reactive :You could see the comment here that says
// expose to template
:And according to setup usage with template :
Conclusion
the object returned in
setup
function is different than that return fromdata
property in option api