主题
响应式陷阱
解构失败
js
const user = reactive({ name: 'Alice' })
let name = user
name = 'Bob' // ❌ 页面不会更新解决方案:
js
const user = reactive({ name: 'Alice' })
user.name = 'Bob' // ✅ 页面会更新js
const user = reactive({ name: 'Alice' })
let { name } = toRefs(user)
name.value = 'Bob' // ✅ 页面会更新新增属性是否响应?
- ✅ Vue3 中新增属性是响应式的
- ❌ Vue2 中新增属性不是响应式的
js
const user = ref({ name: 'Alice' })
user.value.age = 18 // ✅ 页面会更新js
const user = reactive({ name: 'Alice' })
user.age = 18 // ✅ 页面会更新js
export default {
data() {
return { user: { name: 'Alice' } }
},
mounteds: {
changeUser() {
this.user.age = 18 // ❌ Vue2 中页面不会更新
},
},
}Vue2 中的解决方案
js
export default {
data() {
return { user: { name: 'Alice' } }
},
mounteds: {
changeUser() {
this.$set(this.user, 'age', 18) // ✅ 页面会更新
},
},
}数组索引赋值?
- ✅ Vue3 中数组索引赋值是响应式的
- ❌ Vue2 中数组索引赋值不是响应式的
js
const list = ref(['A', 'B', 'C'])
list.value[1] = 'X' // ✅ 页面会更新js
const list = reactive(['A', 'B', 'C'])
list[1] = 'X' // ✅ 页面会更新js
export default {
data() {
return { list: ['A', 'B', 'C'] }
},
mounteds: {
changeList() {
this.list[1] = 'X' // ❌ 页面不会更新
},
},
}Vue2 中的解决方案
js
export default {
data() {
return { list: ['A', 'B', 'C'] }
},
mounteds: {
changeList() {
this.list.splice(1, 1, 'D') // ✅ 页面会更新
},
},
}js
export default {
data() {
return { list: ['A', 'B', 'C'] }
},
mounteds: {
changeList() {
this.$set(this.list, 1, 'D') // ✅ 页面会更新
},
},
}ref 对象的整体替换
问题说明:在下述的例子中,代码逻辑虽然不会失效,但是会触发 Vue 重新追踪响应式依赖。如果其他地方引用了旧的 state.value,就会“断连”。
js
const state = ref({ count: 0 })
state.value = {
...state.value,
count: state.value.count + 1,
}推荐写法:
js
const state = ref({ count: 0 })
// ✅ 更新单个值
state.value.count++
// ✅ 更新多个值
Object.assign(state.value, {
count: state.value.count + 1,
// ...otherProps
})