• 技术文章 >web前端 >Vue.js

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

    青灯夜游青灯夜游2022-08-30 20:21:53转载633
    本篇文章总结分享Vue3学习笔记,深入了解Vue3的11个知识点,希望对大家有所帮助!

    大前端零基础入门到就业:进入学习

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

    一、为什么选择CompositionAPI

    Vue2的局限性

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

    OptionsAPI

    如何使用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是什么

    import {watch} from "vue"
    export defalut {
    	props: {
    		name: String
    	},
    	setup(props) {
    		watch(() => {
    			console.log(props.name)
    		})
    	}
    }
    setup (props,context) {
    	const {attrs,slots,parent,root,emit} = context
    }

    ref是什么

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

    总结

    4.gif

    可维护性明显提高

    三、Methods

    基础用法

    5.gif

    自动拆装箱总结

    6.gif

    四、 Computed - 计算属性

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

    <template>
      <div>
        <div>Capacity: {{ capacity }}</div>
        <p>Spases Left: {{ sapcesLeft }} out of {{ capacity }}</p>
        <button @click="increaseCapacity()">Increase Capacity</button>
      </div>
    </template>
    
    <script>
    
    import { ref, computed, watch } from "vue";
    export default {
      setup(props, context) {
        const capacity = ref(3);
        const attending = ref(["Tim", "Bob", "Joe"]);
        function increaseCapacity() {
          capacity.value++;
        }
        const sapcesLeft = computed(() => {
          return capacity.value - attending.value.length;
        });
        return { capacity, increaseCapacity, attending, sapcesLeft };
      },
    };
    </script>

    五、Reactive - 响应式语法

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

    import { ref,computed } from 'vue'
    export default {
      setup(){
        const capacity = ref(4);
        const attending = ref(["Tim","Bob","Joe"]);
        const spacesLeft = computed(()=>{
          return capacity.value - attending.value.length
        })
        function increaseCapacity(){ capacity.value ++;}
        return { capacity,increaseCapacity,attending,spacesLeft}
      }
    }

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

    import { reactive,computed } from 'vue'
    export default {
      setup(){
        const event = reactive({
          capacity:4,
          attending:["Tim","Bob","Joe"],
          spacesLeft:computed(()=>{
            return event.capacity - event.attending.length;
          })
        })
      }
    }

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

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

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

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

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

    //在这里可以使用toRefs
    import {reactive,computed,toRefs} from 'vue'
    export default{
      setup(){
        const event = reactive({
          capacity:4,
          attending:["Tim","Bob","Joe"],
          spacesLeft:computed(()=>{
            return event.capacity -event.attending.length;
            
          })
        })
        function increaseCapacity(){ event.capacity ++ }
        return {...toRefs(event),increaseCapacity}
      }
    }

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

    return toRefs(event)

    完整代码

    <div>
       <p>Space Left : {{event.spacesLeft}} out of {{event.capacity}} </p>
       <h2>Attending</h2>
       <ul>
          <li v-for="(name,index)" in event.attending :key="index">{{name}}
          </li>
    
    
         
       </ul>
       <button @click="increaseCapacity">Increase Capacity</button>
       </div>
    </template>
    
    <script>
    //第一种
    import {ref,computed } from 'vue'
    export default {
      setup(){
        const capacity = ref(4)
        const attending = ref(["Tim","Bob","Joe"])
        const spaceLeft = computed(()=>{
          return capacity.value - attending.value.length;
        });
        function increaseCapacity(){ capacity.value++; }
        return {capacity,increaseCapacity,attending,spaceLeft}   
    
    
      }
    } 
    
    //返回一个响应式函数 第二种
    import { reactive,computed } from 'vue'
    export default {
      setup(){
        const event = reactive({
          capacity:4,
          attending:["Tim","Bob","Joe"],
          spaceLeft:computed(()=>{
            return event.capacity - event.attending.length;
          })
        })
        //我们不再使用.value
        function increaseCapacity() { event.capacity++; }
        //把这个event放入到template中
        return { event,increaseCapacity}
      }
    }
    
    
    </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中调用生命周期钩子

    import { onBeforeMount,onMounted } from "vue";
    export default {
      setup() {
        onBeforeMount(() => {
            console.log('Before Mount!')
        }) 
        onMounted(() => {
            console.log('Before Mount!')
        }) 
      },
    };

    八、Watch - 监听器

    // 所有依赖响应式对象监听
    watchEffect(() => {
       results.value = getEventCount(searchInput.value);
     });
    
    // 特定响应式对象监听
    watch(
      searchInput,
      () => {
        console.log("watch searchInput:");
      }
    );
    
    // 特定响应式对象监听 可以获取新旧值
    watch(
      searchInput,
     (newVal, oldVal) => {
        console.log("watch searchInput:", newVal, oldVal);
      },
    );
    
    // 多响应式对象监听
    watch(
      [firstName,lastName],
     ([newFirst,newLast], [oldFirst,oldlast]) => {
       // .....
      },
      
    );
    
    // 非懒加载方式监听 可以设置初始值
    watch(
      searchInput,
      (newVal, oldVal) => {
        console.log("watch searchInput:", newVal, oldVal);
      },
      {
        immediate: true, 
      }
    );

    九、Sharing State - 共享状态

    10.gif

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

    11.gif

    import { ref } from "vue";
    
    export default function usePromise(fn) {
      const results = ref(null);
      // is PENDING
      const loading = ref(false);
      const error = ref(null);
    
      const createPromise = async (...args) => {
        loading.value = true;
        error.value = null;
        results.value = null;
        try {
          results.value = await fn(...args);
        } catch (err) {
          error.value = err;
        } finally {
          loading.value = false;
        }
      };
      return { results, loading, error, createPromise };
    }

    应用

    import { ref, watch } from "vue";
    import usePromise from "./usePromise";
    export default {
      setup() {
        const searchInput = ref("");
        function getEventCount() {
          return new Promise((resolve) => {
            setTimeout(() => resolve(3), 1000);
          });
        }
    
        const getEvents = usePromise((searchInput) => getEventCount());
    
        watch(searchInput, () => {
          if (searchInput.value !== "") {
            getEvents.createPromise(searchInput);
          } else {
            getEvents.results.value = null;
          }
        });
    
        return { searchInput, ...getEvents };
      },
    };

    十、Suspense - 悬念

    复杂的Loading实现

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

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

    12.gif

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

    13.gif

    Suspense基础语法

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

    这就是Suspense Component,悬念组件。

    14.gif

    <template>
      <div>
        <div v-if="error">Uh oh .. {{ error }}</div>
        <Suspense>
          <template #default>
            <div>
              <Event />
              <AsyncEvent />
            </div>
          </template>
          <template #fallback> Loading.... </template>
        </Suspense>
      </div>
    </template>
    
    <script>
    import { ref, onErrorCaptured, defineAsyncComponent } from "vue";
    
    import Event from "./Event.vue";
    
    const AsyncEvent = defineAsyncComponent(() => import("./Event.vue"));
    export default {
      components: {
        Event,
        AsyncEvent,
      },
    
      setup() {
        const error = ref(null);
        onErrorCaptured((e) => {
          error.value = e;
          // 阻止错误继续冒泡
          return true;
        });
        return { error };
      },
    };
    </script>

    骨架屏实现

    15.gif

    16.gif

    十一、Teleport - 传送门

    功能

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

    17.gif

    基础语法

    通过选择器QuerySelector配置

    18.gif

    示例代码

    19.gif

    <template>
      <div>
        <teleport to="#end-of-body" :disabled="!showText">
          <!-- 【Teleport : This should be at the end 】 -->
          <div>
            <video src="../assets/flower.webm" muted controls="controls" autoplay="autoplay" loop="loop">
              
            </video>
          </div>
        </teleport>
        <div>【Teleport : This should be at the top】</div>
        <button @click="showText = !showText">Toggle showText</button>
      </div>
    </template>
    <script>
    import { ref } from "vue";
    export default {
      setup() {
        const showText = ref(false);
        setInterval(() => {
          showText.value = !showText.value;
        }, 1000);
        return { showText };
      },
    };
    </script>

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

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

    声明:本文转载于:poetries,如有侵犯,请联系admin@php.cn删除

    前端(VUE)零基础到就业课程:点击学习

    清晰的学习路线+老师随时辅导答疑

    快捷开发Web应用及小程序:点击使用

    支持亿级表,高并发,自动生成可视化后台。

    专题推荐:vue3
    上一篇:认识Vue新一代的状态管理库--Pinia 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • ❤️‍🔥共22门课程,总价3725元,会员免费学• ❤️‍🔥接口自动化测试不想写代码?• 快速了解Vue3的setup执行时机(附代码示例)• 聊聊vue3中setup函数的返回值• 详解vue3中setup函数的参数-props和context• 实例说明vue3中setup参数attrs,slots,emit是什么?• vue3 axios的使用介绍及数据渲染
    1/1

    PHP中文网