# Target类型及属性
```
// 定义target属性
interface Target {
// 标记为原始数据,则不能进行监控,只能为原始数据
[ReactiveFlags.SKIP]?: boolean
// 是否是可读可写响应式
[ReactiveFlags.IS_REACTIVE]?: boolean
// 是否为只读响应式
[ReactiveFlags.IS_READONLY]?: boolean
// 指向原始数据
[ReactiveFlags.RAW]?: any
}
// 判断是否为可读可写响应式
export function isReactive(value: unknown): boolean {
if (isReadonly(value)) {
// 如果是可读的的,以原始数据进行判断
return isReactive((value as Target)[ReactiveFlags.RAW])
}
return !!(value && (value as Target)[ReactiveFlags.IS_REACTIVE])
}
// 判断是否为只读响应式
export function isReadonly(value: unknown): boolean {
return !!(value && (value as Target)[ReactiveFlags.IS_READONLY])
}
// 判断是否为代理数据
export function isProxy(value: unknown): boolean {
return isReactive(value) || isReadonly(value)
}
// 通过RAW属性进行获取原始数据,如果原始数据不存在直接返回监控数据
export function toRaw<T>(observed: T): T {
return (
(observed && toRaw((observed as Target)[ReactiveFlags.RAW])) || observed
)
}
```
# reactive源码
```
export function reactive(target: object) {
// 如果对象为Readonly,则不能创建Reactive,直接返回
if (target && (target as Target)[ReactiveFlags.IS_READONLY]) {
return target
}
return createReactiveObject(
target,
false,
mutableHandlers,
mutableCollectionHandlers
)
}
```
* Reactive: 可读可写的响应式数据结构,调用createReactiveObject, 传入第二个参数为false
* Readonly: 只读的响应式数据结构, 调用createReactiveObject, 传入第二个参数为true
```
function createReactiveObject(
target: Target,
isReadonly: boolean,
baseHandlers: ProxyHandler<any>,
collectionHandlers: ProxyHandler<any>
) {
if (!isObject(target)) {
if (__DEV__) {
console.warn(`value cannot be made reactive: ${String(target)}`)
}
return target
}
// target is already a Proxy, return it.
// exception: calling readonly() on a reactive object
// target[ReactiveFlags.RAW]指target为响应式
// 如果是响应式则直接返回
// 但是如果是创建Readonly类型数据,但是target是Reactive则需要重新创建
if (
target[ReactiveFlags.RAW] &&
!(isReadonly && target[ReactiveFlags.IS_REACTIVE])
) {
return target
}
// target already has corresponding Proxy
const proxyMap = isReadonly ? readonlyMap : reactiveMap
const existingProxy = proxyMap.get(target)
if (existingProxy) {
return existingProxy
}
//
const targetType = getTargetType(target)
if (targetType === TargetType.INVALID) {
return target
}
const proxy = new Proxy(
target,
targetType === TargetType.COLLECTION ? collectionHandlers : baseHandlers
)
proxyMap.set(target, proxy)
return proxy
}
```
[Vue3.0源码分析]reactive