Vue3 组合式API
1.入口
- 创建实例时,配置setup方法,然后其内部书写组合式API代码,通过组合式API生产的数据和返回,需要暴漏出去才能给HTML使用
<script>
//组合式(解构赋值)
const {createApp,ref} = Vue
var app = Vue.createApp({
//所有的代码写入到steup方法中
setup(){
//创建响应式数据
const title = ref('实例2')
function modifyTitle(){
//在 JavaScript 中需要 .value
title.value = "实例2被修改"
}
//返回定义的数据和方法
return {
title,
modifyTitle
}
}
})
app.mount('#app2')
</script>
- 单文件组件:将setup声明写到script标签中,然后直接组合式API代码
<template>
<div>
<h1>{{ title }}</h1>
</div>
</template>
<script setup>
import { ref } from 'vue'
const title = ref("组件标题")
</script>
<style scoped>
</style>
2.ref()和reactive()
- 官方推荐使用ref()函数来声明响应式状态,可以传入支持传入简单数据和引用类型的数据,返回一个数据代理对象。通过对象的value属性读取数值(再模版中使用时可以忽略value属性)
<h2>{{title}}</h2>
<h3>{{person.name}} - {{person.age}}</h3>
const title = ref('实例2')
const person = ref({
name:"张三", age: 20
})
- Ref 会使它的值具有深层响应性,传入对象或者数组这种应用类型的数据时,修改对象属性或者数组子元素都可以触发视图更新
const person = ref({
name:"张三", age: 20
})
const list = ref([1,2,3])
function modifyTitle(){
//在 JavaScript 中需要 .value
person.value.age++
list.value[0] = 5
}
- reactive() 返回的是一个原始对象的 Proxy,所以他只接受对象类型的数据 (对象、数组和如 Map、Set 这样的集合类型),通过他创建的数据访问时无需通过value属性
const person2 = reactive({
name:"李四", age: 18
})
const list = reactive([1,2,3])
function modifyTitle(){
person2.age++
list[0] = 5
}
- ref和reactive底层都是调用Proxy()来创建响应式数据,因为Proxy()不支持简单数据,所以ref会对传入的数据用对象进行包裹,用value来存放传入原数据,这样再调用Proxy()就可以返回响应式数据,正因为多了一层包裹,所以他支持简单数据类型而reactive不支持,也正因为如此,所以ref返回的数据需要用value进行操作
- 打印对象:
const title = ref('实例2')
const person = ref({
name:"张三", age: 20
})
const list = reactive({
name:"张三", age: 20
})

- 嵌套调用:当ref嵌套到reactive内部使用时,会涉及到ref的解包机制,平时估计用不上,使用时再查看文档
3.计算属性 computed
- 通过computed()来创建并返回一个代理对象
<body>
<div id="app" v-cloak>
<div class="form-group">
<label>姓:</label>
<input type="text" v-model="person.firstName" class="form-control" placeholder="请输入姓">
</div>
<div class="form-group">
<label>名:</label>
<input type="text" v-model="person.lastName" class="form-control" placeholder="请输入名">
</div>
<div class="form-group">
<label>姓名:</label>
<h2>{{fullName}}</h2>
</div>
</div>
</body>
<script>
//组合式(解构赋值)
const {createApp, ref, reactive,computed} = Vue
var app = Vue.createApp({
//所有的代码写入到steup方法中
setup(){
const person = ref({
firstName: "",
lastName: ""
})
const fullName = computed(()=>{
return person.value.firstName + person.value.lastName
})
//返回定义的数据和方法
return {
person,
fullName
}
}
})
app.mount('#app')
</script>

4.监听器 watch
- 通过watch()来监听数据变化,并执行对应的回调,参数一为需要监听的响应式数据(同时监听多个数据用数组进行包裹),参数二为需要执行的回调函数
<body>
<div id="app" v-cloak>
<input type="text" v-model="title">
</div>
</body>
<script>
//组合式(解构赋值)
const {createApp, ref, reactive,watch} = Vue
var app = Vue.createApp({
//所有的代码写入到steup方法中
setup(){
const title = ref("测试")
//注册监听器
watch(title,(newValue, oldValue)=>{
console.log('title发送变化,最新值为',title.value)
})
//返回定义的数据和方法
return {
title
}
}
})
app.mount('#app')
</script>

- 深度监听:如果监听对象是复杂类型的数据,例如对象,默认不会监听其内部的变化,需要配置deep->true
//注册监听器
watch(person,(newValue, oldValue)=>{
console.log('person发生变化,最新值为',person.value)
},{
deep: true
})
//监听内部某个属性
watch(()=> person.value.age,(newValue, oldValue)=>{
console.log('person.age发生变化,最新值为',person.value.age)
})
- 其他配置:一次性监听(once: true),即时回调(immediate: true),触发时机(flush: 'post'->Dom更新后,flush: 'sync'->Dom更新前,默认)
- watchEffect(): 和计算属性类似,自动识别回调中的依赖对象作为监听,发生改变则触发回调,传入的回调会立即执行一次
<body>
<div id="app" v-cloak>
<input type="text" v-model="name">
<input type="number" v-model="age">
</div>
</body>
<script>
//组合式(解构赋值)
const {createApp, ref, reactive,watchEffect} = Vue
var app = Vue.createApp({
//所有的代码写入到steup方法中
setup(){
const name = ref("张三")
const age = ref(20)
//注册监听器
watchEffect(()=>{
var person = {name: name.value,age:age.value}
console.log('person发生变化',name.value,age.value)
})
//返回定义的数据和方法
return {
name,age
}
}
})
app.mount('#app')
</script>

5.组件数据交互
- 父->子:通过defineProps()方法来定义要接收的参数,这些定义的参数就可以使用了,提供数组语法和对象语法(二选一)
<script setup lang="ts">
//声明要接收的字段,(数组语法,提供属性名即可)
//defineProps(['msg','num'])
//声明要接收的字段,(对象语法,可以限制属性值的类型)
const props = defineProps({
msg: String,
num: Number
})
</script>
- 子->父:用法与vue2.x一致,不过在setup作用域中,需要使用 defineEmits() 对事件进行注册,然后使用返回的emit对象触发事件
<script setup lang="ts">
//声明自定义事件
const emit = defineEmits(['sayHello'])
//触发事件
const handleSayHello = ()=>{
emit('sayHello','someone')
}
</script>
- 父->后代:通过依赖注入的形式,让所有后代组件都可以访问父组件的数据
//全局提供,所有组件都可以使用
import { createApp } from 'vue'
const app = createApp({})
app.provide()
<script setup lang="ts">
//组件提供,只能给后代组件使用
import { ref, provide } from 'vue'
//将数据暴漏给后代组件(参数一:名称,参数二:值,可以是任意类型,包括响应式的状态)
provide('home_title',"Home title")
provide('sayHello',()=>{
console.log("sayHello define in Home")
})
const num = ref(100)
//暴漏ref
provide('home_num', num)
</script>
<script setup lang="ts">
//接收方
import { inject } from 'vue'
//接收祖先组件暴漏的数据(注入)
const home_title = inject('home_title')
const sayHello = inject('sayHello')
const home_num = inject('home_num')
console.log('home_title',home_title)
console.log('sayHello',sayHello)
console.log('home_num',home_num)
//不确定,或者不存在的值给个默认值
const _unknown = inject('_unknown',null)
console.log('_unknown',_unknown)
const setNum = () => {
//不推荐更改祖先数据,如果需要,最好让祖先组件暴漏一个转码修改数据的办法
home_num.value++
}
</script>

6.模版引用
- 通过ref访问Dom:给Dom挂载一个ref属性,值为ref(null)返回的对象,则可通过这个ref对象直接访问dom
<body>
<div id="app" v-cloak>
<h2 ref="h2">{{title}}</h2>
</div>
</body>
<script>
//组合式(解构赋值)
const {createApp, ref, reactive,onMounted} = Vue
var app = Vue.createApp({
//所有的代码写入到steup方法中
setup(){
const title = ref("测试")
const h2 = ref()
onMounted(()=>{
//onMounted 测试
console.log('onMounted',title.value)
console.log(h2.value)
})
//返回定义的数据和方法
return {
title,h2
}
}
})
app.mount('#app')
</script>

- 在使用了 script setup 的组件是默认私有的,一个父组件无法访问到一个使用了 script setup 的子组件中的任何东西,除非子组件在其中通过 defineExpose 宏显式暴露
<script setup>
import { ref } from 'vue'
const a = 1
const b = ref(2)
// 像 defineExpose 这样的编译器宏不需要导入
defineExpose({
a,
b
})
</script>
7.生命周期
- 通过暴漏出来的API,传入生命周期函数,在不同阶段执行对应的代码
<script>
//组合式(解构赋值)
const {createApp, ref, reactive,onMounted} = Vue
var app = Vue.createApp({
//所有的代码写入到steup方法中
setup(){
const title = ref("测试")
onMounted(()=>{
//onMounted 测试
console.log('onMounted',title.value)
})
//返回定义的数据和方法
return {
title,
}
}
})
app.mount('#app')
</script>
- steup执行时机早于beforeCreate,他能用的生命周期API如下
| 生命周期钩子 | 说明 |
|---|---|
| onBeforeMount() | 在组件被挂载之前被调用,此时无法操作Dom |
| onMounted() | 在组件挂载完成后执行 |
| onBeforeUpdate() | 在组件即将因为响应式状态变更而更新其 DOM 树之前调用 |
| onUpdated() | 在组件因为响应式状态变更而更新其 DOM 树之后调用 |
| onBeforeUnmount() | 在组件实例被卸载之前调用 |
| onUnmounted() | 在组件实例被卸载之后调用 |
Vue3 组合式API的更多相关文章
- vue3组合式API
vue3组合式API 为什么要用组合式API,我们来看看它是如何解决vue2的局限性的 1.vue2的局限性 当组件内容越来越多,逻辑越来越复杂,可读性就会降低,并且难以维护. vue2组件采用配置式 ...
- 解决WebStorm无法正确识别Vue3组合式API的问题
1 问题描述 Vue3的组合式API无法在WebStorm中正确识别,表现为defineComponent等无法被识别: 2 尝试方案 猜想这种问题的原因是无法正确识别对应的Vue3库,笔者相信Web ...
- [Vue]浅谈Vue3组合式API带来的好处以及选项API的坏处
前言 如果是经验不够多的同志在学习Vue的时候,在最开始会接触到Vue传统的方式(选项式API),后边会接触到Vue3的新方式 -- 组合式API.相信会有不少同志会陷入迷茫,因为我第一次听到新的名词 ...
- vue3组合式API介绍
为什么要使用Composition API? 根据官方的说法,vue3.0的变化包括性能上的改进.更小的 bundle 体积.对 TypeScript 更好的支持.用于处理大规模用例的全新 API,全 ...
- Vue3 组合式 API 中获取 DOM 节点的问题
模板引用 Vue 提供了许多指令让我们可以直接操作组件的模板.但是在某些情况下,我们仍然需要访问底层 DOM 元素.在模板中添加一个特殊的属性ref就可以得到该元素. 访问模板引用 <scrip ...
- 第三十五篇:vue3,(组合式api的初步理解)
好家伙, 来一波核心概念:数据劫持是响应式的核心 1.由set up开始 (1)vue3中的一个新的配置项,值为一个函数. (2)组件中所用的到的:数据,方法,计算属性均要配置在set up中. (3 ...
- 一篇文章讲明白vue3的script setup,拥抱组合式API!
引言 vue3除了Composition API是一个亮点之外,尤大大又给我们带来了一个全新的玩意 -- script setup,对于setup大家相信都不陌生,而对于script setup有些同 ...
- Vue3笔记(二)了解组合式API的应用与方法
一.组合式API(Composition API)的介绍 官方文档: https://v3.cn.vuejs.org/guide/composition-api-introduction.html 组 ...
- Vue3全局APi解析-源码学习
本文章共5314字,预计阅读时间5-15分钟. 前言 不知不觉Vue-next的版本已经来到了3.1.2,最近对照着源码学习Vue3的全局Api,边学习边整理了下来,希望可以和大家一起进步. 我们以官 ...
- Vue3 Composition API写烦了,试试新语法糖吧—setup script
前言 Vue3发布近一年了,相信大家对Vue3的新特性,新语法都很熟悉了.那么在使用Composition API的过程中,有没有觉得整个过程比较繁琐.比如你的模板里用到了大量的state和方法的时候 ...
随机推荐
- RxJS 系列 – Mathematical and Aggregate Operators
前言 前几篇介绍过了 Creation Operators Filtering Operators Join Creation Operators Error Handling Operators T ...
- PTA甲级—图
1.图的遍历 1013 Battle Over Cities (25 分) 一种方法使用dfs求连通块的个数 #include <cstdio> #include <cstring& ...
- LoRaWAN网关价格干穿地板了
废话不多说,不要998,不要688,以太网版本只要398,4G版本只要498. 先上图片 1.1 产品特点 ◆ 高性能嵌入式硬件平台 ◆ 使用工业级 Cat.1 4G 模块 ◆ 宽压输入 DC 9-2 ...
- QT疑难杂症之QML程序中如何使用文件系统模型QFileSystemModel?
简介 本文介绍了 QML程序中如何使用树状控件TreeView展示QT文件系统模型QFileSystemModel中的数据,并给出了两种实现模式. 目录 QML程序中使用文件系统模型的代码 树状控件自 ...
- 运维管理平台OEM定制集成开发,激发IT价值
对硬件设备商而言,借助优秀的网管.运维管理平台,可以形成完整的产品解决方案,直接提升产品的形象和适用范围.同时还可以通过网管.运维管理平台,切入到外围的产品及集成领域,并在用户后续的升级改造活动中占据 ...
- war3辅助代码及运行方式
打开VS2019 点这个 自动生成这么一堆代码,全删了,就剩这些就行 然后点这里 然后向CPP里粘贴以下代码 #include "tlhelp32.h" HANDLE hwnd = ...
- 如何理解 .Net 中的 委托
// 委托 // 一种方法的声明和定义,也就是方法的占位符 // 一般使用在 参数 和 属性中 int Add(int a,int b) { return a + b; } // 定义委托的三种方法 ...
- 浅析RocketMQ
SpringBoot引入RocketMQ 快速构建单机RocketMQ https://www.haveyb.com/article/3079 参考这篇文章,快速构建单机RocketMQ 项目引入ja ...
- Java Z 垃圾收集器如何彻底改变内存管理
大家好,我是 V 哥,今天的内容来聊一聊 ZGC,Java Z Garbage Collector(ZGC)是一个低延迟垃圾收集器,旨在优化内存管理,主要用于大内存应用场景.它通过以下几个关键创新,彻 ...
- My SQL 列转行操作
原表结构如下,我们可以发现,"日运输量"和"车次"是在同一张表中相互独立的两个字段,即独立的两列数据,下面,我将系统中的测试数据以及代码全部放出来,以解释列转行 ...