对于vue3的学习其实很早之前就开始了,但是之前都是零零散散的看一些新特性,也没有刻意的系统学习,导致真正工作开发的时候好多东西要现查,这种不熟悉对开发造成了很大的困扰,所以这次师从张满月从零开始学习并记录
ref
将变量变为响应式,,实际效果无论基本数据类型还是引用数据类型都可以通过.value来修改其值
<template lang="pug">
.content {{ boy }}
.arr {{ arr }}
.girl {{ girl }}
button(@click="change") 改变
</template>
<script setup lang="ts">
import { ref } from "vue";
import type { Ref } from "vue";
type B = {
name: string;
gender: string;
};
const boy = ref<B>({ name: "真嗣", gender: "man" });
const arr: Ref<Array<number>> = ref([1, 2, 3, 4]);
const girl = ref("绫波丽");
function change() {
console.log(boy);
boy.value.name = "初号机";
arr.value[0] = 0;
girl.value = "明日香";
}
</script>
点击改变按钮之前
点击改变按钮后
isRef
判断变量是否为ref对象
const boy = ref<B>({ name: "真嗣", gender: "man" });
const normal = "普通"
function change() {
// console.log(boy);
// boy.value.name = "初号机";
// arr.value[0] = 0;
// girl.value = "明日香";
console.log(isRef(boy));
// true
console.log(isRef(normal));
// false
}
shallowRef
浅层次的响应
<template lang="pug">
.content ref:{{ boy }}
.content2 shallowRef: {{ boy2 }}
button(@click="change") 改变
</template>
<script setup lang="ts">
import { ref, isRef, shallowRef } from "vue";
const boy = ref({ name: "真嗣", gender: "man" });
const boy2 =shallowRef({ name: "真嗣", gender: "man" });
function change() {
boy2.value.name = "初号机";
console.log(boy2);
}
</script>
可以看到控制台的变量已经改变而视图没有改变,想要改变其值需在value这一级就赋值改变如下:
function change() {
boy2.value.name = "初号机";
console.log(boy2);
boy2.value = { name: "这下改变了"}
}
注意我们上边说到shallowRef深层次赋值不会改变视图,但是当shallowRef和ref赋值同时出现时shallowRef会被影响,他的深层次赋值也会响应式的更新视图如下:
<template lang="pug">
.content ref:{{ boy }}
.content2 shallowRef: {{ boy2 }}
button(@click="change") 改变
</template>
<script setup lang="ts">
import { ref, isRef, shallowRef } from "vue";
const boy = ref({ name: "真嗣", gender: "man" });
const boy2 = shallowRef({ name: "真嗣", gender: "man" });
function change() {
boy.value.name = "我变了";
boy2.value.name = "这下改变了";
}
</script>
又比如这样
<template lang="pug">
.content ref:{{ boy }}
.content2 shallowRef: {{ boy2 }}
button(@click="change") 改变
button(@click="change2") 后变
</template>
<script setup lang="ts">
import { ref, isRef, shallowRef } from "vue";
const boy = ref({ name: "真嗣", gender: "man" });
const boy2 = shallowRef({ name: "真嗣", gender: "man" });
function change() {
boy2.value.name = "这下改变了";
}
function change2() {
boy.value.name = "我变了";
}
</script>
点击改变之后再点击后变 即:先调用shallowRef的赋值(深层次)再调用ref的赋值 就会导致shallowRef也会更新视图,上边在一个函数里的例子调用顺序相反也达到了相同的效果,可以看出更新视图的方法是异步的。
triggerRef
ref影响shallowRef的原因就是 triggerRef,triggerRef会在视图上强制更新我们收集到的依赖,而ref赋值时会在底层调用该方法
<template lang="pug">
.content ref:{{ boy }}
.content2 shallowRef: {{ boy2 }}
button(@click="change") 改变
button(@click="change2") 后变
</template>
<script setup lang="ts">
import { ref, isRef, shallowRef, triggerRef } from "vue";
const boy = ref({ name: "真嗣", gender: "man" });
const boy2 = shallowRef({ name: "真嗣", gender: "man" });
function change() {
boy2.value.name = "这下改变了";
triggerRef(boy2);
}
customRef
自定一个ref方法,返回customRef函数 这个函数接受两个参数 一个track 一个 trigger 并返回一个对象 对象中一个get方法 一个set方法 一般get返回当前值即可也可以做想做的操作,set中接受新值一般要把新值赋给旧值,给出例子中可以在注释处调接口,并防止多次调用 做了防抖
button(@click="change") 改变
button(@click="change2") 后变
hr
div customRef:{{ cus }}
button(@click="changeCus") 改变cus
</template>
<script setup lang="ts">
import { ref, isRef, shallowRef, triggerRef, customRef } from "vue";
const cus = myRef("旧值");
function changeCus() {
cus.value = "新值";
}
function myRef<T>(value:T) {
let timer:any
return customRef((track, trigger) => {
return {
get() {
track();
return value;
},
set(newVal) {
clearTimeout(timer)
timer = setTimeout(() => {
console.log("触发了set方法");
// 调接口 做防抖
value = newVal;
trigger();
}, 500);
},
};
});
</script>
获取dom
注意因为setup是在created之前,还获取不到dom元素,所以这边引入onMounted勾子
<template>
.DOM(ref="dom") 我是dom
</template>
<script setup lang="ts">
import { ref, isRef, shallowRef, triggerRef, customRef, onMounted } from "vue";
const dom = ref<HTMLElement>();
onMounted(() => {
console.log(dom.value);
});