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

Posted

技术标签:

【中文标题】Vue.js 3:当 `data()` 转换为 `setup()` 时,`v-model` 失去响应性【英文标题】:Vue.js 3 : a `v-model` looses reactivity when `data()` converted to `setup()` 【发布时间】:2021-01-12 15:09:52 【问题描述】:

考虑这个基本示例,我们有一个 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>

当您更改输入文本时,它会反映在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>

一个简单的解决方法是refmessage

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>

但是为什么我们必须这样做呢?为什么它不能开箱即用?

我认为这可能是因为从 data() 返回的对象在内部具有反应性,但从 setup() 返回的对象不是因为该对象可能不仅包含数据,还包含不需要观察的方法但是当我查看inputEl.__vueParentComponent.setupState 时,我发现它是Proxy。那么,为什么它不起作用?

【问题讨论】:

很确定这与修补 DOM 有关 【参考方案1】:

return ... 只是将该值暴露给设置函数的外部,您应该始终使用refreactive 使您的数据反应:

setup() 
    const message = Vue.ref("hello world!");
    return 
      message
    ;
  

你可以看到评论 here 上面写着 // 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>

根据setup usage with template:

如果setup返回一个对象,则可以在组件的模板中访问该对象上的属性,以及传入setupprops的属性

结论

setup 函数返回的对象与选项 api 中data 属性返回的对象不同

【讨论】:

以上是关于Vue.js 3:当 `data()` 转换为 `setup()` 时,`v-model` 失去响应性的主要内容,如果未能解决你的问题,请参考以下文章

vue.js怎么把字符串转化为数组

vue.js怎么把字符串转化为数组

Vue.js - 当标头中使用 multipart/form-data 时,axios 中的文件上传验证失败

如何使用Google自动完成和Vue js来自动填写地址?

Vue.js - 强制过滤器应用程序

当 API 返回空数据时显示警告(Vue.js / Axios)