文章目录

  • 1. Vue3 之 生命周期
  • 2. Vue3 之 自定义hook函数
  • 3. Vue3 之 toRef 和 toRefs的使用
  • 4. Vue3 之 shallowReactive 和 shallowRef 函数API
  • 5. Vue3 之 readonly函数 和 shallowReadonly函数
  • 6. Vue3 之 toRaw 和 markRaw函数 使用
  • 7. Vue3 之 customRef 函数 使用
  • 8. Vue3 之 provide 和 inject函数使用
  • 8. Vue3 之 响应式数据的判断 api函数
  • 9. Vue3 之 Composition API(组合式API)的优势
  • 10. Vue3 之 Fragment组件
  • 11. Vue3 之 Teleport组件
  • 12. Vue3 之 Suspense组件
  • 13. 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>

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>

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

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>

一般我们再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}

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

3. Vue3 之 toRef 和 toRefs的使用


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

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

如下图中的name1 和 name2 :

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

ref函数的疑点:


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

  • 巩固一个知识点:
let a = {  //在一个对象里面,通过...展开另外一个对象的写法  ...toRefs(person),}//这种...写法让a对象扩展了toRefs(person)的属性
<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>

总结:

4. Vue3 之 shallowReactive 和 shallowRef 函数API


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

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

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

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

原因如下:

  • 打印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,达到这样的一个效果。

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>

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>

相当于跨了多个组件来指定的位置:

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>

异步引入:

  • 通过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>

通过异步引入 和 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>


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

  • 第一种:网速慢。
  • 第二种:使用了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)。