liuliancc
V2EX  ›  Vue.js

求助 Vue 大佬,为什么使用 reactive 数据没有双向绑定?

  •  
  •   liuliancc · Jul 21, 2025 · 6129 views
    This topic created in 474 days ago, the information mentioned may be changed or developed.

    萌新小白请教,不太明白为什么使用 ref 数据可以双向绑定,使用 reactive 数据无法双向绑定?是我用法不对吗?
    到底什么时候应该使用 ref 什么时候应该使用 reactive 呢?

    https://play.vuejs.org/#eNp9U8Fu00AQ/ZXRXmJEsIVAHCInElQ9wAEqijj54tqTdMt6d2Wv3UCUOzeEOMAHIHFC8AP8De13MDubpNu09GLtzrx582b9ZiWeWpsOPYqJyLuqldZBh663s0LLxprWwQpanI/pU1ZODghrmLemgREVjXagA9PYTTzN/MVzUrrQWQaV0R3RuvcKD4yeywVMPWey4izMjXbH8gNO4OETjqzvFfr2miDBF+6X+Zo8CxOQdro4bKwqHdINILcwYbJpIVZRadQg3UbhPozscrQuxOzy4+fLb78ufn79++dLnvlHISqedXjQmBoV0UUUhYCMMHkW9RZj4Tqaxnc464ymh2b5haiIRypsX1knadpCTIAzPlcqZc5fcMy1PY638eoUq3e3xM+6pY8V4qjFDtsBC7HLubJdoAvpw+OXuKTzLklT9IrQdyRfY2dU7zUG2LNe1yQ7wrHa5+wEqRdvusOlQ91th/JCPXLN+EKQM/wT/m/0K7mP0sdcR3+XXnHrqn2ngir1gv6DI5rrrg1uGcN56arTPd8SUDts52WFcBy5bM9aum9OaFRNGuKKo9bYLmDZBm9L1RM6IuKSYGLL4CnUOJcauTTn7ywh08a0h410G9qE6Ea9rclEk6sWozEMN1rdm8BgZB11ROLZNWTSnL+bhgGkTFWqG7uVR8SzZAVpmrL+9EoE72eh+VWTiGUMicbzjSaYzsIgXkty6yRMvqtg1rWP1og2uIZjd211LQc+0FGVJ6hmYVUvvv+4+P0pz0JsA5Da9i7a20j5bvU3C0zoLFBfX+X1P0Ky0Q8=

    直接展示代码:

    App.vue

    <script setup>
    import { ref, reactive } from 'vue'
    import Comp from './Comp.vue'
    
    // const styleConfig = ref({
    //  fontSize: 16
    // })
    const styleConfig = reactive({
      fontSize: 16
    })
    </script>
    
    <template>
      <p :style="{ fontSize: styleConfig.fontSize + 'px'}">我是字体</p>
      <Comp v-model="styleConfig" />
    </template>
    
    

    Comp.vue

    <script setup lang="ts">
    import { reactive, watch } from 'vue'
    
    interface StyleConfig {
      fontSize: number
    }
    
    interface Props {
      modelValue: StyleConfig
    }
    const props = defineProps<Props>()
    
    interface Emits {
      (e: 'update:modelValue', value: StyleConfig): void
    }
    const emit = defineEmits<Emits>()
    
    const localConfig = reactive<StyleConfig>({ ...props.modelValue })
    
    watch(localConfig, (newConfig) => {
      emit('update:modelValue', { ...newConfig })
    }, { deep: true })
    </script>
    
    <template>
      <div>
        <label>字体大小</label>
        <input v-model="localConfig.fontSize" />
      </div>
    </template>
    
    18 replies  •  2025-07-24 10:15:38 +08:00
    WJYuan
    WJYuan
    Jul 21, 2025❤️1
    1
    用法不对,reactive 不能直接替换整个对象
    https://cn.vuejs.org/guide/essentials/reactivity-fundamentals.html
    coli
    coli
    Jul 21, 2025❤️1
    2
    举个简单的例子吧:

    ```javascript
    const a = reactive({ b: 1 });
    // some logics ...
    a = { b: 123 };
    ```

    结果会报错,因为你在尝试把 `const` 定义的值赋值为另外一个值。

    而 `<Comp v-model="styleConfig" />` 的语法糖等效为:

    ```vue
    <Comp :modelValue="styleConfig" @update-modelValue="(newVal) => styleConfig = newVal" />
    ```

    这边 `styleConfig = newVal` ,看出问题了吧?

    ---

    而用 `ref` 没问题是因为,ref 用了一层 `.value` 包裹起来,这样你把原来整个对象覆盖掉,改到的都是 `.value` ,而不是 `styleConfig` 这个对象本身。

    不过看原来的代码,把 `v-model="styleConfig.fontSize"` 传出去就好了,这么绕除非你想要用到 `styleConfig` 的其他属性……

    ---

    PS:Vue3 可以用 `defineModel` 写,用起来很爽。

    ---

    PPS: 这也是个 JS 对象地址的问题:

    ```javascript
    const a = [ { x: 1 }, { y: 2 }, { z: 3 } ];
    const b = a[0];
    a[0].x = 2;
    console.log(b); // => { x: 2 }
    a[0] = { x: 3 };
    console.log(b, a[0] === b); // => { x: 2 } , false
    ```
    xuhuanzy
    xuhuanzy
    Jul 21, 2025 via Android
    4
    reactive 解构后的对象是原始值而不是代理对象。
    liuliancc
    liuliancc
    OP
    Jul 21, 2025
    5
    感谢各位大佬解惑
    liwenka1
    liwenka1
    Jul 22, 2025
    6
    应该使用 ref 什么时候应该使用 reactive 呢?
    只使用 ref 即可,虽然要不断的使用 .value 会比较繁琐,但是可以更好的区分响应式数据和非响应式数据
    wangtian2020
    wangtian2020
    Jul 22, 2025
    7
    reactive 出错时 ref 一定不会出错,弄不明白就一直用 ref 完事儿,.value 一定触发更新
    gogogo2000
    gogogo2000
    Jul 22, 2025
    8
    js 的对象无论是 getter/setter 还是 proxy 都是一个对象,你直接把对象给替换了,当然就无法监听变化了
    ref 无论你怎么替换,实际上你置换的都是对象的.value 值。

    基本上你可以理解为 ref=reactive{ value: ??? },所以使用 ref 时,ref 对象本身永久都不会变,自然总是可以监听到变动
    hamwong
    hamwong
    Jul 22, 2025
    9
    没用过 reactive ,ref 一把梭
    erwin985211
    erwin985211
    Jul 22, 2025
    10
    这种问题直接丢给 ai 就行了
    johnnyyeen
    johnnyyeen
    Jul 22, 2025
    11
    官方文档有详细说明
    MIUIOS
    MIUIOS
    Jul 22, 2025
    12
    @erwin985211 每次看到这种无意义的评论就很烦,人家正儿八经问问题非要来一句这种问题直接丢给 ai 就行了,AI 要是能帮楼主解决了楼主还跑来这问人?人家一句话就给解惑了, 换成 AI ,给你输出一大堆文字你还要在里面找到最重要的信息,到头来还是一头雾水
    erwin985211
    erwin985211
    Jul 23, 2025
    13
    @totoro52 他这么具体的问题为什么不能问 ai ?? ,我不知道 up 是不是问过 ai ,但是我的把它的帖子原封不动丢给 ai 很明确的就得出结论了。你发问题就一定有人回答吗,回答的人的质量就一定高吗。ai 是能够训练了。凭什么说我的回答没意义,如果 up 想我一样直接问题 ai 它的疑问早就解决了。
    univ
    univ
    Jul 23, 2025
    14
    统一用 ref
    zhj0326
    zhj0326
    Jul 23, 2025
    15
    使用 ref 觉得 .value 麻烦的话,可以了解一下 vue macros
    liuliancc
    liuliancc
    OP
    Jul 23, 2025
    16
    @erwin985211 #13 我的代码是 ai 写的,帖子贴的是简化版代码,当时直接让 ai 改的乱七八糟,改了好几次都不行就想着来论坛问一下,我下次注意
    NerbraskaGuy
    NerbraskaGuy
    Jul 23, 2025
    17
    @liuliancc #16 其实也不用问 ai ,vue3 reactive 这个东西的弊端被讨论烂了,掘金上面随便找几个文章看一下就很快明白了。
    linkopeneyes
    linkopeneyes
    Jul 24, 2025
    18
    全用 ref 就好了,reactive 还要过一下脑子,ref 不用动脑
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1595 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 45ms · UTC 09:20 · PVG 17:20 · LAX 01:20 · JFK 04:20
    ♥ Do have faith in what you're doing.