vue-next
是Vue3的源码仓库,Vue3采用lerna做package的划分,而响应式能力@vue/reactivity
被划分到了单独的一个package中。
如果我们想把它集成到React中,可行吗?来试一试吧。
话不多说,先看看怎么用的解解馋吧。
// store.ts
import { reactive, computed, effect } from '@vue/reactivity';
export const state = reactive({
count: 0,
});
const plusOne = computed(() => state.count + 1);
effect(() => {
console.log('plusOne changed: ', plusOne);
});
const add = () => (state.count += 1);
export const mutations = {
// mutation
add,
};
export const store = {
state,
computed: {
plusOne,
},
};
export type Store = typeof store;
复制代码
// Index.tsx
import { Provider, useStore } from 'rxv'
import { mutations, store, Store } from './store.ts'
function Count() {
const countState = useStore((store: Store) => {
const { state, computed } = store;
const { count } = state;
const { plusOne } = computed;
return {
count,
plusOne,
};
});
return (
<Card hoverable style={{ marginBottom: 24 }}>
<h1>计数器h1>
<div className="chunk">
<div className="chunk">store中的count现在是 {countState.count}div>
<div className="chunk">computed值中的plusOne现在是 {countState.plusOne.value}div>
<Button onClick={mutations.add}>addButton>
div>
Card>
);
}
export default () => {
return (
<Provider value={store}>
<Count />
Provider>
);
};
复制代码
可以看出,store
的定义只用到了@vue/reactivity
,而rxv
只是在组件中做了一层桥接,连通了Vue3和React,然后我们就可以尽情的使用Vue3的响应式能力啦。
可以看到,完美的利用了reactive、computed的强大能力。
从这个包提供的几个核心api来分析:
effect其实是响应式库中一个通用的概念:观察函数
,就像Vue2中的Watcher
,mobx中的autorun
,observer
一样,它的作用是收集依赖
。
它接受的是一个函数,它会帮你执行这个函数,并且开启依赖收集,
这个函数内部对于响应式数据的访问都可以收集依赖,那么在响应式数据被修改后,就会触发更新。
最简单的用法
const data = reactive({ count: 0 })
effect(() => {
// 就是这句话 访问了data.count
// 从而收集到了依赖
console.log(data.count)
})
data.count = 1
// 控制台打印出1
复制代码
那么如果把这个简单例子中的
() => {
// 就是这句话 访问了data.count
// 从而收集到了依赖
console.log(data.count)
}
这个函数,替换成React的组件渲染,是不是就能达成响应式更新组件的目的了?
响应式数据的核心api,这个api返回的是一个proxy
,对上面所有属性的访问都会被劫持,从而在get的时候收集依赖(也就是正在运行的effect
),在set的时候触发更新。
对于简单数据类型比如number
,我们不可能像这样去做:
let data = reactive(2)
//