代码测试
- js代码
const rowData = reactive({
nameAbc: 'sdfsdf'
})
console.log(rowData, "rowData")
let rowDataValue = toRaw(rowData);
console.log(rowDataValue, "rowdatavalue")
//toRefs 使对象本身转为普通对象,但是子属性全部转为ref value方式
//toRefs 就是把一个对象的属性全部转为ref
let rowDataRef = toRefs(rowData);
let abmmd = {
a: '32432',
b: "sdfkljsdfkjs",
m: 234234,
c: {
d: 23423423
}
}
// toRefs 可以将普通对象的子属性全部转为ref对象
let abmmd_refs = toRefs(abmmd);
console.log(abmmd_refs, "abmmd_refs")
console.log(rowDataRef, "toRefs")
//toRef 将reactive对象转为ref对象
/**
* toRef 针对对象 value会返回一个proxy代理对象,对普通数据是直接监听,对对象数据是返回proxy代理对象,实现深度监听
*/
let rowData2 = toRef(rowData);
console.log(rowData2, "toRef_rowData")
//toValue 改变不了reactive proxy对象,只能改变ref创建的value对象
let rowData3 = toValue(rowData)
console.log(rowData3, "toValue")
//unref 改变不了proxy对象,只能改变ref创建的代理对象
let rowdata4 = unref(rowData);
console.log(rowdata4, "unref")
//将reactive 创建的proxy对象转为普通对象
let rowData5 = toRaw(rowData);
console.log(rowData5, "toRaw")
let nnd = ref("sdlfjslkfsjdf")
console.log(nnd, "ref_nnd")
console.log(nnd.value, "nnd")
//unref 将ref创建的代理对象转为普通对象,效果和toValue一样
let nnd2 = unref(nnd);
console.log(nnd2, "nnd2_unref")
//toValue 将ref创建的代理对象转为普通对象,效果和unref一样
let nnd3 = toValue(nnd);
console.log(nnd3, "nnd3_toValue")
/**
* isRef 只能判断ref创建的对象是否为ref,不能判断reactive创建的对象是否为reactive
*/
console.log(isRef(nnd), "isRef_test")// true
console.log(isRef(rowData), "isRef_test") //false
//isReactive 判断 reactive创建的对象是否为reactive
console.log(isReactive(rowData), "isReactive_test")
let cmdFrom = 2342342
let cmd = toRef(cmdFrom) //toRef 可以改变普通数据为ref对象
console.log(cmd, "cmd")
console.log(isProxy(rowData), "isProxy_test") //true
console.log(isProxy(nnd.value), "isProxy_test2")//false
console.log(isProxy(nnd), "isProxy_test3")//false
/**
* shallowRef 创建的代理对象不能深度监听,只能监听第一层的对象属性
*/
let tttf = shallowRef(abmmd)
console.log(tttf, "tttf")
setTimeout(() => {
// tttf.value.c.d = 449645864
}, 1000)
/**
* ref 创建的代理对象能深度监听
*/
let tttc = ref(abmmd)
console.log(tttc, "tttc")
setTimeout(() => {
tttc.value.c.d = 449645864
}, 1000)
/**
* reactive 创建的代理对象能深度监听
*/
let tttr = reactive(abmmd)
console.log(tttr, "tttr")
setTimeout(() => {
// tttr.c.d = 449645864
console.log(tttr,"tttr_result")
console.log(tttf,"tttf_result")
console.log(tttc,"tttc_result")
}, 2000)
- vue template
<div>tttf.c.d:{{ tttf.c.d }}</div>
<div>tttc.c.d:{{ tttc.c.d }}</div>
<div>tttr.c.d:{{ tttr.c.d }}</div>
ref创建基本数据和对象的差异原理
ref 创建基本数据是直接通过监听,创建对象数据是返回一个proxy的value,通过reactive创建。
// 判断是不是对象
const isObject = (val) => val !== null && typeof val === 'object';
// ref的函数
function ref(val) {
// 此处源码中为了保持一致,在对象情况下也做了用value 访问的情况value->proxy对象
// 我们在对象情况下就不在使用value 访问
return isObject(val) ? reactive(val) : new refObj(val);
}
//创建响应式对象
class refObj {
constructor(val) {
this._value = val;
}
get value() {
// 在第一次执行之后触发get来收集依赖
track(this, 'value');
return this._value;
}
set value(newVal) {
console.log(newVal);
this._value = newVal;
trigger(this, 'value');
}
};
前端工程师、程序员