• Vue3 学习总结笔记 (十四)


    1. Vue3 之 生命周期


    Vue3的声明周期流程:
    在这里插入图片描述
    在这里插入图片描述

    vue3中没有了 beforeDestroy 和 destroyed 两个钩子函数,取而代之的是 beforeUnmount 和 unmounted ,卸载前和卸载后的两个钩子函数。

    在这里插入图片描述


    Vue3 配置项的钩子函数如下:

    <template>
      <h2>当前求和为:{{sum}}</h2>
      <button @click="sum++">+1操作</button>
    </template>
    
    <script>
    import {ref,reactive,watch,watchEffect} from 'vue'
    
    export default {
      name:'Demo',
      setup(){
        //数据
        let sum = ref(0)
        return {
          sum
        }
      },
      //通过配置项的形式使用生命周期钩子函数
      beforeCreate() {
        console.log('beforeCreate')
      },
      created() {
        console.log('created')
      },
      beforeMount() {
        console.log('beforeMount')
      },
      mounted() {
        console.log('mounted')
      },
      beforeUpdate() {
        console.log('beforeUpdate')
      },
      updated() {
        console.log('updated')
      },
      beforeUnmount() {
        console.log('beforeUnmount')
      },
      unmounted() {
        console.log('unmounted')
      }
    }
    </script>
    
    • 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
    • 40
    • 41
    • 42
    • 43
    • 44

    Vue3也提供了Composition API 组合式API形式的生命周期钩子:

    • vue3因为有了setup配置项,所以就没必要再去提供beforeCreate和created的组合API了。setup就可以替代他俩的作用!

    在这里插入图片描述

    同样开始要先引入对应钩子的api:

    <template>
      <h2>当前求和为:{{sum}}</h2>
      <button @click="sum++">+1操作</button>
    </template>
    
    <script>
    import {ref,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted} from 'vue'
    
    export default {
      name:'Demo',
      setup(){
        //数据
        let sum = ref(0)
        onBeforeMount(()=>{
          console.log('onBeforeMount')
        })
        onMounted(()=>{
          console.log('onMounted')
        })
        onBeforeUpdate(()=>{
          console.log('onBeforeUpdate')
        })
        onUpdated(()=>{
          console.log('onUpdated')
        })
        onBeforeUnmount(()=>{
          console.log('onBeforeUnmount')
        })
        onUnmounted(()=>{
          console.log('onUnmounted')
        })
        return {
          sum
        }
      },
    }
    </script>
    
    • 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

    如果以上的两种都配置了,组合式的钩子比配置项的钩子优先级高,同一个钩子都是先执行组合式的钩子在执行配置项的钩子。

    2. Vue3 之 自定义hook函数


    什么是hook?

    • 本质是一个函数,把setup函数中使用的Composition API进行了封装。

    实现一个鼠标点击显示坐标的功能:

    <template>
      <h2>当前点击时鼠标的坐标为:x:{{point.x}}, y:{{point.y}}</h2>
    </template>
    
    <script>
    import {ref, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, reactive} from 'vue'
    
    export default {
      name:'Demo',
      setup(){
        //数据
        let sum = ref(0)
        let point = reactive({
          x:0,
          y:0
        })
    
        //获取鼠标点击的xy坐标
        function savePoint(event){
          point.x = event.pageX
          point.y = event.pageY
          console.log(event.pageX,event.pageY)
        }
    
        //给window添加一个点击事件,获取鼠标当前的位置!
        onMounted(()=>{
          window.addEventListener('click',savePoint)
        })
    
        //组件被卸载之前,将window的事件移除
        onUnmounted(()=>{
          window.removeEventListener('click',savePoint)
        })
    
        return {
          point
        }
      },
    }
    </script>
    
    • 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
    • 40

    在这里插入图片描述

    一般我们再src下面创建一个hooks目录,在里面创建useXxx.js的文件,作为钩子函数。

    这样我们就可以将上面的那些功能全部拿出去,单独写一个js文件暴露出来,谁要用,谁引用,这就和钩子组合式API一样。
    在这里插入图片描述

    import {onMounted, onUnmounted, reactive} from "vue";
    
    export default function (){
        //实现鼠标打点相关的数据
        let point = reactive({
            x:0,
            y:0
        })
        //实现鼠标打点相关的方法
        function savePoint(event){
            point.x = event.pageX
            point.y = event.pageY
            console.log(event.pageX,event.pageY)
        }
    
        //实现鼠标打点相关的钩子声明周期
        onMounted(()=>{
            window.addEventListener('click',savePoint)
        })
    
        //组件被卸载之前,将window的事件移除
        onUnmounted(()=>{
            window.removeEventListener('click',savePoint)
        })
    
        return point
    }
    
    • 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

    其实hook就是为了复用代码。

    3. Vue3 之 toRef 和 toRefs的使用


    同样使用toRef和toRefs前也需要导入对应api:

    import {reactive,toRef,toRefs} from 'vue'
    
    • 1

    如下图中的name1 和 name2 :

    • name1只是单纯的拿到了person.name的值,并没有响应式!
    • 而通过toRef获取到的name2是和person存在响应式的关系!!
      在这里插入图片描述

    ref函数的疑点:
    在这里插入图片描述


    toRef处理一个数据,而toRefs就能处理多个,写法如下:

    • 巩固一个知识点:
    let a = {
      //在一个对象里面,通过...展开另外一个对象的写法
      ...toRefs(person),
    }
    
    //这种...写法让a对象扩展了toRefs(person)的属性
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    <template>
      <h2>姓名:{{name}}</h2>
      <h2>年龄:{{age}}</h2>
      <h2>薪资:{{job.j1.salary}}</h2>
      <button @click="name += '~'">修改姓名</button>
      <button @click="age++">增长年龄</button>
      <button @click="job.j1.salary++">涨薪</button>
    </template>
    
    <script>
    import {reactive,toRef,toRefs} from 'vue'
    
    export default {
      name:'Demo',
      setup(){
        //数据
        let person = reactive({
          name:'张三',
          age:18,
          job:{
            j1:{
              salary: 20
            }
          }
        })
    
        //将person里面的所有属性全部代理!
        const x = toRefs(person)
    
        return {
          //在一个对象里面,通过...展开另外一个对象的写法
          ...toRefs(person),
        }
      }
    }
    </script>
    
    • 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

    总结:

    在这里插入图片描述

    4. Vue3 之 shallowReactive 和 shallowRef 函数API


    shallowReactive函数只是考虑第一层响应式:

    //shallow是浅的的意思,就是仅第一层能够有响应式,而job下面的这些对象就没有响应式!
    //shallowReactive只考虑也就是只考虑第一层
    let person = shallowReactive({
      name:'张三',
      age:18,
      job:{
        j1:{
          salary: 20
        }
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    shallowRef函数,会去处理基本数据类型的响应式,不会去处理对象类型的响应式:

    //shallowRef函数不会去处理对象类型的响应式!
    //ref函数会去处理对象的响应式!
    let x = shallowRef({
      y:0
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5

    原因如下:

    • 打印x如下信息:
      在这里插入图片描述

    总结:
    在这里插入图片描述

    踩坑经历:

    • 之前有的时候vue2项目赋予值,经常把整个响应式都给赋值过去,以至于一改赋予对象其他对象也就跟着改变。这样在vue3就可以直接通过shallowRef函数来赋予就没问题了。

    5. Vue3 之 readonly函数 和 shallowReadonly函数


    readonly函数就是让一个响应式数据变为只读(深只读)。

    shallowReadonly函数让一个响应式数据变为只读的(浅只读)。

    应用场景:就是不希望数据被修改时!


    注意点 - 页面数据没有变化有两种情况:

    • js数据没有响应式,数据变了,但是页面没变!
    • js数据有响应式,但是数据自身没有变化,页面就更不会变化了。

    而 readOnly 以及 shallowReadonly 函数是属于第二种情况,数据压根就不会变化的!

    let person = reactive({
      name:'张三',
      age:18,
      job:{
        j1:{
          salary: 20
        }
      }
    })
    
    //person里面所有的person都不能修改!
    //person = readonly(person)
    //浅可读
    let person2 = shallowReadonly(person)
    
    //person2就是浅可读的,这样的喊出就是别人没办法修改person2,但是却可以修改person,达到这样的一个效果。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    6. Vue3 之 toRaw 和 markRaw函数 使用


    raw英文直译:生的,未加工的。

    toRaw作用:将一个reactive生成的响应式对象转为普通对象。

    markRaw作用:标记一个对象,使其永远不会再成为响应式对象。


    toRaw函数的使用:

    • 注意:toRaw只能使用到reactive函数。
      在这里插入图片描述

    markRaw函数 使用:

    • 注意:markRaw虽然标记了一个对象,使其不会成为响应式,但是如果改变对象的数据,对象本身数据是会改变的!只不过没有了响应式,页面不会显示了。

    在这里插入图片描述


    总结:

    • 着重记一下,应用场景。
      在这里插入图片描述

    7. Vue3 之 customRef 函数 使用


    customRef 函数作用:创建一个自定义的ref,并对其依赖项跟踪和更新触发进行显式控制。

    使用customRef函数,必须熟练使用customRef函数的两个参数track和trigger:

    • track作用:通知Vue追踪value的变化(相当于提前和get商量一下,让他任务这个value有用的!)
    • trigger作用:通知Vue重新解析模板。

    以下实现了一个定时器防抖效果的操作:

    <template>
      <input type="text" v-model="keyWord">
      <h3>{{keyWord}}</h3>
    </template>
    <script>
    import {ref,customRef} from 'vue'
    export default {
      name:'App',
      setup(){
    
        //自定义一个ref--名为:myRef
        function myRef(value,delay){
          let timer
          //customref函数有两个参数:track , trigger
          //trigger是个函数,一般再set中使用,通知vue重新解析模板
          //track也是个函数,通知Vue追踪数据(return的值)的变化
          return customRef((track, trigger)=>{
            return {
              //读,走get
              get(){
                console.log(`有人从myRef容器中读取了数据,${value}`)
                track()//通知Vue追踪value的变化(相当于提前和get商量一下,让他任务这个value有用的!)
                return value
              },
              //改,走set
              set(newValue){
                console.log(`有人改变了myRef容器中读取了数据,${newValue}`)
                //先清除定时器,在设置定时器,这样就做成了防抖效果。
                clearTimeout(timer)
                timer = setTimeout(()=>{
                  //修改get用到的value
                  value = newValue
                },delay)
                trigger()//通知Vue重新解析模板
              }
            }
          })
        }
    
        //使用自定义的ref
        let keyWord = myRef('hello',500)
    
        return {
          keyWord
        }
      },
    }
    </script>
    
    • 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
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    8. Vue3 之 provide 和 inject函数使用


    provide英文直译:提供。

    inject英文直译:注入。

    作用:实现祖孙组件间通信(祖和孙之间,隔了一个父)。

    在这里插入图片描述

    总结:
    在这里插入图片描述

    8. Vue3 之 响应式数据的判断 api函数


    在这里插入图片描述

    9. Vue3 之 Composition API(组合式API)的优势


    传统的Options API(配置项API)的缺点:
    在这里插入图片描述


    而Vue3的组合式API更好的划分功能!也是最方便的!
    在这里插入图片描述

    10. Vue3 之 Fragment组件


    在这里插入图片描述
    在这里插入图片描述

    11. Vue3 之 Teleport组件


    teleport组件作用:teleport是一种能够将我们的组件html结构移动到指定位置的计数。

    使用teleport组件实现一个弹框效果:

    • 以下是点击组件,将teleport里面的元素放到其他标签里面。
    <template>
      <div>
        <button @click="isShow=true">点我弹个窗</button>
        <!--定位到id为itholmes的标签里面,也可以定位元素。-->
        <teleport to="#itholmes">
          <div v-if="isShow" class="mask">
            <div  class="dialog">
              <h3>我是一个弹窗</h3>
              <h4>一些内容</h4>
              <h4>一些内容</h4>
              <h4>一些内容</h4>
              <button @click="isShow=false">关闭弹窗</button>
            </div>
          </div>
        </teleport>
      </div>
    </template>
    <script>
    import {ref} from 'vue'
    
    export default {
      name: 'Dialog',
      setup(){
        let isShow = ref(false)
        return {
          isShow
        }
      }
    }
    </script>
    <style>
      .dialog{
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%,-50%);
        text-align: center;
        width: 300px;
        height: 300px;
        background-color: green;
      }
      /*对话框后面的遮蔽框*/
      .mask{
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        background-color: rgba(0,0,0,0.5);
      }
    </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
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    在这里插入图片描述

    相当于跨了多个组件来指定的位置:
    在这里插入图片描述

    12. Vue3 之 Suspense组件


    Suspense英文直译:悬念,悬疑。

    Suspense组件作用就是等待异步组件渲染一些额外的环境,增加用户体验。


    静态引入:

    • import Child from ‘@/components/Child’ 这种方式就是静态引用。
    <template>
      <div class="app">
        <h3>我是App()</h3>
        <Child></Child>
      </div>
    </template>
    <script>
    
    //通过这种方式引入的Child组件,App会等child组件加载完成后,再加载
    import Child from '@/components/Child'
    
    export default {
      name:'App',
      components:{
        Child
      },
    }
    
    </script>
    <style>
    .app{
      background-color: gray;
      padding: 10px;
    }
    </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

    异步引入:

    • 通过defineAsyncComponent方式的引入,叫做异步引入。
    <template>
      <div class="app">
        <h3>我是App()</h3>
        <Child></Child>
      </div>
    </template>
    <script>
    
    import {defineAsyncComponent} from 'vue'
    //这样
    const Child = defineAsyncComponent(()=>import('@/components/Child')) //异步引入
    
    export default {
      name:'App',
      components:{
        Child
      },
    }
    
    </script>
    <style>
    .app{
      background-color: gray;
      padding: 10px;
    }
    </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

    通过异步引入 和 Suspense组件的使用达到如下的效果图:

    • 注意:Suspense组件是一个内置组件,不需要引入。
    <template>
      <div class="app">
        <h3>我是App()</h3>
        <!-- Suspense是一个内置组件。 -->
        <Suspense>
          <!-- Suspense使用的是插槽技术 -->
          <!-- default就是我们要放置的模块数据,因为是异步的所以app先加载。 -->
          <template v-slot:default>
            <Child></Child>
          </template>
          <!--default定义的模块还没有加载出来之前,由fallback插槽模块进行替代。 -->
          <template v-slot:fallback>
            <h3>加载中...</h3>
          </template>
        </Suspense>
      </div>
    </template>
    <script>
    
    import {defineAsyncComponent} from 'vue'
    const Child = defineAsyncComponent(()=>import('@/components/Child')) //异步引入
    
    export default {
      name:'App',
      components:{
        Child
      },
    }
    
    </script>
    <style>
    .app{
      background-color: gray;
      padding: 10px;
    }
    </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

    在这里插入图片描述


    在异步加载下,俩种情况下能产生组件之间延迟的情况。

    • 第一种:网速慢。
    • 第二种:使用了promise对象。(这里是个特例!)
      在这里插入图片描述

    补充一点:setup不能是一个async函数,因为返回值不再是return的对象,而是promise,模板看不到return对象中的属性。(后期也可以,返回一个Promise实例,但需要Suspense和异步组件的配合!)
    在这里插入图片描述


    总结:
    在这里插入图片描述

    13. Vue3 之 其他情况的转变


    Vue2 和 Vue3 全局API做出的一些调整:

    在这里插入图片描述


    Vue3的data配置项使用被声明为一个函数!(一般都用setup了。)


    过度类名的修改:
    在这里插入图片描述


    Vue3移除了keyCode作为v-on的修饰符,同时不再支持config.keyCodes了。

    keyCode就是像 keyup.13 等等,也就是没有了@keyup.13的形式。


    在Vue2中,native的使用:

    • 如果写了一个click的自定义事件,现在想要调用原生的click事件,就用到了native。
      在这里插入图片描述

    而Vue3移除了v-on.native修饰符。

    在这里插入图片描述


    Vue3移除过滤器(filter)。
    在这里插入图片描述

  • 相关阅读:
    Vite-Wechat网页聊天室|vite5.x+vue3+pinia+element-plus仿微信客户端
    python教程:使用gevent实现高并发并限制最大并发数
    JVM内存和垃圾回收-03.运行时数据区概述及线程
    Kotlin(十)类的继承
    Docker部署高性能分布式存储MinIO
    如何改变讨好型人格,做回真正的自己
    【搜题公众号】详解搜题公众号搭建教程(附赠题库)
    系列八、堆(Heap)
    i5 13600KF参数 酷睿i53600KF什么水平i5 13600KF核显相当于什么显卡
    Jprofiler/ VisualVM 定位内存溢出OOM
  • 原文地址:https://blog.csdn.net/IT_Holmes/article/details/126404039