ref
创建一个响应式数据,一般来说用于创建简单类型的响应式对象,比如String
、Number
类型
const name = ref('tom')
可以看到,ref
方法将这个字符串进行了一层包裹,返回的是一个RefImpl
类型的对象,译为引用的实现(reference implement)
,在该对象上设置了一个不可枚举的属性value
,所以使用name.value
来读取值。
正如上面所说,ref
通常用于定义一个简单类型,那么是否可以定义一个对象或者数组?
const obj = ref({
age: 12,
sex: 'man',
})
控制台可以看到,对于复杂的对象,值是一个被proxy
拦截处理过的对象,但是里面的属性age
和sex
不是RefImpl
类型的对象,proxy
代理的对象同样被挂载到value
上,所以可以通过obj.value.age
来读取属性,这些属性同样也是响应式的,更改时可以触发视图的更新
reactive
通过上面ref的使用案例,起始不管是复杂引用类型,如array,object
等,亦或者是简单的值类型string,number
都可以使用ref
来进行定义,但是,定义对象的话,通常还是用reactive
来实现
const person = reactive({
height: 180,
})
可以看到返回的person是一个proxy
代理的对象,使用时person.height
即可
那么能否使用reactive
来定义普通类型?
const id = reactive('id是1')
可以看到reactive
只能被用来定义对象
ref与reactive的区别与联系
一般来说,ref
被用来定义简单的字符串或者数值,而reactive
被用来定义对象数组等
ref
定义对象时,value
返回的是proxy
,reactive
定义对象时返回的也是proxy
,而这确实存在一些联系
ref
来定义数据时,会对里面的数据类型进行一层判断,当遇到复杂的引用类型时,还是会使用reactive
来进行处理
class RefImpl {
constructor(value, _shallow) {
this._shallow = _shallow;
this.dep = undefined;
this.__v_isRef = true;
this._rawValue = _shallow ? value : toRaw(value);
this._value = _shallow ? value : toReactive(value);
}
////......
}
const toReactive = (value) => isObject(value) ? reactive(value) : value;// 判断参数是否为对象,是对象调用reactive创建,否则返回原始值