萌新小白请教,不太明白为什么使用 ref 数据可以双向绑定,使用 reactive 数据无法双向绑定?是我用法不对吗?
到底什么时候应该使用 ref 什么时候应该使用 reactive 呢?
直接展示代码:
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>
![]() | 1 WJYuan 80 天前 ![]() 用法不对,reactive 不能直接替换整个对象 https://cn.vuejs.org/guide/essentials/reactivity-fundamentals.html |
2 coli 79 天前 ![]() 举个简单的例子吧: ```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 ``` |
![]() | 3 K120 79 天前 ![]() |
4 xuhuanzy 79 天前 via Android reactive 解构后的对象是原始值而不是代理对象。 |
![]() | 5 liuliancc OP 感谢各位大佬解惑 |
![]() | 6 liwenka1 79 天前 应该使用 ref 什么时候应该使用 reactive 呢? 只使用 ref 即可,虽然要不断的使用 .value 会比较繁琐,但是可以更好的区分响应式数据和非响应式数据 |
![]() | 7 wangtian2020 79 天前 reactive 出错时 ref 一定不会出错,弄不明白就一直用 ref 完事儿,.value 一定触发更新 |
8 gogogo2000 79 天前 js 的对象无论是 getter/setter 还是 proxy 都是一个对象,你直接把对象给替换了,当然就无法监听变化了 ref 无论你怎么替换,实际上你置换的都是对象的.value 值。 基本上你可以理解为 ref=reactive{ value: ??? },所以使用 ref 时,ref 对象本身永久都不会变,自然总是可以监听到变动 |
![]() | 9 hamwong 79 天前 没用过 reactive ,ref 一把梭 |
![]() | 10 erwin985211 79 天前 这种问题直接丢给 ai 就行了 |
11 johnnyyeen 79 天前 官方文档有详细说明 |
![]() | 12 MIUIOS 79 天前 @erwin985211 每次看到这种无意义的评论就很烦,人家正儿八经问问题非要来一句这种问题直接丢给 ai 就行了,AI 要是能帮楼主解决了楼主还跑来这问人?人家一句话就给解惑了, 换成 AI ,给你输出一大堆文字你还要在里面找到最重要的信息,到头来还是一头雾水 |
![]() | 13 erwin985211 78 天前 @totoro52 他这么具体的问题为什么不能问 ai ?? ,我不知道 up 是不是问过 ai ,但是我的把它的帖子原封不动丢给 ai 很明确的就得出结论了。你发问题就一定有人回答吗,回答的人的质量就一定高吗。ai 是能够训练了。凭什么说我的回答没意义,如果 up 想我一样直接问题 ai 它的疑问早就解决了。 |
![]() | 14 sunny2580839896 78 天前 统一用 ref |
![]() | 15 zhj0326 78 天前 使用 ref 觉得 .value 麻烦的话,可以了解一下 vue macros |
![]() | 16 liuliancc OP @erwin985211 #13 我的代码是 ai 写的,帖子贴的是简化版代码,当时直接让 ai 改的乱七八糟,改了好几次都不行就想着来论坛问一下,我下次注意 ![]() |
![]() | 17 NerbraskaGuy 78 天前 @liuliancc #16 其实也不用问 ai ,vue3 reactive 这个东西的弊端被讨论烂了,掘金上面随便找几个文章看一下就很快明白了。 |
![]() | 18 linkopeneyes 77 天前 全用 ref 就好了,reactive 还要过一下脑子,ref 不用动脑 |