vue3-ref
宁静致远 7/17/2020 vue3
# ref -- 做值类型的响应式, 变量命名建议xxxRef
接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象仅有一个 .value property,指向该内部值。 生成值类型的响应式数据 可用于模板和reactive 通过.value修改值
无法实现响应式
<script setup lang="ts">
let count:number = 0
const handleClick = () => {
count++
console.log('count: ' + count);
}
</script>
<template>
<div>
{{count}}
<button @click="handleClick">更新</button>
</div>
</template>
<style scoped>
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
被ref包裹后,被处理为响应式对象
<script setup lang="ts">
import { ref, Ref } from 'vue';
let count:Ref<number> = ref(0)
const handleClick = () => {
count.value++
console.log(count.value);
}
</script>
<template>
<div>
{{count}}
<button @click="handleClick">更新</button>
</div>
</template>
<style scoped>
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
为何需要.value (实现响应式、保持响应式、传递响应式)
- ref 是一个对象(不丢失响应式,保证响应式),value 是存储值的
- 通过.value属性的get、set实现响应式
- 用于模板、reactive时,不需要.value, 其他情况都需要
# 用于模板
<template>
<div>
<p ref="pRef">这是一段文字</p>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
const pRef = ref<any>(null)
onMounted(() => {
console.log(pRef.value.innerHTML); // 这是一段文字
})
</script>
<style>
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# isref
判断是不是ref对象
<script setup lang="ts">
import { ref, Ref, isRef } from 'vue';
let count:Ref<number> = ref(0)
let name:string = 'xxx'
console.log(isRef(count)); // true
console.log(isRef(name)); // false
</script>
<template>
<div>
</div>
</template>
<style scoped>
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# unref
如果参数是一个ref,则返回内布置,否则返回参数本身
val = isRef(val) ? val.value : val 的语法糖函数
<script setup lang="ts">
import { ref, Ref, unref } from 'vue';
function useFoo(x:number | Ref<number>){
return unref(x)
}
console.log(useFoo(2));
console.log(useFoo(ref(2)));
</script>
<template>
<div>
</div>
</template>
<style scoped>
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# shallowRef
修改.value 属性是非响应式,不会改变
注意:ref 定义的数据会触发triggerRef函数,所以如果同时使用ref和shallowRef会一起更新数据
<script setup lang="ts">
import { ref, Ref, shallowRef } from 'vue';
let result:Ref<Object> = shallowRef({
name: 'xxx'
})
const handleClick = () => {
result.value.name = 'yyy'
console.log(result.value);
}
</script>
<template>
<div>
{{result}}
<button @click="handleClick">更新</button>
</div>
</template>
<style scoped>
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
只跟踪.value自身变化的ref,
<script setup lang="ts">
import { ref, Ref, shallowRef } from 'vue';
let result:Ref<Object> = shallowRef({
name: 'xxx'
})
const handleClick = () => {
result.value = {
name : 'yyy'
}
console.log(result.value);
}
</script>
<template>
<div>
{{result}}
<button @click="handleClick">更新</button>
</div>
</template>
<style scoped>
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# triggerRef
与shallowRef 配合使用,解决DOM的更新
<script setup lang="ts">
import { ref, Ref, shallowRef, triggerRef } from 'vue';
let result:Ref<Object> = shallowRef({
name: 'xxx'
})
const handleClick = () => {
result.value.name = 'yyy'
triggerRef(result)
console.log(result.value);
}
</script>
<template>
<div>
{{result}}
<button @click="handleClick">更新</button>
</div>
</template>
<style scoped>
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# customRef
自定义ref 响应式, customRef 是一个工厂函数,需要返回一个get\set的对象,
<script setup lang="ts">
import { customRef } from 'vue';
function MyRef<T>(value:T){
return customRef((track, trigger) => {
return {
get(){
track()
return value
},
set(newVal:T){
value = newVal
trigger()
}
}
})
}
let count = MyRef(0)
const handleClick = () => {
count.value++
console.log(count.value);
}
</script>
<template>
<div>
{{count}}
<button @click="handleClick">更新</button>
</div>
</template>
<style scoped>
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39