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的更多相关文章

  1. vue3组合式API

    vue3组合式API 为什么要用组合式API,我们来看看它是如何解决vue2的局限性的 1.vue2的局限性 当组件内容越来越多,逻辑越来越复杂,可读性就会降低,并且难以维护. vue2组件采用配置式 ...

  2. 解决WebStorm无法正确识别Vue3组合式API的问题

    1 问题描述 Vue3的组合式API无法在WebStorm中正确识别,表现为defineComponent等无法被识别: 2 尝试方案 猜想这种问题的原因是无法正确识别对应的Vue3库,笔者相信Web ...

  3. [Vue]浅谈Vue3组合式API带来的好处以及选项API的坏处

    前言 如果是经验不够多的同志在学习Vue的时候,在最开始会接触到Vue传统的方式(选项式API),后边会接触到Vue3的新方式 -- 组合式API.相信会有不少同志会陷入迷茫,因为我第一次听到新的名词 ...

  4. vue3组合式API介绍

    为什么要使用Composition API? 根据官方的说法,vue3.0的变化包括性能上的改进.更小的 bundle 体积.对 TypeScript 更好的支持.用于处理大规模用例的全新 API,全 ...

  5. Vue3 组合式 API 中获取 DOM 节点的问题

    模板引用 Vue 提供了许多指令让我们可以直接操作组件的模板.但是在某些情况下,我们仍然需要访问底层 DOM 元素.在模板中添加一个特殊的属性ref就可以得到该元素. 访问模板引用 <scrip ...

  6. 第三十五篇:vue3,(组合式api的初步理解)

    好家伙, 来一波核心概念:数据劫持是响应式的核心 1.由set up开始 (1)vue3中的一个新的配置项,值为一个函数. (2)组件中所用的到的:数据,方法,计算属性均要配置在set up中. (3 ...

  7. 一篇文章讲明白vue3的script setup,拥抱组合式API!

    引言 vue3除了Composition API是一个亮点之外,尤大大又给我们带来了一个全新的玩意 -- script setup,对于setup大家相信都不陌生,而对于script setup有些同 ...

  8. Vue3笔记(二)了解组合式API的应用与方法

    一.组合式API(Composition API)的介绍 官方文档: https://v3.cn.vuejs.org/guide/composition-api-introduction.html 组 ...

  9. Vue3全局APi解析-源码学习

    本文章共5314字,预计阅读时间5-15分钟. 前言 不知不觉Vue-next的版本已经来到了3.1.2,最近对照着源码学习Vue3的全局Api,边学习边整理了下来,希望可以和大家一起进步. 我们以官 ...

  10. Vue3 Composition API写烦了,试试新语法糖吧—setup script

    前言 Vue3发布近一年了,相信大家对Vue3的新特性,新语法都很熟悉了.那么在使用Composition API的过程中,有没有觉得整个过程比较繁琐.比如你的模板里用到了大量的state和方法的时候 ...

随机推荐

  1. 技术解析 | ZEGO 移动端超分辨率技术

    ​ 即构超分追求:速度更快.效果更好.码率更低.机型更广. 超分辨率(Super Resolution, SR)是从给定的低分辨率(Low Resolution, LR)图像中恢复高分辨率(High ...

  2. Parquet.Net: 将 Apache Parquet 移植到 .NET

    Parquet.Net 是一个用于读取和写入 Apache Parquet 文件的纯 .NET 库,使用MIT协议开源,github仓库:https://github.com/aloneguid/pa ...

  3. Spring —— bean实例化

    bean 实例化 bean本质上就是对象,创建bean使用构造方法完成(反射)      构造方法(常用)        静态工厂*        实例工厂*        FactoryBean(实 ...

  4. JSP+Java编程资源

    <JSP+Servlet+Tomcat应用开发从零开始学(第2版)>源码课件视频下载地址: https://pan.baidu.com/s/1HkFRul3wYBxe-skXCoQPwg ...

  5. C4996 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.

    错误原因 VS平台认为scanf函数不安全,要求换成scanf_s函数 解决方案 方案一:将scanf换成scanf_s[不建议] 将scanf换成scanf_s 但是,scanf_s函数只能在vs上 ...

  6. iotdb时序数据库常见使用命令

    docker 安装IOTDB核心代码: #docker启动 docker run -d -p 6667:6667 -p 31999:31999 -p 8181:8181 --name some-iot ...

  7. C#WebApi 对数据进行缓存加快前请求数据的速度

    using ClassLibrary1; using ClassLibrary2; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions ...

  8. vant 2 的 toast

    因为toast使用的场景比较频繁,所以在 注册使用 Toast 的时候,直接在Vue实列的原型上添加了toast方便我们使用 : 格式:this.$toast.fail()      this.$to ...

  9. JOI Open 2016

    T1 JOIRIS 你在玩俄罗斯方块,游戏区域是一个宽度为 \(n\),高度足够大的矩形网格.初始时第 \(i\) 列有 \(a_i\) 个方块. 给定参数 \(k\),你可以做不超过 \(10^4\ ...

  10. 云原生爱好者周刊:玩 Kubernetes 游戏,赢取免费机票

    云原生一周动态要闻: Grafana 8.2.2 发布 OSM(Open Service Mesh)发布 v1.0 的第一个候选版本 谷歌宣布推出 Google Distributed Cloud K ...