Vue3组合式API快速入门


前言

本文记录了关于Vue3组合式API的大部分常用内容,通过此文可以快速掌握,并使用组合式API,同时本文中所有代码均运行过,没有问题,可直接粘贴运行,喜欢的话望收藏,评论,点赞🎈🎈🎈


提示:以下是本篇文章正文内容,下面案例可供参考

一、🎇组合式API入口-setup

1. setup选项的写法和执行时机

<script>

export default {
  setup(){
    //code
  }
}
</script>

在组件进行渲染时会优先执行setup函数,其执行时期是先于beforeCreate之前。

在这里插入图片描述

代码案例

<template>
  <div>
    main
  </div>
</template>
<script>
export default {
  setup(){
    console.log("setup")
  },
  beforeCreate() {
    console.log("beforeCreate")
  }
}
</script>

在这里插入图片描述

2. 如何使用setup函数

<template>
  <div>
    {{ message }}
  </div>
    <button @click="clikfunc">这是个按钮</button>
</template>

<script>

export default {
  setup() {
    const message = "这是一条信息"
    const clikfunc = () => {
      console.log("按钮被点击",this)
    };
    return {
      message,
      clikfunc
    }
  }
}
</script>

在这里插入图片描述

在setup函数中的数据和方法必须要return出去才能够使用,其中已经没有了this关键字,因vue3语法风格的问题,已经不推荐使用this这个关键字进行数据更改,在setup中打印this也会得到一个undefine,可见this并没有指向组件实例。

3. <script setup>语法糖

在定义了许多变量或者函数时,如果每一个变量和函数都需要return的话,会显的代码十分的冗余,所以就有了<script setup>这种语法糖写法,直接定义,直接使用.

语法糖写法(实现效果与上图一致)

<template>
  <div>
    {{ message }}
  </div>
  <button @click="clikfunc">这是个按钮</button>
</template>
<script setup>
const message = "这是一条信息"
const clikfunc = () => {
  console.log("按钮被点击")
}
</script>

二、🎄组合式API-reactive和ref函数

这两个函数都是类似vue2中的data一样,用于生成响应式数据

1. reactive函数

reactive():接受对象类型数据的参数传入并返回一个响应式的对象

<template>
  <button @click="setCount">{{ state.count }}</button>
</template>
<script setup>
//1.导入函数
import {reactive} from "vue";
//2.执行函数 传入一个对象类型的参数,并使用变量接收
const state = reactive({
  count: 0
})
const setCount = () => {
  state.count++
}
</script>

在这里插入图片描述

2. ref函数

ref():接收简单类型或者对象类型的数据传入并返回一个响应式的对象

提示:ref函数是简单类型和对象类型都可以接受,reactive函数只能接受对象类型

<template>
  <button @click="setCount">{{ count }}</button>
</template>

<script setup>
//1.导入函数
import {ref} from "vue";
//2.执行函数 传入一个对象类型的参数,并使用变量接收
const count = ref(0)
const setCount = () => {
  //在脚本区域修改由ref产生的响应式数据,必须通过.value属性
  count.value++
}
</script>

打印count,可以发现ref产生的是一个响应式的对象
在这里插入图片描述

三、🎨组合式API-computed

computed():计算属性的思想与vue2的是完全一致的,组合式API下只是修改了写法

<template>
  <div>原始的数组-{{ org_list }}</div>
  <div>过滤后的数组-{{ new_list }}</div>
</template>

<script setup>
//1.导入computed函数
import {ref} from "vue";
import {computed} from "vue";

const org_list = ref([1, 2, 3, 4, 5, 6, 7, 8])

//执行函数return计算后的值 变量接收
const new_list = computed(() => {
  return org_list.value.filter(item => item > 2)
})

setTimeout(() => {
  org_list.value.push(9,10)
}, 3000)
</script>

image-20230825102337549
提示:计算属性中不应该有异步请求,修改DOM这些操作,同时避免直接修改计算属性的值,计算属性应该是只读的

四、🎃组合式API-watch

watch的作用与vue2中是一致的,侦听一个或者多个数据的变化,数据变化时执行回调函数

额外的两个参数:

  1. immediate(立即执行)
  2. deep(深度侦听)

1. 基础使用-单个数据的侦听

<template>
  <button @click="setCount">{{ count }}</button>
</template>

<script setup>
//1.导入watch
import {ref, watch} from "vue";

const count = ref(0)
const setCount = () => {
  count.value++
}
//2.调用watch 侦听变化
//此处的ref对象不加.value
watch(count, (newValue, oldVale) => {
  console.log(`count发生了变化,旧值为${oldVale},新值为${newValue}`)
})

</script>

image-20230825114943236

2. 基础使用-多个数据的侦听

同时侦听多个数据的变化,不管哪个数据变化都需要执行回调

<template>
  <button @click="setCount">{{ count }}</button><br>
  <button @click="setName">{{ name }}</button>
</template>

<script setup>
//1.导入watch
import {ref, watch} from "vue";
//创建两个响应式数据
const count = ref(0)
const name = ref("test")

const setCount = () => {
  count.value++
}
const setName = () => {
  name.value="test被修改了"
}
//2.调用watch 侦听变化
//此处的ref对象不加.value
watch([count,name], ([newCount,newName], [oldCount,oldName]) => {
  console.log(`count发生了变化,旧值为${oldCount},新值为${newCount}`)
  console.log(`name发生了变化,旧值为${oldName},新值为${newName}`)
})
</script>

无论点击哪个按钮,都会执行回调函数

image-20230825135355507

3. immediate选项

在某些情况下,我们可能需要在组件初始化阶段就立即执行侦听器,以获取某些初始数据或执行某些操作,这个时候便可开启immediate选项

<template>
  <button @click="setCount">{{ count }}</button>
  <br>
</template>

<script setup>
//1.导入watch
import {ref, watch} from "vue";

const count = ref(0)

const setCount = () => {
  count.value++
}

watch(count, () => {
  console.log("该监听器已被创建")
}, {immediate: true})
</script>

在侦听器创建时(页面刷新时)立即触发回调,响应式数据变化之后继续执行回调

out_demo

4. deep选项

通过watch监听的ref对象默认是浅层侦听,直接修改嵌套的对象属性不会触发回调执行,你需要监听一个由ref产生的对象类型的响应式数据的属性值时,需要开启deep选项。

没有开启deep选项时

<template>
  <button @click="setCount">{{ state.count }}</button>
  <br>
</template>

<script setup>
//1.导入watch
import {ref, watch} from "vue";

const state = ref({count: 0})

const setCount = () => {
  state.value.count++
}

watch(state, () => {
  console.log("数据发生了变化")
})
</script>

数据会修改,但是没有执行回调函数

image-20230825144129940

开启deep选项

//与上述代码一致,只是在watch中开启deep选项
watch(state, () => {
  console.log("数据发生了变化")
},{deep:true})

开启过后,执行了回调函数并打印了语句

image-20230825144234230

5. 精确监听

当你开启deep选项时,就会递归遍历,监听对象的所有属性都会被监听,特别是在处理大型对象或频繁更新的对象时,会造成性能浪费。

<template>
  <div>当前的名字为:{{ info.name }}</div>
  <br>
  <div>当前的年龄为:{{ info.age }}</div>
  <button @click="changeName">修改名字</button>
  <button @click="changeAge">修改年龄</button>
  <br>
</template>

<script setup>
import {ref, watch} from "vue";

const info = ref({name: '张三', age: 18})

const changeName = () => {
  info.value.name = "李四"
}
const changeAge = () => {
  info.value.age = 68
}
//不开启deep选项,精确监听age属性
watch(
    () => info.value.age,
    () => console.log("age发生变化了")
)
</script>

image-20230825153516007

修改name时,控制台没有变化,修改age时,监听到变化,执行回调函数,打印了语句

五、🎁组合式API-生命周期函数

Vue的生命周期指的是Vue实例从创建到销毁的过程,包括开始创建、初始化数据、编译模板、挂载Dom→数据更新→再次编译模板、再次挂载Dom等过程。这个过程总共分为8个阶段:创建前/后,载入前/后,更新前/后和销毁前/后。

官网的生命周期图(组合式)

lifecycle.16e4c08e

Vue3的生命周期API(选项式 VS 组合式)

选项式API组合式API
beforeCreate/createdsetup
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeUnmountonBeforeUnmount
unmountedonUnmounted

以onMounted函数为例

<template>
  <div>onMounted</div>
</template>

<script setup>
//1.导入
import {onMounted} from "vue";
//2.执行函数
onMounted(()=>{
  console.log("组件挂载完毕")
})
</script>

image-20230825164410926

生命周期函数是可以多次执行的,多次执行时传入的回调会在时机成熟时依次执行

<template>
  <div>onMounted</div>
</template>

<script setup>
//1.导入
import {onMounted} from "vue";
//2.执行函数
onMounted(()=>{
  console.log("onMounted1")
})
onMounted(()=>{
  console.log("onMounted2")
})
</script>

image-20230825164631187

当在一个onMounted中有大量的代码的时候,可以再写一个onMounted进行补充逻辑,换句话说就是,不敢动屎代码的时候,加上去就完事了。

六、🥽组合式API-父子组件通信

1. 父传子

基本思想:

  1. 父组件给子组件绑定属性
  2. 子组件内部通过props选项接收

image-20230825174817026

image-20230825174841815

传入响应式的数据

image-20230825175340231

image-20230825175358920

2. 子传父

基本思想:

  1. 父组件中给子组件标签通过@绑定事件
  2. 子组件内部通过$emit方法触发事件

image-20230825182324566

image-20230825182341037

3. 解决报错

在这一章节中,遇到了两个问题,一个是defineProps没有被定义,一个是组件名称命名问题,这两个问题都是Eslint检测的出的问题

‘defineProps’ is not defined no-undefine

直接引入就行,或者关闭Eslint

import {defineProps} from "vue";

Component name “xxx” should always be multi-word

在组件命名的时候未按照 ESLint 的官方代码规范进行命名,根据 ESLint 官方代码风格指南,除了根组件(App.vue)以外,其他自定义组件命名要使用大驼峰命名方式或者用“-”连接单词进行命名,遇到该问题时重命名就行了;

七、🎢组合式API-模板引用

通过red标识获取真实的dom对象或者组件实例对象

<template>
  <!--2。通过ref标识绑定ref对象-->
  <h1 ref="h1Ref">这是一个标签</h1>
  <TestCom ref="testComRef"/>
</template>

<script setup>

import {onMounted, ref} from "vue";
import TestCom from "@/components/TestCom";
//1. 调用ref函数
const h1Ref = ref(null)
const testComRef = ref(null)
//组件挂载完毕后才能够获取
onMounted(()=>{
  console.log(h1Ref.value)
  console.log(testComRef.value)
})

</script>

image-20230825184642242

1.difineExpose函数

在自定义组件<TestCom/>中,有内部属性和方法,但是,打印出来的实例对象中却没有,默认情况下在<script setup>语法糖下组件内部的属性和方法是不开放给父组件访问的,所以可以通过defineExpose编译宏指定哪些属性和方法允许访问。这样设计的主要原因是防止错误修改。

<template>
  <div>这是TestCom组件</div>
</template>

<script setup>
import {ref, defineExpose} from "vue";

const name = ref("test name")

const setName = () => { // eslint-disable-line no-unused-vars
  name.value = "new name"
}
//暴露子组件的属性
defineExpose({
  name
})
</script>

image-20230825185827905

八、🎭组合式API-provide和inject

作用:顶层组件向任意底层组件传递数据和方法,实现跨层组件通信

此处传的静态数据

image-20230825193442811

image-20230825193536782

传响应式数据,在调用provider时,将第二个参数设置为ref对象

image-20230825193900155

image-20230825193908493

顶层传递方法:

image-20230825194633003

image-20230825194722842

注意:谁的数据谁负责修改。

🍜总结

由于本人也是初次系统的学习Vue3的组合式API,所以文中可能有缺漏或有误的知识点,如果您知道的话,望在评论区指出。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑的像个child

好人一生平安,先磕为敬

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值