您的位置:首页 > 技术中心 > 前端框架 >

【整理总结】详解Vue3的11个知识点

时间:2022-09-07 11:14

本篇文章总结分享Vue3学习笔记,深入了解Vue3的11个知识点,希望对大家有所帮助!

如何快速入门VUE3.0:进入学习

《Vue3+Node+Webpack+API 商城项目工程化实战开发课!》

一、为什么选择CompositionAPI

Vue2的局限性

  • 组件逻辑膨胀导致的可读性变差
  • 无法跨组件重用代码
  • Vue2对TS的支持有限

在传统的OptionsAPI中我们需要将逻辑分散到以下六个部分。【相关推荐:vue.js视频教程】

OptionsAPI

  • components
  • props
  • data
  • computed
  • methods
  • lifecycle methods

如何使用CompositionAPI解决问题

最佳的解决方法是将逻辑聚合就可以很好的代码可读性。

这就是我们的CompositionAPI语法能够实现的功能。CompositionAPI是一个完全可选的语法与原来的OptionAPI并没有冲突之处。他可以让我们将相同功能的代码组织在一起,而不需要散落到optionsAPI的各个角落

代码重用方法PK

Vue2中的跨组件重用代码,我们大概会有四个选择

1、Mixin - 混入

1.gif

  • 代码混入其实就是设计模式中的混合模式,缺点也非常明显。
  • 可以理解为多重继承,简单的说就是一个人如何有两个父亲

缺点

  • 无法避免属性名冲突
  • 继承关系不清晰

2、Mixin Factory - 混入工厂

返回一个

2.gif

✅代码重用方便

✅继承关系清洗

3、ScopeSlots - 作用域插槽

❌可读性不高

❌配置复杂 - 需要再模板中进行配置

❌性能低 - 每个插槽相当于一个实例

4、CompositionApi - 复合API

3.gif

✅代码量少

✅没有引入新的语法,只是单纯函数

✅异常灵活

✅工具语法提示友好 - 因为是单纯函数所以 很容易实现语法提示、自动补偿

二、setup & ref

使用CompositionAPI理由

✅更好的Typescript支持

✅在复杂功能组件中可以实现根据特性组织代码 - 代码内聚性, 比如:
排序和搜索逻辑内聚

✅组件间代码复用

setup是什么

  • 在以下方法前执行:
    • Components
    • Props
    • Data
    • Methods
    • Computed Properties
    • Lifecycle methods
  • 可以不在使用难于理解的this
  • 有两个可选参数
    • props - 属性 (响应式对象 且 可以监听(watch))
  1. import {watch} from "vue"
  2. export defalut {
  3. props: {
  4. name: String
  5. },
  6. setup(props) {
  7. watch(() => {
  8. console.log(props.name)
  9. })
  10. }
  11. }
  • context 上下文对象 - 用于代替以前的this方法可以访问的属性
  1. setup (props,context) {
  2. const {attrs,slots,parent,root,emit} = context
  3. }

ref是什么

对基本数据类型数据进行装箱操作使得成为一个响应式对象,可以跟踪数据变化。

总结

4.gif

可维护性明显提高

  • 可以控制哪些变量暴露
  • 可以跟中哪些属性被定义 (属性继承与引用透明)

三、Methods

基础用法

5.gif

自动拆装箱总结

6.gif

  • JS :需要通过.value访问包装对象
  • 模板: 自动拆箱

四、 Computed - 计算属性

这个地方实在没什么好讲的,和Vue2没变化

  1. <template>
  2. <div>
  3. <div>Capacity: {{ capacity }}</div>
  4. <p>Spases Left: {{ sapcesLeft }} out of {{ capacity }}</p>
  5. <button @click="increaseCapacity()">Increase Capacity</button>
  6. </div>
  7. </template>
  8. <script>
  9. import { ref, computed, watch } from "vue";
  10. export default {
  11. setup(props, context) {
  12. const capacity = ref(3);
  13. const attending = ref(["Tim", "Bob", "Joe"]);
  14. function increaseCapacity() {
  15. capacity.value++;
  16. }
  17. const sapcesLeft = computed(() => {
  18. return capacity.value - attending.value.length;
  19. });
  20. return { capacity, increaseCapacity, attending, sapcesLeft };
  21. },
  22. };
  23. </script>

五、Reactive - 响应式语法

之前reactive 的 Ref 去声明所有的响应式属性

  1. import { ref,computed } from 'vue'
  2. export default {
  3. setup(){
  4. const capacity = ref(4);
  5. const attending = ref(["Tim","Bob","Joe"]);
  6. const spacesLeft = computed(()=>{
  7. return capacity.value - attending.value.length
  8. })
  9. function increaseCapacity(){ capacity.value ++;}
  10. return { capacity,increaseCapacity,attending,spacesLeft}
  11. }
  12. }

但是有另一个等效的方法用它去代替 reactive 的Ref

  1. import { reactive,computed } from 'vue'
  2. export default {
  3. setup(){
  4. const event = reactive({
  5. capacity:4,
  6. attending:["Tim","Bob","Joe"],
  7. spacesLeft:computed(()=>{
  8. return event.capacity - event.attending.length;
  9. })
  10. })
  11. }
  12. }

过去我们用vue2.0的data来声明响应式对象,但是现在在这里每一个属性都是响应式的包括computed 计算属性

这2种方式相比于第一种没有使用.

接下来 我们再声明method 这2种语法都ok,取决于你选择哪一种

  1. setup(){
  2. const event = reactive(){
  3. capacity:4,
  4. attending:["Tim","Bob","Joe"],
  5. spacesLeft:computed(()=>{
  6. return event.capacity - event.attending.length;
  7. })
  8. function increaseCapacity(){event.capacity++}
  9. //return整个对象
  10. return {event,increaseCapacity}
  11. }
  12. }
  1. <p>Spaces Left:{{event.spacesLeft}} out of {{event.capacity}}</p>
  2. <h2>Attending</h2>
  3. <ul>>
  4. <li v-for="(name,index) in event.attending" :key="index">
  5. {{name}}
  6. </li>
  7. </ul>
  8. <button @click="increaseCapacity()"> Increase Capacity</button>

在这里我们使用对象都是.属性的方式,但是如果 这个结构变化了,event分开了编程了一个个片段,这个时候就不能用.属性的方式了

  1. //在这里可以使用toRefs
  2. import {reactive,computed,toRefs} from 'vue'
  3. export default{
  4. setup(){
  5. const event = reactive({
  6. capacity:4,
  7. attending:["Tim","Bob","Joe"],
  8. spacesLeft:computed(()=>{
  9. return event.capacity -event.attending.length;
  10. })
  11. })
  12. function increaseCapacity(){ event.capacity ++ }
  13. return {...toRefs(event),increaseCapacity}
  14. }
  15. }

如果没有 increaseCapacity() 这个方法 直接可以简化为

  1. return toRefs(event)

完整代码

  1. <div>
  2. <p>Space Left : {{event.spacesLeft}} out of {{event.capacity}} </p>
  3. <h2>Attending</h2>
  4. <ul>
  5. <li v-for="(name,index)" in event.attending :key="index">{{name}}
  6. </li>
  7. </ul>
  8. <button @click="increaseCapacity">Increase Capacity</button>
  9. </div>
  10. </template>
  11. <script>
  12. //第一种
  13. import {ref,computed } from 'vue'
  14. export default {
  15. setup(){
  16. const capacity = ref(4)
  17. const attending = ref(["Tim","Bob","Joe"])
  18. const spaceLeft = computed(()=>{
  19. return capacity.value - attending.value.length;
  20. });
  21. function increaseCapacity(){ capacity.value++; }
  22. return {capacity,increaseCapacity,attending,spaceLeft}
  23. }
  24. }
  25. //返回一个响应式函数 第二种
  26. import { reactive,computed } from 'vue'
  27. export default {
  28. setup(){
  29. const event = reactive({
  30. capacity:4,
  31. attending:["Tim","Bob","Joe"],
  32. spaceLeft:computed(()=>{
  33. return event.capacity - event.attending.length;
  34. })
  35. })
  36. //我们不再使用.value
  37. function increaseCapacity() { event.capacity++; }
  38. //把这个event放入到template中
  39. return { event,increaseCapacity}
  40. }
  41. }
  42. </script>

六、 Modularizing

使用CompositionAPI的两个理由

1、可以按照功能组织代码

7.gif

2、组件间功能代码复用

8.gif

9.gif

七、 LifecycleHooks - 生命周期钩子

Vue2Vue3
beforeCreate❌setup(替代)
created❌setup(替代)
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestroyonBeforeUnmount
destroyedonUnmounted
errorCapturedonErrorCaptured
-?onRenderTracked
-?onRenderTriggered

setup中调用生命周期钩子

  1. import { onBeforeMount,onMounted } from "vue";
  2. export default {
  3. setup() {
  4. onBeforeMount(() => {
  5. console.log('Before Mount!')
  6. })
  7. onMounted(() => {
  8. console.log('Before Mount!')
  9. })
  10. },
  11. };

八、Watch - 监听器

  1. // 所有依赖响应式对象监听
  2. watchEffect(() => {
  3. results.value = getEventCount(searchInput.value);
  4. });
  5. // 特定响应式对象监听
  6. watch(
  7. searchInput,
  8. () => {
  9. console.log("watch searchInput:");
  10. }
  11. );
  12. // 特定响应式对象监听 可以获取新旧值
  13. watch(
  14. searchInput,
  15. (newVal, oldVal) => {
  16. console.log("watch searchInput:", newVal, oldVal);
  17. },
  18. );
  19. // 多响应式对象监听
  20. watch(
  21. [firstName,lastName],
  22. ([newFirst,newLast], [oldFirst,oldlast]) => {
  23. // .....
  24. },
  25. );
  26. // 非懒加载方式监听 可以设置初始值
  27. watch(
  28. searchInput,
  29. (newVal, oldVal) => {
  30. console.log("watch searchInput:", newVal, oldVal);
  31. },
  32. {
  33. immediate: true,
  34. }
  35. );

九、Sharing State - 共享状态

10.gif

编写一个公共函数usePromise函数需求如下:

  • results : 返回Promise执行结果
  • loading: 返回Promise运行状态
    • PENDING :true
    • REJECTED : false
    • RESOLVED: false
  • error : 返回执行错误

11.gif

  1. import { ref } from "vue";
  2. export default function usePromise(fn) {
  3. const results = ref(null);
  4. // is PENDING
  5. const loading = ref(false);
  6. const error = ref(null);
  7. const createPromise = async (...args) => {
  8. loading.value = true;
  9. error.value = null;
  10. results.value = null;
  11. try {
  12. results.value = await fn(...args);
  13. } catch (err) {
  14. error.value = err;
  15. } finally {
  16. loading.value = false;
  17. }
  18. };
  19. return { results, loading, error, createPromise };
  20. }

应用

  1. import { ref, watch } from "vue";
  2. import usePromise from "./usePromise";
  3. export default {
  4. setup() {
  5. const searchInput = ref("");
  6. function getEventCount() {
  7. return new Promise((resolve) => {
  8. setTimeout(() => resolve(3), 1000);
  9. });
  10. }
  11. const getEvents = usePromise((searchInput) => getEventCount());
  12. watch(searchInput, () => {
  13. if (searchInput.value !== "") {
  14. getEvents.createPromise(searchInput);
  15. } else {
  16. getEvents.results.value = null;
  17. }
  18. });
  19. return { searchInput, ...getEvents };
  20. },
  21. };

十、Suspense - 悬念

复杂的Loading实现

我们考虑一下当你加载一个远程数据时,如何显示loading状态

通常我们可以在模板中使用v-if

12.gif

但是在一个组件树中,其中几个子组件需要远程加载数据,当加载完成前父组件希望处于Loading状态时我们就必须借助全局状态管理来管理这个Loading状态

13.gif

Suspense基础语法

这个问题在Vue3中有一个全新的解决方法。

这就是Suspense Component,悬念组件。

14.gif

  1. <template>
  2. <div>
  3. <div v-if="error">Uh oh .. {{ error }}</div>
  4. <Suspense>
  5. <template #default>
  6. <div>
  7. <Event />
  8. <AsyncEvent />
  9. </div>
  10. </template>
  11. <template #fallback> Loading.... </template>
  12. </Suspense>
  13. </div>
  14. </template>
  15. <script>
  16. import { ref, onErrorCaptured, defineAsyncComponent } from "vue";
  17. import Event from "./Event.vue";
  18. const AsyncEvent = defineAsyncComponent(() => import("./Event.vue"));
  19. export default {
  20. components: {
  21. Event,
  22. AsyncEvent,
  23. },
  24. setup() {
  25. const error = ref(null);
  26. onErrorCaptured((e) => {
  27. error.value = e;
  28. // 阻止错误继续冒泡
  29. return true;
  30. });
  31. return { error };
  32. },
  33. };
  34. </script>

骨架屏实现

15.gif

16.gif

十一、Teleport - 传送门

功能

类似React中的Portal, 可以将特定的html模板传送到Dom的任何位置

17.gif

基础语法

通过选择器QuerySelector配置

18.gif

示例代码

19.gif

  1. <template>
  2. <div>
  3. <teleport to="#end-of-body" :disabled="!showText">
  4. <!-- 【Teleport : This should be at the end 】 -->
  5. <div>
  6. <video src="../assets/flower.webm" muted controls="controls" autoplay="autoplay" loop="loop">
  7. </video>
  8. </div>
  9. </teleport>
  10. <div>【Teleport : This should be at the top】</div>
  11. <button @click="showText = !showText">Toggle showText</button>
  12. </div>
  13. </template>
  14. <script>
  15. import { ref } from "vue";
  16. export default {
  17. setup() {
  18. const showText = ref(false);
  19. setInterval(() => {
  20. showText.value = !showText.value;
  21. }, 1000);
  22. return { showText };
  23. },
  24. };
  25. </script>

更多编程相关知识,请访问:编程入门!!

以上就是【整理总结】详解Vue3的11个知识点的详细内容,更多请关注gxlsystem.com其它相关文章!

热门排行

今日推荐

热门手游