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爱好者10 分钟前
vue3.x 使用vue3-tree-org实现组织架构图 + 自定义模版内容 - 附完整示例
前端·javascript·vue.js
flashlight_hi17 分钟前
LeetCode 分类刷题:1669. 合并两个链表
javascript·leetcode·链表
毕设十刻1 小时前
基于Vue的售票系统开发3g480(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
MC丶科1 小时前
Spring Boot + Vue 实现一个在线商城(商品展示、购物车、订单)!从零到一完整项目
前端·vue.js·spring boot
码途进化论3 小时前
从Chrome跳转到IE浏览器的完整解决方案
前端·javascript
笙年3 小时前
Vue 基础配置新手总结
前端·javascript·vue.js
哆啦A梦15883 小时前
40 token
前端·vue.js·node.js
摇滚侠3 小时前
Vue 项目实战《尚医通》,获取挂号医生的信息展示,笔记43
前端·javascript·vue.js·笔记·html5
k09334 小时前
vue3中基于AntDesign的Form嵌套表单的校验
前端·javascript·vue.js
茶憶4 小时前
UniApp RenderJS中集成 Leaflet地图,突破APP跨端开发限制
javascript·vue.js·uni-app