ref
ref | toRef |
---|---|
普通ref对象 | 特殊ref对象 |
不会和原始对象挂钩 | 创建的ref对象,与原始对象挂钩 |
重新渲染 | 不会触发渲染 |
-普通ref对象
- 不会和原始对象挂钩
- 重新渲染
如下面的例子中, ref对象改变,视图已更新,原始数据json保持不变。
<template>
<div>b = {{b}}</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
let json = { a: 12 }
let b = ref(json.a)
b.value++
console.log('b', b.value)
console.log('json', JSON.stringify(json))
return {
b
}
}
}
</script>
toRef() -特殊ref对象,传入对象和属性
4. 创建的ref对象,与原始对象挂钩
5. 不会触发渲染
<template>
<div>b = {{b}}</div>
</template>
<script>
import { ref, toRef } from 'vue'
export default {
setup() {
let json = { a: 12 }
let b = toRef(json, 'a')
setInterval(() => {
b.value++
console.log('b', b.value)
console.log('json', JSON.stringify(json))
}, 1000)
return {
b
}
}
}
</script>
toRefs()-批量处理toRef,传入一个对象
<template>
<div>res = {{res}}</div>
</template>
<script>
import { ref, toRef, toRefs } from 'vue'
export default {
setup() {
let json = { a: 12, b: 5 }
let res = toRefs(json) // 相当于{a: toRef(json, 'a'), b: toRef(json, 'b')}
setInterval(() => {
res.a.value++
res.b.value++
console.log('res.a', res.a.value, 'res.b', res.b.value)
console.log('json', JSON.stringify(json))
}, 1000)
return {
res
}
}
}
</script>
customRef
创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收 track 和 trigger 函数作为参数,并且应该返回一个带有 get 和 set 的对象。
function useDebouncedRef(value, delay = 200) {
let timeout
return customRef((track, trigger) => {
return {
get() {
track()
return value
},
set(newValue) {
clearTimeout(timeout)
timeout = setTimeout(() => {
value = newValue
trigger()
}, delay)
}
}
})
}
export default {
setup() {
return {
text: useDebouncedRef('hello')
}
}
}
shallowReactive的简单实现
shallowReactive只对第一层监听变化
function shallowReactive(obj) {
if (typeof obj === 'object') {
return new Proxy(obj, {
get(obj, key) {
if (key in obj) {
return obj[key];
} else {
console.warn('no this key:' + key)
return undefined;
}
},
set(obj, key, val) {
console.log('重新渲染')
if (key in obj) {
obj[key] = val;
} else {
console.warn('no this key:' + key)
obj[key] = val;
}
return true;
}
})
} else {
console.warn('this is not reactive :' + obj)
}
}
let obj1 = shallowReactive({
a: 12,
b: [{
c: 2
}]
})
obj1.a++;
console.log(obj1)
结果:
let obj1 = shallowReactive({
a: 12,
b: [{
c: 2
}]
})
obj1.b[0].c++;
console.log(obj1.b[0])
结果:
reactive简单实现
深度监听
function reactive(obj) {
if (typeof obj === 'object') {
if (obj instanceof Array) {
obj.forEach((item, index) => {
if (typeof item === 'object') {
obj[index] = reactive(item);
}
})
} else {
for (let key in obj) {
if (typeof obj[key] === 'object') {
obj[key] = reactive(obj[key])
}
}
}
return new Proxy(obj, {
get(obj, key) {
if (key in obj) {
return obj[key];
} else {
console.warn('no this key:' + key)
return undefined;
}
},
set(obj, key, val) {
console.log('重新渲染')
if (key in obj) {
obj[key] = val;
} else {
console.warn('no this key:' + key)
obj[key] = val;
}
return true;
}
})
} else {
console.warn('this is not reactive :' + obj)
}
}
let obj1 = reactive({
a: 12,
b: [{
c: 2
}]
})
obj1.b[0].c++;
console.log(obj1.b[0])