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和方法的时候 ...
随机推荐
- 记一次 公司.NET项目部署在Linux环境压测时 内存暴涨分析
一:背景 讲故事 公司部署在某碟上的项目在9月份压测50并发时,发现某个容器线程.内存非正常的上涨,导致功能出现了异常无法使用.根据所学,自己分析了下线程和内存问题,分析时可以使用lldb或者wind ...
- Windbg常用命令及分析套路
自己也在使用windbg分析问题,但是属于刚入门所以转发下大神的总结:https://www.cnblogs.com/fj365/p/13295453.html 常用 !threadpool 查看线程 ...
- 更新iManager离线镜像包方法
例如将iserver_gisapplication_mapping_10_1_0.tar镜像更新到iManager仓库中 步骤一.将镜像导入本地镜像仓库 docker load -i iserver_ ...
- 仿函数(Functor)是什么?
仿函数(Functor) 仿函数是通过重载()运算符的类或结构体的对象.这样一个对象可以像普通函数一样被调用. 仿函数通常用于需要在对象内部保留状态或多次调用时有特定行为的情况. 特点: 仿函数是一个 ...
- Linux 循环设备 loop疑惑
什么是loop设备? loop设备是一种伪设备,是使用文件来模拟块设备的一种技术,文件模拟成块设备后, 就像一个磁盘或光盘一样使用.在使用之前,一个 loop 设备必须要和一个文件进行连接.这种结合方 ...
- 对3D图像进行裁剪
在对医学图像进行深度学习的过程中,我们会遇到图片过大,导致train的过程中网络会瘫痪,所以我们会考虑到对图像进行分割.比如一张155x240x240的图像,我们可以将他分割成一系列128x128x1 ...
- Pytorch常用的交叉熵损失函数CrossEntropyLoss()详解
本篇借鉴了这篇文章,如果有兴趣,大家可以看看:https://blog.csdn.net/geter_CS/article/details/84857220 1.交叉熵:交叉熵主要是用来判定实际的输出 ...
- signalR的身份认证
- element的图片上传预处理函数
/** 图片格式和大小的控制 */ beforeAvatarUpload (file) { // 允许上传 jpg 和 png 格式的图片 const isJPG = file.type === &q ...
- Promise 有几种状态,什么时候会进入catch?
Promise 有几种状态 三个状态:pending.fulfilled.reject 两个过程:padding -> fulfilled.padding -> rejected Prom ...