vue3学习小结
目录
闲谈
今年的学习计划终于到了vue3了。自从上家公司入职之后有一年没有使用vue开发项目了,之后基本都是用的react来进行项目的开发。由于vue更新了vue3版本一方面为了提升自身的竞争力,另一方面也是对于升级之后的vue3比较充满期待。
对比vue和react
使用react开发了一年半左右在回头来看vue,react有两种组件模式来进行开发函数式组件和class组件官方更推荐使用函数式组件。
函数式组件确实开发起来比较纯粹没有过多的生命周期但是新增加了hook API,hook使用也是相对比较简单易懂的,通过hook可以来模拟class组件的生命周期和定义重新渲染页面的参数,再有一点比较大的区别就是函数式组件没有实例化而是直接返回react元素因此函数式组件中没有this我们不需要像class组件或vue需要再去关注this指向的问题这是很舒服的开发体验。
vue的话和react的class组件比较类似都有相应的生命周期,vue是基于Vue对象进行编程区别于函数式组件需要记的api比较多并且对于ts的支持不是很友好,vue3升级之后加入组合式API让我们可以将与同一个逻辑关注点相关的代码配置在一起,主要体现在setup中并且仍然保留原有的生命周期,并且对ts的支持对比vue2有了较大的提升。
总的来说vue3和react越来越像了!!!
生命周期
<template>
</template>
<script lang="ts">
import {
defineComponent,
onActivated,
onDeactivated,
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onErrorCaptured,
onRenderTracked,
onRenderTriggered,
onBeforeUnmount,
onUnmounted,
} from "vue";
export default defineComponent({
mounted() {
console.log(this, "this");
},
setup: () => {
onActivated(() => {
console.log('作为keep-alive被**了')
})
onDeactivated(() => {
console.log('作为keep-alive被停用了')
})
onErrorCaptured(() => {
console.log("onErrorCaptured"); // 错误处理
});
onRenderTracked(({ key, target, type }) => {
// 跟踪虚拟 DOM 重新渲染时调用
console.log("onRenderTracked", { key, target, type });
});
onRenderTriggered(({ key, target, type }) => {
// 当虚拟 DOM 重新渲染为 triggered.Similarly 为renderTracked,接收 debugger event 作为参数。此事件告诉你是什么操作触发了重新渲染,以及该操作的目标对象和键。
console.log("onRenderTriggered", { key, target, type });
});
onBeforeMount(() => {
console.log("onBeforeMount");
});
onMounted(() => {
console.log("onMounted");
});
onBeforeUpdate(() => {
console.log("onBeforeUpdate");
});
onUpdated(() => {
console.log("onUpdated");
});
onBeforeUnmount(() => {
console.log("onBeforeUnmount"); // 以前的beforeDestroy
});
onUnmounted(() => {
console.log("onUnmounted"); // 以前的destroyed
});
}
})
</script>
<style scoped>
</style>
vue3新加入了组合式API并且主要体现在setup中,组合式API中可以定义生命周期同时在setup之外还可以保留了vue2的生命周期。需要注意的是:
1.由于在执行 setup 时尚未创建组件实例,因此在 setup 选项中没有 this。这意味着,除了 props 之外,你将无法访问组件中声明的任何属性——本地状态、计算属性或方法。
2.beforeCreate 和 created在vue3中直接在setup中编写。
3.setup之外的生命周期是可以获取到this同vue2。
setup
vue3将核心API换成了proxy,在setup中任何响应式数据都需要通过ref或reactive这两个api转化成响应式数据,并且如果要在templete模板使用需要return出来(自定义方法也是)。
区别于react的函数式组件在相应式数据更新是setup不会重新执行,react函数式组件在state更新是会重新执行整个函数组件但是react内部会保留上一次更新的state状态。
值的注意的几个点:
1.在setup中vue3提供了getCurrentInstance方法可以获取当前实例。
2.ref和reactive是相同的功能都是将参数转化成响应式数据但是ref是转化单个值,reactive是转化对象。
3.在setup中使用计算属性需要用到computed这个api。
4.watch监听数据变化的回调有返回新旧数据,监听多个数据可传入数组。
5.watchEffect和react的useEffect,watchEffect可以在任何时候主动停止比较灵活,其中onInvalidate就是在组件卸载或者主动停止监听时触发。主要监听的对象为watchEffect中用到的响应式参数例如例子中的refTest,很关键的是即使没有使用到响应式参数也会在初始化的时候执行一次。
<div>
<input @keyup.delete="testFn" />
pageVue3Test<br />
{{ test.a }}<br />
{{ refTest }}<br />
{{ computedTest }}<br />
</div>
import {
defineComponent,
ref,
reactive,
toRefs,
watch,
onMounted,
computed,
watchEffect,
getCurrentInstance,
} from "vue";
export default defineComponent({
setup: () => {
const all = getCurrentInstance(); // 获取当前实例
console.log("aaaaaaaaaaaaaaaaa", all); // 不同于react即使有响应式依赖更新了setup也只会在刚进入组件执行一次
let test = reactive({
// 将对象分配为 ref 值用reactive
a: 103333,
});
let refTest = ref(111); // 单个值用ref
let computedTest = computed(() => refTest.value + "计算属性"); //计算属性
let testFn = (e?: any) => {
// setup中的方法需要暴露才能在模板中使用
console.log("testFn", e);
refTest.value = 22222;
};
let effect = watchEffect((onInvalidate) => {
// watchEffect只有在回调中有使用到的相应式参数才会生效
console.log("有依赖更新了", refTest.value);
onInvalidate(() => {
// 侦听器被停止时和副作用即将重新执行时的回调
console.log("和react相比");
});
});
// 停止监听(组件卸载时自动停止)
effect();
watch(refTest, (newValue, oldValue) => {
// 监听回调
console.log(newValue, oldValue);
});
onMounted(() => {
testFn();
console.log("onMounted", MYPROCESS);
setTimeout(() => {
test.a = 1000;
refTest.value = 10;
});
});
return { test, refTest, testFn, computedTest, testHook }; // 暴露出来的才能用到templete模板
}
})
总结
简单的入门了一下vue3新的东西还是很多的,组合式API让我们可以将与同一个逻辑关注点相关的代码配置在一起,让我们可以像react hook一样将复杂和碎片化的逻辑抽离到hook中使我们的代码更易于维护。