写在后面

本文为尚硅谷禹神 Vue3 教程的学习笔记。本着本人学习、分享别人的态度,分享学习笔记,心愿能对大家有所帮忙。举荐先按程序浏览往期内容:\
1. Vue3 学习笔记(Day1)


::: block-1

目录

  • 3 Vue3 外围语法

    • 3.1 选项式API 与 组合式API
    • 3.2 setup
    • 3.3 ref 和 reactive
    • 3.4 computed
    • 3.5 watch
    • 3.6 标签的 ref 属性
    • 3.7 props
    • 3.8 生命周期
    • 3.9 hook
      :::

3 Vue3 外围语法

3.1 选项式API 与 组合式API

P6:https://www.bilibili.com/video/BV1Za4y1r7KE?p=6
  • Vue2API设计是Options(选项式)格调的。
  • Vue3API设计是Composition(组合式)格调的。

Options API 的弊病:

Options类型的 API,数据、办法、计算属性等,是扩散在:datamethodscomputed中的,若想新增或者批改一个需要,就须要别离批改:datamethodscomputed,不便于保护和复用。

:::: column
::: column-left 44.5%

:::
::: column-right 55.5%

:::
::::

Composition API 的劣势:

能够用函数的形式,更加优雅的组织代码,让相干性能的代码更加有序的组织在一起。

:::: column
::: column-left 48.5%

:::
::: column-right 51.5%

:::
::::

3.2 setup

setup 概述

P7:https://www.bilibili.com/video/BV1Za4y1r7KE?p=7

setupVue3中一个新的配置项,值是一个函数,它是 Composition API “表演的舞台”,组件中所用到的:数据、办法、计算属性、监督......等等,均配置在setup中。

特点如下:

  • setup函数返回的对象中的内容,可间接在模板中应用。
  • setup中拜访thisundefined
  • setup函数会在beforeCreate之前调用,它是“当先”所有钩子执行的。
<template>  <div class="person">    <h2>姓名:{{name}}</h2>    <h2>年龄:{{age}}</h2>    <button @click="changeName">批改名字</button>    <button @click="changeAge">年龄+1</button>    <button @click="showTel">点我查看联系方式</button>  </div></template><script lang="ts">  export default {    name:'Person',    setup(){      // 数据,原来写在data中(留神:此时的name、age、tel数据都不是响应式数据)      let name = '张三'      let age = 18      let tel = '13888888888'      // 办法,原来写在methods中      function changeName(){        name = 'zhang-san' //留神:此时这么批改name页面是不变动的        console.log(name)      }      function changeAge(){        age += 1 //留神:此时这么批改age页面是不变动的        console.log(age)      }      function showTel(){        alert(tel)      }      // 返回一个对象,对象中的内容,模板中能够间接应用      return {name,age,tel,changeName,changeAge,showTel}    }  }</script>

setup 的返回值

P8:https://www.bilibili.com/video/BV1Za4y1r7KE?p=8
  • 若返回一个对象:则对象中的:属性、办法等,在模板中均能够间接应用(重点关注)。
  • 若返回一个函数:则能够自定义渲染内容,代码如下:
setup(){  return ()=> '你好啊!'}

setup 与 Options API 的关系

P9:https://www.bilibili.com/video/BV1Za4y1r7KE?p=9
  • Vue2 的配置(datamethos......)中能够拜访到 setup中的属性、办法。
  • 但在setup不能拜访到Vue2的配置(datamethos......)。
  • 如果与Vue2抵触,则setup优先。

setup 语法糖

P10:https://www.bilibili.com/video/BV1Za4y1r7KE?p=10

setup函数有一个语法糖,这个语法糖,能够让咱们把setup独立进来,代码如下:

<template>  <div class="person">    <h2>姓名:{{name}}</h2>    <h2>年龄:{{age}}</h2>    <button @click="changName">批改名字</button>    <button @click="changAge">年龄+1</button>    <button @click="showTel">点我查看联系方式</button>  </div></template><script lang="ts">  export default {    name:'Person234', // 定义组件名  }</script><!-- 上面的写法是setup语法糖 --><script setup lang="ts">  console.log(this) //undefined    // 数据(留神:此时的name、age、tel都不是响应式数据)  let name = '张三'  let age = 18  let tel = '13888888888'  // 办法  function changName(){    name = '李四'//留神:此时这么批改name页面是不变动的  }  function changAge(){    console.log(age)    age += 1 //留神:此时这么批改age页面是不变动的  }  function showTel(){    alert(tel)  }</script>

扩大:上述代码,还须要编写一个不写setupscript标签,去指定组件名字,比拟麻烦,咱们能够借助vite中的插件简化

  1. 第一步:npm i vite-plugin-vue-setup-extend -D
  2. 第二步:在vite.config.ts文件中增加以下内容

    import { defineConfig } from 'vite'import VueSetupExtend from 'vite-plugin-vue-setup-extend'export default defineConfig({  plugins: [ VueSetupExtend() ]})
  3. 第三步:<script setup lang="ts" name="Person234">

3.3 ref 和 reactive

ref 创立:根本类型的响应式数据

P11:https://www.bilibili.com/video/BV1Za4y1r7KE?p=11
  • 作用:定义响应式变量。
  • 语法:let xxx = ref(初始值)
  • 返回值:一个RefImpl的实例对象,简称ref对象refref对象的value属性是响应式的
  • 留神点:

    • JS中操作数据须要:xxx.value,但模板中不须要.value,间接应用即可。
    • 对于let name = ref('张三')来说,name不是响应式的,name.value是响应式的。
<template>  <div class="person">    <h2>姓名:{{name}}</h2>    <h2>年龄:{{age}}</h2>    <button @click="changeName">批改名字</button>    <button @click="changeAge">年龄+1</button>    <button @click="showTel">点我查看联系方式</button>  </div></template><script setup lang="ts" name="Person">  import {ref} from 'vue'  // name和age是一个RefImpl的实例对象,简称ref对象,它们的value属性是响应式的。  let name = ref('张三')  let age = ref(18)  // tel就是一个一般的字符串,不是响应式的  let tel = '13888888888'  function changeName(){    // JS中操作ref对象时候须要.value    name.value = '李四'    console.log(name.value)    // 留神:name不是响应式的,name.value是响应式的,所以如下代码并不会引起页面的更新。    // name = ref('zhang-san')  }  function changeAge(){    // JS中操作ref对象时候须要.value    age.value += 1     console.log(age.value)  }  function showTel(){    alert(tel)  }</script>

reactive 创立:对象类型的响应式数据

P12:https://www.bilibili.com/video/BV1Za4y1r7KE?p=12
  • 作用:定义一个响应式对象(根本类型不要用它,要用ref,否则报错)
  • 语法:let 响应式对象= reactive(源对象)
  • 返回值:一个Proxy的实例对象,简称:响应式对象。
  • 留神点:reactive定义的响应式数据是“深层次”的。
<template>  <div class="person">    <h2>汽车信息:一台{{ car.brand }}汽车,价值{{ car.price }}万</h2>    <h2>游戏列表:</h2>    <ul>      <li v-for="g in games" :key="g.id">{{ g.name }}</li>    </ul>    <h2>测试:{{obj.a.b.c.d}}</h2>    <button @click="changeCarPrice">批改汽车价格</button>    <button @click="changeFirstGame">批改第一游戏</button>    <button @click="test">测试</button>  </div></template><script lang="ts" setup name="Person">import { reactive } from 'vue'// 数据let car = reactive({ brand: '飞驰', price: 100 })let games = reactive([  { id: 'ahsgdyfa01', name: '英雄联盟' },  { id: 'ahsgdyfa02', name: '王者光荣' },  { id: 'ahsgdyfa03', name: '原神' }])let obj = reactive({  a:{    b:{      c:{        d:666      }    }  }})function changeCarPrice() {  car.price += 10}function changeFirstGame() {  games[0].name = '流星蝴蝶剑'}function test(){  obj.a.b.c.d = 999}</script>

ref 创立:对象类型的响应式数据

P13:https://www.bilibili.com/video/BV1Za4y1r7KE?p=13
  • 其实ref接管的数据能够是:根本类型对象类型
  • ref接管的是对象类型,外部其实也是调用了reactive函数。
<template>  <div class="person">    <h2>汽车信息:一台{{ car.brand }}汽车,价值{{ car.price }}万</h2>    <h2>游戏列表:</h2>    <ul>      <li v-for="g in games" :key="g.id">{{ g.name }}</li>    </ul>    <h2>测试:{{obj.a.b.c.d}}</h2>    <button @click="changeCarPrice">批改汽车价格</button>    <button @click="changeFirstGame">批改第一游戏</button>    <button @click="test">测试</button>  </div></template><script lang="ts" setup name="Person">import { ref } from 'vue'// 数据let car = ref({ brand: '飞驰', price: 100 })let games = ref([  { id: 'ahsgdyfa01', name: '英雄联盟' },  { id: 'ahsgdyfa02', name: '王者光荣' },  { id: 'ahsgdyfa03', name: '原神' }])let obj = ref({  a:{    b:{      c:{        d:666      }    }  }})console.log(car)function changeCarPrice() {  car.value.price += 10}function changeFirstGame() {  games.value[0].name = '流星蝴蝶剑'}function test(){  obj.value.a.b.c.d = 999}</script>

ref 比照 reactive

P14:https://www.bilibili.com/video/BV1Za4y1r7KE?p=14

宏观角度看:

  1. ref用来定义:根本类型数据对象类型数据
  2. reactive用来定义:对象类型数据

区别:

  1. ref创立的变量必须应用.value(能够应用volar插件主动增加.value)。
  2. reactive重新分配一个新对象,会失去响应式(能够应用Object.assign去整体替换)。

应用准则:

  1. 若须要一个根本类型的响应式数据,必须应用ref
  2. 若须要一个响应式对象,层级不深,refreactive都能够。
  3. 若须要一个响应式对象,且层级较深,举荐应用reactive

toRefs 与 toRef

P15:https://www.bilibili.com/video/BV1Za4y1r7KE?p=15
  • 作用:将一个响应式对象中的每一个属性,转换为ref对象。
  • 备注:toRefstoRef性能统一,但toRefs能够批量转换。
  • 语法如下:
<template>  <div class="person">    <h2>姓名:{{person.name}}</h2>    <h2>年龄:{{person.age}}</h2>    <h2>性别:{{person.gender}}</h2>    <button @click="changeName">批改名字</button>    <button @click="changeAge">批改年龄</button>    <button @click="changeGender">批改性别</button>  </div></template><script lang="ts" setup name="Person">  import {ref,reactive,toRefs,toRef} from 'vue'  // 数据  let person = reactive({name:'张三', age:18, gender:'男'})      // 通过toRefs将person对象中的n个属性批量取出,且仍然放弃响应式的能力  let {name,gender} =  toRefs(person)      // 通过toRef将person对象中的gender属性取出,且仍然放弃响应式的能力  let age = toRef(person,'age')  // 办法  function changeName(){    name.value += '~'  }  function changeAge(){    age.value += 1  }  function changeGender(){    gender.value = '女'  }</script>

3.4 computed

P16:https://www.bilibili.com/video/BV1Za4y1r7KE?p=16

作用:依据已有数据计算出新数据(和Vue2中的computed作用统一)。

<template>  <div class="person">    姓:<input type="text" v-model="firstName"> <br>    名:<input type="text" v-model="lastName"> <br>    全名:<span>{{fullName}}</span> <br>    <button @click="changeFullName">全名改为:li-si</button>  </div></template><script setup lang="ts" name="App">  import {ref,computed} from 'vue'  let firstName = ref('zhang')  let lastName = ref('san')  // 计算属性——只读取,不批改  /* let fullName = computed(()=>{    return firstName.value + '-' + lastName.value  }) */  // 计算属性——既读取又批改  let fullName = computed({    // 读取    get(){      return firstName.value + '-' + lastName.value    },    // 批改    set(val){      console.log('有人批改了fullName',val)      firstName.value = val.split('-')[0]      lastName.value = val.split('-')[1]    }  })  function changeFullName(){    fullName.value = 'li-si'  } </script>

3.5 watch

P17:https://www.bilibili.com/video/BV1Za4y1r7KE?p=17
  • 作用:监督数据的变动(和Vue2中的watch作用统一)
  • 特点:Vue3中的watch只能监督以下四种数据
  1. ref定义的数据。
  2. reactive定义的数据。
  3. 函数返回一个值(getter函数)。
  4. 一个蕴含上述内容的数组。

咱们在Vue3中应用watch的时候,通常会遇到以下几种状况:

状况一

监督ref定义的【根本类型】数据:间接写数据名即可,监督的是其value值的扭转。

<template>  <div class="person">    <h1>状况一:监督【ref】定义的【根本类型】数据</h1>    <h2>以后求和为:{{sum}}</h2>    <button @click="changeSum">点我sum+1</button>  </div></template><script lang="ts" setup name="Person">  import {ref,watch} from 'vue'  // 数据  let sum = ref(0)  // 办法  function changeSum(){    sum.value += 1  }  // 监督,状况一:监督【ref】定义的【根本类型】数据  const stopWatch = watch(sum,(newValue,oldValue)=>{    console.log('sum变动了',newValue,oldValue)    if(newValue >= 10){      stopWatch()    }  })</script>

状况二

P18:https://www.bilibili.com/video/BV1Za4y1r7KE?p=18

监督ref定义的【对象类型】数据:间接写数据名,监督的是对象的【地址值】,若想监督对象外部的数据,要手动开启深度监督。

留神:

  • 若批改的是ref定义的对象中的属性,newValueoldValue 都是新值,因为它们是同一个对象。
  • 若批改整个ref定义的对象,newValue 是新值,oldValue 是旧值,因为不是同一个对象了。
<template>  <div class="person">    <h1>状况二:监督【ref】定义的【对象类型】数据</h1>    <h2>姓名:{{ person.name }}</h2>    <h2>年龄:{{ person.age }}</h2>    <button @click="changeName">批改名字</button>    <button @click="changeAge">批改年龄</button>    <button @click="changePerson">批改整个人</button>  </div></template><script lang="ts" setup name="Person">  import {ref,watch} from 'vue'  // 数据  let person = ref({    name:'张三',    age:18  })  // 办法  function changeName(){    person.value.name += '~'  }  function changeAge(){    person.value.age += 1  }  function changePerson(){    person.value = {name:'李四',age:90}  }  /*     监督,状况一:监督【ref】定义的【对象类型】数据,监督的是对象的地址值,若想监督对象外部属性的变动,须要手动开启深度监督    watch的第一个参数是:被监督的数据    watch的第二个参数是:监督的回调    watch的第三个参数是:配置对象(deep、immediate等等.....)   */  watch(person,(newValue,oldValue)=>{    console.log('person变动了',newValue,oldValue)  },{deep:true})  </script>

状况三

P19:https://www.bilibili.com/video/BV1Za4y1r7KE?p=19

监督reactive定义的【对象类型】数据,且默认开启了深度监督。

<template>  <div class="person">    <h1>状况三:监督【reactive】定义的【对象类型】数据</h1>    <h2>姓名:{{ person.name }}</h2>    <h2>年龄:{{ person.age }}</h2>    <button @click="changeName">批改名字</button>    <button @click="changeAge">批改年龄</button>    <button @click="changePerson">批改整个人</button>    <hr>    <h2>测试:{{obj.a.b.c}}</h2>    <button @click="test">批改obj.a.b.c</button>  </div></template><script lang="ts" setup name="Person">  import {reactive,watch} from 'vue'  // 数据  let person = reactive({    name:'张三',    age:18  })  let obj = reactive({    a:{      b:{        c:666      }    }  })  // 办法  function changeName(){    person.name += '~'  }  function changeAge(){    person.age += 1  }  function changePerson(){    Object.assign(person,{name:'李四',age:80})  }  function test(){    obj.a.b.c = 888  }  // 监督,状况三:监督【reactive】定义的【对象类型】数据,且默认是开启深度监督的  watch(person,(newValue,oldValue)=>{    console.log('person变动了',newValue,oldValue)  })  watch(obj,(newValue,oldValue)=>{    console.log('Obj变动了',newValue,oldValue)  })</script>

状况四

P20:https://www.bilibili.com/video/BV1Za4y1r7KE?p=20

监督refreactive定义的【对象类型】数据中的某个属性,留神点如下:

  1. 若该属性值不是【对象类型】,须要写成函数模式。
  2. 若该属性值仍然是【对象类型】,可间接编,也可写成函数,倡议写成函数。

论断:监督的要是对象里的属性,那么最好写函数式,留神点:若是对象监督的是地址值,须要关注对象外部,须要手动开启深度监督。

<template>  <div class="person">    <h1>状况四:监督【ref】或【reactive】定义的【对象类型】数据中的某个属性</h1>    <h2>姓名:{{ person.name }}</h2>    <h2>年龄:{{ person.age }}</h2>    <h2>汽车:{{ person.car.c1 }}、{{ person.car.c2 }}</h2>    <button @click="changeName">批改名字</button>    <button @click="changeAge">批改年龄</button>    <button @click="changeC1">批改第一台车</button>    <button @click="changeC2">批改第二台车</button>    <button @click="changeCar">批改整个车</button>  </div></template><script lang="ts" setup name="Person">  import {reactive,watch} from 'vue'  // 数据  let person = reactive({    name:'张三',    age:18,    car:{      c1:'飞驰',      c2:'宝马'    }  })  // 办法  function changeName(){    person.name += '~'  }  function changeAge(){    person.age += 1  }  function changeC1(){    person.car.c1 = '奥迪'  }  function changeC2(){    person.car.c2 = '公众'  }  function changeCar(){    person.car = {c1:'雅迪',c2:'爱玛'}  }  // 监督,状况四:监督响应式对象中的某个属性,且该属性是根本类型的,要写成函数式  /* watch(()=> person.name,(newValue,oldValue)=>{    console.log('person.name变动了',newValue,oldValue)  }) */  // 监督,状况四:监督响应式对象中的某个属性,且该属性是对象类型的,能够间接写,也能写函数,更举荐写函数  watch(()=>person.car,(newValue,oldValue)=>{    console.log('person.car变动了',newValue,oldValue)  },{deep:true})</script>

状况五

P21:https://www.bilibili.com/video/BV1Za4y1r7KE?p=21

监督上述的多个数据

<template>  <div class="person">    <h1>状况五:监督上述的多个数据</h1>    <h2>姓名:{{ person.name }}</h2>    <h2>年龄:{{ person.age }}</h2>    <h2>汽车:{{ person.car.c1 }}、{{ person.car.c2 }}</h2>    <button @click="changeName">批改名字</button>    <button @click="changeAge">批改年龄</button>    <button @click="changeC1">批改第一台车</button>    <button @click="changeC2">批改第二台车</button>    <button @click="changeCar">批改整个车</button>  </div></template><script lang="ts" setup name="Person">  import {reactive,watch} from 'vue'  // 数据  let person = reactive({    name:'张三',    age:18,    car:{      c1:'飞驰',      c2:'宝马'    }  })  // 办法  function changeName(){    person.name += '~'  }  function changeAge(){    person.age += 1  }  function changeC1(){    person.car.c1 = '奥迪'  }  function changeC2(){    person.car.c2 = '公众'  }  function changeCar(){    person.car = {c1:'雅迪',c2:'爱玛'}  }  // 监督,状况五:监督上述的多个数据  watch([()=>person.name,person.car],(newValue,oldValue)=>{    console.log('person.car变动了',newValue,oldValue)  },{deep:true})</script>

watchEffect

P22:https://www.bilibili.com/video/BV1Za4y1r7KE?p=22

官网:立刻运行一个函数,同时响应式地追踪其依赖,并在依赖更改时从新执行该函数。

watch比照watchEffect

  1. 都能监听响应式数据的变动,不同的是监听数据变动的形式不同
  2. watch:要明确指出监督的数据
  3. watchEffect:不必明确指出监督的数据(函数中用到哪些属性,那就监督哪些属性)。

示例代码:

<template>  <div class="person">    <h1>需要:水温达到50℃,或水位达到20cm,则分割服务器</h1>    <h2 id="demo">水温:{{temp}}</h2>    <h2>水位:{{height}}</h2>    <button @click="changePrice">水温+1</button>    <button @click="changeSum">水位+10</button>  </div></template><script lang="ts" setup name="Person">  import {ref,watch,watchEffect} from 'vue'  // 数据  let temp = ref(0)  let height = ref(0)  // 办法  function changePrice(){    temp.value += 10  }  function changeSum(){    height.value += 1  }  // 用watch实现,须要明确的指出要监督:temp、height  watch([temp,height],(value)=>{    // 从value中获取最新的temp值、height值    const [newTemp,newHeight] = value    // 室温达到50℃,或水位达到20cm,立即分割服务器    if(newTemp >= 50 || newHeight >= 20){      console.log('分割服务器')    }  })  // 用watchEffect实现,不必  const stopWtach = watchEffect(()=>{    // 室温达到50℃,或水位达到20cm,立即分割服务器    if(temp.value >= 50 || height.value >= 20){      console.log(document.getElementById('demo')?.innerText)      console.log('分割服务器')    }    // 水温达到100,或水位达到50,勾销监督    if(temp.value === 100 || height.value === 50){      console.log('清理了')      stopWtach()    }  })</script>

3.6 标签的 ref 属性

P23:https://www.bilibili.com/video/BV1Za4y1r7KE?p=23

作用:用于注册模板援用。

  • 用在一般DOM标签上,获取的是DOM节点。
  • 用在组件标签上,获取的是组件实例对象。

用在一般DOM标签上:

<template>  <div class="person">    <h1 ref="title1">尚硅谷</h1>    <h2 ref="title2">前端</h2>    <h3 ref="title3">Vue</h3>    <input type="text" ref="inpt"> <br><br>    <button @click="showLog">点我打印内容</button>  </div></template><script lang="ts" setup name="Person">  import {ref} from 'vue'      let title1 = ref()  let title2 = ref()  let title3 = ref()  function showLog(){    // 通过id获取元素    const t1 = document.getElementById('title1')    // 打印内容    console.log((t1 as HTMLElement).innerText)    console.log((<HTMLElement>t1).innerText)    console.log(t1?.innerText)            /************************************/            // 通过ref获取元素    console.log(title1.value)    console.log(title2.value)    console.log(title3.value)  }</script>

用在组件标签上:

<!-- 父组件App.vue --><template>  <Person ref="ren"/>  <button @click="test">测试</button></template><script lang="ts" setup name="App">  import Person from './components/Person.vue'  import {ref} from 'vue'  let ren = ref()  function test(){    console.log(ren.value.name)    console.log(ren.value.age)  }</script><!-- 子组件Person.vue中要应用defineExpose裸露内容 --><script lang="ts" setup name="Person">  import {ref,defineExpose} from 'vue'    // 数据  let name = ref('张三')  let age = ref(18)  /****************************/  /****************************/  // 应用defineExpose将组件中的数据交给内部  defineExpose({name,age})</script>

3.7 props

回顾 TS 中的接口

P24:https://www.bilibili.com/video/BV1Za4y1r7KE?p=24

props 的应用

P25:https://www.bilibili.com/video/BV1Za4y1r7KE?p=25

type/index.ts中代码:

// 定义一个接口,限度每个Person对象的格局export interface PersonInter {id:string,name:string, age:number}// 定义一个自定义类型Personsexport type Persons = Array<PersonInter>

App.vue中代码:

<template>    <Person :list="persons"/></template><script lang="ts" setup name="App">import Person from './components/Person.vue'import {reactive} from 'vue'import {type Persons} from './types'let persons = reactive<Persons>([  {id:'e98219e12',name:'张三',age:18},  {id:'e98219e13',name:'李四',age:19},  {id:'e98219e14',name:'王五',age:20}  ])</script>

Person.vue中代码:

<template><div class="person"><ul>  <li v-for="item in list" :key="item.id">     {{item.name}}--{{item.age}}  </li></ul></div></template><script lang="ts" setup name="Person">import {defineProps} from 'vue'import {type PersonInter} from '@/types'// 第一种写法:仅接管// const props = defineProps(['list'])// 第二种写法:接管+限度类型// defineProps<{list:Persons}>()// 第三种写法:接管+限度类型+指定默认值+限度必要性let props = withDefaults(defineProps<{list?:Persons}>(),{  list:()=>[{id:'asdasg01',name:'小猪佩奇',age:18}]})console.log(props)</script>

3.8 生命周期

P26:https://www.bilibili.com/video/BV1Za4y1r7KE?p=26

概念:Vue组件实例在创立时要经验一系列的初始化步骤,在此过程中Vue会在适合的机会,调用特定的函数,从而让开发者有机会在特定阶段运行本人的代码,这些特定的函数统称为:生命周期钩子

法则:生命周期整体分为四个阶段,别离是:创立、挂载、更新、销毁,每个阶段都有两个钩子,一前一后。

P27:https://www.bilibili.com/video/BV1Za4y1r7KE?p=27

Vue2的生命周期

  • 创立阶段:beforeCreatecreated
  • 挂载阶段:beforeMountmounted
  • 更新阶段:beforeUpdateupdated
  • 销毁阶段:beforeDestroydestroyed
P28:https://www.bilibili.com/video/BV1Za4y1r7KE?p=28

Vue3的生命周期

  • 创立阶段:setup
  • 挂载阶段:onBeforeMountonMounted
  • 更新阶段:onBeforeUpdateonUpdated
  • 卸载阶段:onBeforeUnmountonUnmounted

罕用的钩子:onMounted(挂载结束)、onUpdated(更新结束)、onBeforeUnmount(卸载之前)

示例代码:

<template>  <div class="person">    <h2>以后求和为:{{ sum }}</h2>    <button @click="changeSum">点我sum+1</button>  </div></template><!-- vue3写法 --><script lang="ts" setup name="Person">  import {     ref,     onBeforeMount,     onMounted,     onBeforeUpdate,     onUpdated,     onBeforeUnmount,     onUnmounted   } from 'vue'  // 数据  let sum = ref(0)  // 办法  function changeSum() {    sum.value += 1  }  console.log('setup')  // 生命周期钩子  onBeforeMount(()=>{    console.log('挂载之前')  })  onMounted(()=>{    console.log('挂载结束')  })  onBeforeUpdate(()=>{    console.log('更新之前')  })  onUpdated(()=>{    console.log('更新结束')  })  onBeforeUnmount(()=>{    console.log('卸载之前')  })  onUnmounted(()=>{    console.log('卸载结束')  })</script>

3.9 hook

P29:https://www.bilibili.com/video/BV1Za4y1r7KE?p=29

什么是hook?—— 实质是一个函数,把setup函数中应用的Composition API进行了封装,相似于vue2.x中的mixin

自定义hook的劣势:复用代码, 让setup中的逻辑更分明易懂。

示例代码:

  • useSum.ts中内容如下:
import {ref,onMounted} from 'vue'export default function(){  let sum = ref(0)  const increment = ()=>{    sum.value += 1  }  const decrement = ()=>{    sum.value -= 1  }  onMounted(()=>{    increment()  })  //向内部裸露数据  return {sum,increment,decrement}}        
  • useDog.ts中内容如下:
import {reactive,onMounted} from 'vue'import axios,{AxiosError} from 'axios'export default function(){  let dogList = reactive<string[]>([])  // 办法  async function getDog(){    try {      // 发申请      let {data} = await axios.get('https://dog.ceo/api/breed/pembroke/images/random')      // 保护数据      dogList.push(data.message)    } catch (error) {      // 处理错误      const err = <AxiosError>error      console.log(err.message)    }  }  // 挂载钩子  onMounted(()=>{    getDog()  })      //向内部裸露数据  return {dogList,getDog}}
  • 组件中具体应用:
<template>  <h2>以后求和为:{{sum}}</h2>  <button @click="increment">点我+1</button>  <button @click="decrement">点我-1</button>  <hr>  <img v-for="(u,index) in dogList.urlList" :key="index" :src="(u as string)">   <span v-show="dogList.isLoading">加载中......</span><br>  <button @click="getDog">再来一只狗</button></template><script lang="ts">  import {defineComponent} from 'vue'  export default defineComponent({    name:'App',  })</script><script setup lang="ts">  import useSum from './hooks/useSum'  import useDog from './hooks/useDog'      let {sum,increment,decrement} = useSum()  let {dogList,getDog} = useDog()</script>


<center>完结</center>

本文由mdnice多平台公布