- 逻辑复用及代码整理
- 更好的Typescript支持
https://vue-composition-api-rfc.netlify.app/#summary
Vue中的是使用依赖追踪的方式去通知变更的,所以在开发Vue组件的时候我们只需要用this.x = y
重新赋值某个状态,DOM Tree就会自动响应变更。这是Vue的优势,但在Composition API
中就变了一个需要重点关注的点,如果使用不好,甚至会变成缺点。
我是可以从试着从Vue的实现原理去查找此原因。Vue2中是使用Object.defineProperty
,而Vue3则使用了Proxy
,但无论使用哪种方法,我们在访问和设置某个state
的时候实际是调用了他们getter/setter的方法,但是这个state作为一个返回值或者参数的时候,它实际是作为一个值传递到了另外要给方法中,所以他的getter/setter将会丢失,数据无法响应。
这涉及到了引用传递及值传递,官方api也说的非常清楚
function changeStuff(a, b, c) {
a = a * 10
b.item = 'changed'
c = { item: 'changed' }
}
var num = 10
var obj1 = { item: 'unchanged' }
var obj2 = { item: 'unchanged' }
changeStuff(num, obje1, obj2)
console.log(num)
console.log(obj1.item)
console.log(obj2.item)
打印结果为
10
changed
unchanged
这说明Javascript中参数传递是以值传递的方式进行传递的,而传递的内容是它自己本身的引用值
解决方法可以使用toRefs
如果你从一个组合函数里返回了响应式对象,在使用函数里把它解构进行使用是会丢失响应性的,解决这个问题你可以把原封不动的返回:
import { toRefs, reactive } from 'vue'
function useCounter () {
let data = reactive({
count: 0
})
return toRefs(data)
}
export default {
setup() {
let {count} = useCounter()
return {
count
}
}
}
在setup
函数里返回的数据使用toRefs
转换一下是有好处的:
import { toRefs, reactive } from 'vue'
export default {
setup() {
let data = reactive({
count: 0
})
return {
...toRefs(data)
}
}
}
如果这样的话在模板里使用需要通过data.count
来引用count
的值,如果使用toRefs
的话可以直接使用count
另外一个是使用ref
去初始化state
import { toRefs, reactive } from 'vue'
function useCounter () {
let count =ref (0)
return {count}
}
export default {
setup() {
let {count} = useCounter()
return {
count
}
}
}
vue3的响应式原理(proxy和reflect)可以看