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