简体   繁体   English

Vue.js 3:当 `data()` 转换为 `setup()` 时,`v-model` 失去反应性

[英]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 函数的外部,您应该始终使用refreactive来使您的数据具有反应性:

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 the props passed into setup如果setup返回一个对象,则可以在组件的模板中访问该对象的属性,以及传递给setupprops的属性

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM