前端框架Vue3(二)——Vue3核心语法之OptionsAPI与CompositionAPI与setup

Vue3核心语法

OptionsAPI与CompositionAPI

  • Vue2API设计是Options(配置)风格的。
  • Vue3API设计是Composition(组合)风格的。

Options APl的弊端

Options类型的API,数据、方法、计算属性等,是分散在:datamethodscomputed中的,若想新

增或者修改一个需求,就需要分别修改:datamethodscomputed,不便于维护和复用。

Composition API的优势

可以用函数的方式,更加优雅的组织代码,让相关功能的代码更加有序的组织在一起。

Vue3.0的响应式

  • 实现原理:
    • 通过Proxy(代理):拦截对象中任意属性的变化,包括:属性值的读写、属性的添加、属性的删除等。
    • 通过Reflect(反射):对被代理对象的属性进行操作。
    • MDN文档中描述的Proxy与Reflect:
      Proxy:Proxy的MDN文档
      Reflect:Reflect的MDN文档
javascript 复制代码
new Proxy(data,{
	//拦截读取属性值
	get(target,prop){
	return Reflect.get(target,prop)
	},
	//拦截设置属性值或添加新属性
	set (target,prop,value){
	return Reflect.set(target,prop,value)
	},
	//拦截删除属性
	deleteProperty (target,prop){
	return Reflect.deleteProperty(target,prop)
	}
	})
	proxy.name 'tom'

拉开序幕的setup

setup概述

  1. setupVue3中一个新的配置项,值是一个函数,它是Composition API"表演的舞台",组件中所用到的:数
    据、方法、计算属性、监视等等,均配置在setup中。
    特点如下:
  • setup函数返回的对像中的内容,可直接在模板中使用。
  • setup中访问thisundefined
  • setup函数会在beforeCreate之前调用,它是"领先"所有钩子执行的。
  1. setup函数的两种返回值:
    1. 若返回一个对象,则对象中的属性、方法,在模板中均可以直接使用。(重点关注!)
    2. 若返回一个渲染函数:则可以自定义渲染内容。(了解)
    3. 注意点:
      1. 尽量不要与Vue2.x配置混用
        • Vue2.x配置(datamethodscomputed)中可以访问setup中的属性、方法
        • 但在setup中不能访问 到Vue2.x配置(datamethodscomputed)。
        • 如果有重名,setup优先。
      2. setup不能是一个async函数,因为返回值不再是return的对象,而是promise,模板看不到return对象中的属性。
  2. setup的两个注意点
  • setup执行的时机
    • 在peforeCreate之前执行一次,this是undefined
  • setup的参数
    • props:值为对象包含:组件外部传递过来且组件内部声明接收了的属性。
    • context:上下文对象
      • attrs:值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性,相当于this.$attrs
      • slots:收到的插槽内容,相当于this.$slots
      • emit:分发自定义事件的函数,相当于this.$emit

ref创建:基本类型的响应式数据

  • 作用:定义响应式变量。
  • 语法:let xxx=ref(初始值)
  • 返回值:一个RefImpl的实例对象,简称ref对象ref,ref对象的value属性是响应式的,
  • 注意点:
    • JS中操作数据需要:xxx.value,但模板中不需要.value,直接使用即可。
    • 对于let name=ref('张三')来说,name不是响应式的,name.value是响应式的。
javascript 复制代码
<template>
  <div class="person">
    <h2>姓名:{{ name }}</h2>
    <h2>年龄:{{ age }}</h2>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="showSex">查看性别</button>
  </div>
</template>

<script lang="ts">
  export default {
    name:'PersonComponent',
  }
</script>
<script lang="ts" setup name='PersonComponent'>
import { ref } from 'vue';
  const name = ref("张三")
  const age = ref(18)
  const sex = "男"
  // 方法
  function changeName() {
    name.value = "王五"
    console.log(name)
  }
  function changeAge() {
    age.value+=1
  }
  function showSex() {
    alert(sex)
  }
</script>
<style  scoped>
.person{
  background-color: pink;
  box-shadow: 0 0 10px ;
  border-radius: 10px;
  padding: 20px;
}
button{
  margin-right: 10px;
}
</style>

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

javascript 复制代码
<template>
  <div class="person">
    <h2>一辆{{ car.brand }}车,价值{{ car.price }}万</h2>
    <button @click="changePrice">修改汽车的价格</button>
    <br>
    <h2>游戏列表:
      <ul>
        <li v-for="g in games" :key="g.id">{{ g.name }}</li>
      </ul>
    </h2>
    <button @click="changeFirstGameName">修改游戏</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { defineComponent, reactive } from 'vue';

const car = reactive({
  brand: 'Benz',
  price: 100
});

const games = reactive([
  { id: "1", name: "王者荣耀" },
  { id: "2", name: "英雄联盟" },
  { id: "3", name: "和平精英" }
])

console.log(car)

function changePrice() {
  car.price += 10;
}

function changeFirstGameName() {
  games[0].name = "羊了个羊"
}
defineComponent({
  name: 'PersonInfo'
})
</script>

<style scoped>
.person {
  background-color: pink;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin-right: 10px;
}
</style>

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

javascript 复制代码
<template>
  <div class="person">
    <h2>一辆{{ car.brand }}车,价值{{ car.price }}万</h2>
    <button @click="changePrice">修改汽车的价格</button>
    <br>
    <h2>游戏列表:
      <ul>
        <li v-for="g in games" :key="g.id">{{ g.name }}</li>
      </ul>
    </h2>
    <button @click="changeFirstGameName">修改游戏</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { defineComponent, ref } from 'vue';

const car = ref({
  brand: 'Benz',
  price: 100
});

const games = ref([
  { id: "1", name: "王者荣耀" },
  { id: "2", name: "英雄联盟" },
  { id: "3", name: "和平精英" }
])

console.log(car)

 function changePrice() {
   car.value.price += 10;
 }
 function changeFirstGameName() {
   games.value[0].name = "羊了个羊"
 }
defineComponent({
  name: 'PersonInfo'
})
</script>

<style scoped>
.person {
  background-color: pink;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin-right: 10px;
}
</style>

ref对比reactive

  • 宏观角度看:
    1. ref用来定义:基本类型数据对象类型数据
    2. reactive用来定义:对象类型数据
  • 区别:
    1. ref创建的变量必须使用.value(可以使用volar插件自动添加.value)。
    2. reactive重新分配一个新对象,会失去 响应式(可以使用Object.assign去整体替换)。
  • 使用原则:
    1. 若需要一个基本类型的响应式数据,必须使用ref
    2. 若需要一个响应式对象,层级不深,refreactive都可以。
    3. 若需要一个响应式对象,且层级较深,推荐使用reactive
javascript 复制代码
<template>
  <div class="person">
    <h2>一辆{{ car.brand }}车,价值{{ car.price }}万</h2>
    <button @click="changePrice">修改汽车的价格</button>
    <button @click="changeBrand">修改汽车的品牌</button>
    <button @click="changeCar">修改汽车</button>
    <hr>
    <h2>当前求和为:{{ sum }}</h2>
    <button @click="changeSum">sum+1</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { defineComponent, ref } from 'vue';

// const car = reactive({
//   brand: 'Benz',
//   price: 100
// });
const car = ref({
  brand: 'Benz',
  price: 100
});
const sum = ref(0);

// function changePrice() {
//    car.price += 10;
//  }
// function changeBrand() {
//    car.brand = 'hongqi';
//  }
function changePrice() {
   car.value.price += 10;
 }
function changeBrand() {
   car.value.brand = 'hongqi';
 }
 function changeCar() {
  // Object.assign(car, {
  //   brand: 'Aodi',
  //   price: 10
  // });
  car.value = {
    brand: 'Aodi',
    price: 10
  };
 }
function changeSum() {
  sum.value += 1;
 }
defineComponent({
  name: 'PersonInfo'
})
</script>

<style scoped>
.person {
  background-color: pink;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin-right: 10px;
}
</style>

toRefs与toRef

  • 作用:将一个响应式对象中的每一个属性,转换为ref对象。
  • 备注:toRefstoRef功能一致,但toRefs可以批量转换
  • 语法如下:
javascript 复制代码
<template>
  <div class="person">
    <h2>name:{{ name }}</h2>
    <h2>age:{{ age }}</h2>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
  </div>
</template>

<script lang="ts" setup name="Person">
  import { defineComponent, reactive, toRefs } from 'vue';
  const person = reactive({
    name: '张三',
    age: 18,
  })
  defineComponent({
    name: 'PersonComponent',
  })
  const {name,age} = toRefs(person);
  function changeName() {
    name.value += '三';
  }
  function changeAge() {
    age.value += 1;
  }

</script>

<style scoped>
.person {
  background-color: pink;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin-right: 10px;
}
</style>

计算属性(computed)

javascript 复制代码
<template>
  <div class="person">
    姓:<input type="text" v-model="firstname"><br>
    名:<input type="text" v-model="lastname"><br>
    <button @click="changeFullName()">将全名改为li-si</button>
    全名:<span>{{ fullname}}</span>
  </div>
</template>

<script lang="ts" setup>
import { computed, ref } from 'vue';

const firstname = ref('张');
const lastname = ref('三');
// 这样定义的fullname是一个计算属性,且是只读的
// const fullname=computed(() => {
//   return firstname.value.slice(0,1).toUpperCase() + firstname.value.slice(1)+'-'+ lastname.value;
// });
const fullname = computed( {
  get(){
    return firstname.value.slice(0,1).toUpperCase() + firstname.value.slice(1)+'-'+ lastname.value;
  },
  set(val){
    const [str1,str2]=val.split('-');
    firstname.value=str1
    lastname.value=str2
  }
});

function changeFullName() {
  fullname.value='李-四'
}
</script>

<style scoped>
.person {
  background-color: pink;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin-right: 10px;
}
</style>

watch

  • 作用:监视数据的变化(和Vue2中的watch作用一致)
  • 特点:Vue3中的watch只能监视以下四种数据
    1. ref定义的数据。
    2. reactive定义的数据。
    3. 函数返回一个值(getter函数)。
    4. 一个包含上述内容的数组。
      我们在Vue3中使用watch的时候,通常会遇到以下几种情况:
*情况一

监视ref定义的【基本类型】数据:直接写数据名即可,监视的是其value值的改变。

javascript 复制代码
<template>
  <div class="person">
    <h1>情况一:监视【ref】定义的【基本类型】数据</h1>
    <h2>当前求和为:{{ sum }}</h2>
    <button @click="changeSum">点击sum+1</button>
  </div>
</template>

<script lang="ts" setup>
import { ref, watch } from 'vue';

const sum=ref(0)

function changeSum() {
  sum.value+=1;
}
// 监视
watch(sum,(newValue,oldValue)=>{
  console.log('sum被修改了',newValue,oldValue)
})
</script>

<style scoped>
.person {
  background-color: pink;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin-right: 10px;
}
</style>
*情况二

监视ref定义的【对像类型】数据:直接写数据名,监视的是对像的【地址值】,若想监视对像内部的数据,要

手动开启深度监视。

注意:

  • 若修改的是ref定义的对象中的属性,newValueoldValue都是新值,因为它们是同一个对象。
  • 若修改整个ref定义的对象,newValue是新值,oldValue是旧值,因为不是同一个对象了。
javascript 复制代码
<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';

const 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(person,(newValue,oldValue)=>{
//   console.log('person变化了',newValue,oldValue)
// })
// 监视`ref`定义的【对像类型】数据:直接写数据名,监视的是对像的【地址值】,若想监视对像内部的数据,要手动开启深度监视
// watch的第一个参数是监视的数据
// watch的第二个参数是监视的回调
// watch的第二个参数是配置对象()
watch(person,(newValue,oldValue)=>{
  console.log('person变化了',newValue,oldValue)
},{deep:true,immediate:true})
</script>

<style scoped>
.person {
  background-color: pink;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin-right: 10px;
}
</style>
*情况三

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

javascript 复制代码
<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 { reactive, watch } from 'vue';

const person = reactive({
  name:'张三',
  age:18
})

function changeName(){
  person.name += '五'
}

function changeAge(){
  person.age += 1
}

function changePerson(){
  Object.assign(person,{
    name:'王五',
    age:19
  })
}
//监视,情况三:监视`reactive`定义的【对象类型】数据,且默认开启了深度监视。
watch(person,(newValue,oldValue)=>{
  console.log('person被修改了',newValue,oldValue)
})
</script>

<style scoped>
.person {
  background-color: pink;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin-right: 10px;
}
</style>
*情况四

监视refreactive定义的【对象类型】数据中的某个属性,注意点如下:

  1. 若该属性值不是【对象类型】,需要写成函数形式。
  2. 若该属性值是依然 是【对象类型】,可直接编,也可写成函数,不过建议写成函数。
    结论:监视的要是对象里的属性,那么最好写函数式,注意点:若是对象监视的是地址值,需要关注对象内部,
    需要手动开启深度监视。
javascript 复制代码
<template>
  <div class="person">
    <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="changeFirstCar">修改第一台车</button>
  <button @click="changeSecondCar">修改第二台车</button>
  <button @click="changeCar">修改车</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { reactive, watch } from 'vue';
const person = reactive({
  name: '张三',
  age: 18,
  car:{
    c1:"Benz",
    c2:"BMW"
  }
});
  function changeName() {
    person.name += '三';
  }
  function changeAge() {
    person.age += 1;
  }
  function changeFirstCar() {
    person.car.c1 ='hongqi'
  }
  function changeSecondCar() {
    person.car.c2 ='Aodi'
  }
  function changeCar() {
    person.car.c1 ='hongqi';
    person.car.c2 ='Aodi';
  }
  watch(()=>{return person.name},(newValue, oldValue) => {
    console.log('person.name被修改了', newValue, oldValue);
  })
</script>

<style scoped>
.person {
  background-color: pink;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin-right: 10px;
}
</style>
*情况五

情况五:监视多个数据

javascript 复制代码
<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="changeFirstCar">修改第一台车</button>
  <button @click="changeSecondCar">修改第二台车</button>
  <button @click="changeCar">修改车</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { reactive, watch } from 'vue';
const person = reactive({
  name: '张三',
  age: 18,
  car:{
    c1:"Benz",
    c2:"BMW"
  }
});
  function changeName() {
    person.name += '三';
  }
  function changeAge() {
    person.age += 1;
  }
  function changeFirstCar() {
    person.car.c1 ='hongqi'
  }
  function changeSecondCar() {
    person.car.c2 ='Aodi'
  }
  function changeCar() {
    person.car.c1 ='hongqi';
    person.car.c2 ='Aodi';
  }

 // 监视,情况五:监视上述多个数据
  watch([()=>person.name,()=>person.car.c1] ,(newValue, oldValue) => {
    console.log("person.car被修改了", newValue, oldValue);
  },{deep:true})
</script>

<style scoped>
.person {
  background-color: pink;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin-right: 10px;
}
</style>

watchEffect

  • 官网:立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行该函数。
  • watch对比watchEffect
    1. 都能监听响应式数据的变化,不同的是监听数据变化的方式不同
    2. watch:要明确指出监视的数据
    3. watchEffect:不用明确指出监视的数据(函数中用到哪些属性,那就监视哪些属性)。
      示例代码:
javascript 复制代码
<template>
  <div class="person">
    <h2>需求:当水温达到60度,或水位达到80cm,给服务器发送请求</h2>
   <h2>当前水温为:{{ temp }}°C</h2>
   <h2>当前水位为:{{ height }}cm</h2>
   <button @click="changeTemp">点我temp+10</button>
   <button @click="changeHeight">点我height+10</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { ref, watchEffect } from 'vue';
const temp = ref(10);
const height = ref(0);
function changeTemp() {
  temp.value+=10
}
function changeHeight() {
  height.value+=10
}
// 监视 watch实现
/*watch([temp,height],(value)=>{
const [newTemp,newHeight]=value
console.log(newTemp,newHeight)
if(newTemp>=60||newHeight>=80){
console.log("预警!")
}
})*/

// 监视 watchEffect实现
watchEffect(()=>{
  if(temp.value>=60||height.value>=80){
    console.log("预警!")
  }
})
</script>

<style scoped>
.person {
  background-color: pink;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin-right: 10px;
}
</style>

【标签的ref属性】

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

  • 用在普通DOM标签上,获取的是DOM节点。
  • 用在组件标签上,获取的是组件实例对象。
    用在普通DOM标签上:
javascript 复制代码
<template>
  <div class="person">
    <h1>中国</h1>
    <h2 ref="title2">河南</h2>
    <h3>前端</h3>
    <button @click="showLog">点我输出h2</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { defineExpose, ref } from 'vue';
//创建一个title2,用于存储ref标记的内容
const title2 = ref()
const a = ref(1)
const b = ref(2)
const c = ref(3)
function showLog() {
  console.log(title2.value)
}
defineExpose({a,b,c})
</script>

<style scoped>
.person {
  background-color: pink;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin-right: 10px;
}
</style>

回顾TS中的接口泛型自定义类型

javascript 复制代码
<template>
  <div class="person">
<h3>{{ person }}</h3>
<h3>{{ personList }}</h3>
  </div>
</template>

<script lang="ts" setup name="Person">
import { type PersonInter, type Persons } from '@/types';

const person:PersonInter={id:'1',name:'张三',age:18}
const personList:Persons=[
  {id:'1',name:'张三',age:18},
  {id:'2',name:'李四',age:20},
  {id:'3',name:'王五',age:30}
]
</script>

<style scoped>
.person {
  background-color: pink;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin-right: 10px;
}
</style>

props的使用

javascript 复制代码
//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 { withDefaults } from 'vue';
import {type Persons } from '../types/index';

// 只接收list
// defineProps(['list'])

// 接收list+限制类型
// defineProps<{list:Persons}>()

//接收list+限制类型+限制必要性+指定默认值
// withDefaults(defineProps<{list?:Persons}>(),{
//   list:()=>[{id:'1',name:'haha',age:18}]
// })

// 接收a,同时将props保存起来
// const x=defineProps(['a'])
// console.log(x)

</script>

<style scoped>
.person {
  background-color: pink;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin-right: 10px;
}
</style>
javascript 复制代码
//App.vue
<template>
  <Person a="haha" :list="personList"/>
</template>

<script lang="ts" setup name="App">
import Person from './components/Person.vue';
import {reactive} from 'vue';
import {type Persons} from "@/types";
const personList=reactive<Persons>([
  {
    id:'1',
    name:'李四',
    age:18,
    x:10
  },
  {
    id:'2',
    name:'王五',
    age:20,
  },
  {
    id:'3',
    name:'张三',
    age:35,
  }
])
</script>

生命周期

人的生命周期:

【时刻】 【要做的事】
出生
经历 哭、笑
死亡 遗嘱

组件的生命周期:

【时刻】 【调用特定的函数】
创建 created
挂载 mounted
更新
销毁
  • 概念:Vue组件实例在创建时要经历一系列的初始化步骤,在此过程中Vue会在合适的时机,调用特定的函
    数,从而让开发者有机会在特定阶段运行自己的代码,这些特定的函数统称为:生命周期钩子
  • 规律:
    生命周期整体分为四个阶段,分别是:创建、挂载、更新、销毁,每个阶段都有两个钩子,一前一后。
  • Vue2的生命周期
    • 创建阶段:beforeCreatecreated
    • 挂载阶段:beforeMountmounted
    • 更新阶段:beforeUpdateupdated
    • 销毁阶段:beforeDestroydestroyed
  • Vue3的生命周期
    • 创建阶段:setup
    • 挂载阶段:onBeforeMountonMounted
    • 更新阶段:onBeforeUpdateonUpdated
    • 销毁阶段:onBeforeUnmountonUnmounted
  • 常用的钩子:onMounted(挂载完毕)、onUpdated(更新完毕)、onBeforeUnmount(卸载之前)
  • 示例代码:
javascript 复制代码
<template>
  <div class="person">
    <h2>当前求和为:{{ sum }}</h2>
    <button @click="add">点我sum+1</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { onBeforeMount, onBeforeUnmount, onBeforeUpdate, onMounted, onUnmounted, onUpdated, ref } from 'vue'
// 数据
const sum=ref(0)

// 方法
function add() {
  sum.value+=1
}

// 创建
console.log("子--创建成功")
// 挂载
onBeforeMount(()=>{
  console.log("子--挂载成功")
})
// 挂载完毕
onMounted(()=>{
  console.log("子--挂载完毕")
})
// 更新前
onBeforeUpdate(()=>{
  console.log("子--更新前")
})
// 更新后
onUpdated(()=>{
  console.log("子--更新后")
})
// 销毁前
onBeforeUnmount(()=>{
  console.log("子--销毁前")
})
// 销毁后
onUnmounted(()=>{
  console.log("子--销毁后")
})
</script>
<style scoped>
.person {
  background-color: pink;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin-right: 10px;
}
</style>

自定义hooks

javascript 复制代码
import { computed, onMounted, ref } from 'vue'
export default function () {
  // 数据
  const sum = ref(0)
  const bigSum=computed(()=>{
    return sum.value*10
  })
  // 方法
  function add() {
    sum.value += 1
  }
  // 钩子
  onMounted(() => {
    add()
  })
// 向外部提供东西
  return {
    sum,
    add,
    bigSum
  }
}
javascript 复制代码
import axios from 'axios'
import { reactive,onMounted } from 'vue'

export default function (){
  // 数据
const dogList = reactive([
  'https://images.dog.ceo/breeds/pembroke/n02113023_4373.jpg'
])
// 方法
async function addDog() {
  try {
    const result = await axios.get('https://dog.ceo/api/breeds/image/random')
    if (result.data && result.data.message) {
      dogList.push(result.data.message)
    }
  } catch (error) {
    console.error('获取狗狗图片失败:', error)
  }
}
// 钩子
onMounted(() => {
  addDog()
})
//向外部提供东西
return {dogList, addDog}
}
javascript 复制代码
import { computed, onMounted, ref } from 'vue'
export default function () {
  // 数据
  const sum = ref(0)
  const bigSum=computed(()=>{
    return sum.value*10
  })
  // 方法
  function add() {
    sum.value += 1
  }
  // 钩子
  onMounted(() => {
    add()
  })
// 向外部提供东西
  return {
    sum,
    add,
    bigSum
  }
}
相关推荐
持续前行3 小时前
vscode 中找settings.json 配置
前端·javascript·vue.js
JosieBook4 小时前
【Vue】11 Vue技术——Vue 中的事件处理详解
前端·javascript·vue.js
安逸点4 小时前
Vue项目中使用xlsx库解析Excel文件
vue.js
一只小阿乐4 小时前
vue 改变查询参数的值
前端·javascript·vue.js·路由·router·网文·未花中文网
小酒星小杜5 小时前
在AI时代下,技术人应该学会构建自己的反Demo地狱系统
前端·vue.js·ai编程
Code知行合壹5 小时前
Pinia入门
vue.js
今天也要晒太阳4735 小时前
element表单和vxe表单联动校验的实现
vue.js
@PHARAOH6 小时前
WHAT - Vercel react-best-practices 系列(四)
前端·react.js·前端框架
2501_944711436 小时前
现代 React 路由实践指南
前端·react.js·前端框架
依赖_赖6 小时前
前端实现token无感刷新
前端·javascript·vue.js