Vue3组合式Api快速入门

一、🍕组合式API入口-setup

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

js 复制代码
<script>

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

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

代码案例

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

2. 如何使用setup函数

js 复制代码
<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>这种语法糖写法,直接定义,直接使用

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

js 复制代码
<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():接受==对象类型数据的参数==传入并返回一个==响应式的对象==

js 复制代码
<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函数只能接受对象类型

js 复制代码
<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下==只是修改了写法==

js 复制代码
<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])

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

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

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

四、🌭组合式API-watch

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

额外的两个参数:

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

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

js 复制代码
<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>

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

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

js 复制代码
<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>

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

3. immediate选项

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

js 复制代码
<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>

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

4. deep选项

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

没有开启deep选项时

js 复制代码
<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>

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

开启deep选项

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

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

5. 精确监听

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

js 复制代码
<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>

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

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

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

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

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

选项式API 组合式API
beforeCreate/created setup
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeUnmount onBeforeUnmount
unmounted onUnmounted

以onMounted函数为例

js 复制代码
<template>
  <div>onMounted</div>
</template>

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

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

js 复制代码
<template>
  <div>onMounted</div>
</template>

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

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

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

1. 父传子

基本思想:

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

传入响应式的数据

2. 子传父

基本思想:

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

3. 解决报错

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

'defineProps' is not defined no-undefine

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

js 复制代码
import {defineProps} from "vue";

Component name "xxx" should always be multi-word

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

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

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

js 复制代码
<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>

1.difineExpose函数

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

js 复制代码
<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>

八、🥐组合式API-provide和inject

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

此处传的静态数据

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

顶层传递方法:

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

总结

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

相关推荐
bug丸8 分钟前
js数字计算
前端·javascript
Re27516 分钟前
谁懂啊!家人们,AI 帮我做出了“我的大学模拟器”网页小游戏
前端·javascript
Sun_light18 分钟前
链表 --- 高效离散存储的线性数据结构
前端·javascript·算法
我想说一句19 分钟前
盒模型大揭秘:从快递盒到网页布局的奇妙之旅
前端·javascript·面试
干就完了131 分钟前
vue3+Vite/Vue CLI脚手架创建新项目+路由配置详细步骤
前端·vue.js
bitbitDown33 分钟前
监听一个对象,vue watch 新旧值怎么会相等呢
前端·javascript·vue.js
前端一小卒37 分钟前
深入浅出 React 19:AI 视角下的源码解析与进阶-源码概览
前端·javascript·react.js
钟看不钟用38 分钟前
Iterator和循环
javascript
华洛1 小时前
《从0到1打造企业级AI售前机器人——实战指南五:处理用户意图的细节实现!》
javascript·vue.js·node.js
江城开朗的豌豆2 小时前
🔥 Vue组件传值:小杨教你玩转父子组件通信
前端·javascript·面试