灵活运用Vue 3中的setup函数—深入解析Composition API

在这里插入图片描述

新建项目,项目主入口为App.vue(主组件),新建child.vue(子组件)。

image-20230319152907890

1.1 setup 执行 时机问题

1.在主组件里引入子组件和ref:

import {ref} from 'vue'
import child from './components/child.vue'

2.template层:写一些基本提示性语句

<template><h1>父组件</h1><h3>{{ msg }}</h3><button @click="msg +='你好'">更新数据</button><hr><child :msg="msg"/>
</template>

3.注册放行子组件:

neme: 'App',//注册components: {child},

4.写setup方法:

setup() {const msg = ref("11")return {msg,}
},

5.子组件如下:使用props获取到父组件的值,查看beforeCreate和setup的执行顺序。

export default {name:'child',props:['msg'],beforeCreate(){console.log("beforeCreate执行");},setup(){console.log("setup执行了");return}
}

6.子组件template

<template><h2>子组件</h2><h3>msg:{{ msg }}</h3>
</template>

1.1.1 总结

1.setup 中一般都是返回一个对象,对象中的属性和方法都可以在 html 模版中直接使用

2.setup 是在 before Create 生命周期回调之前就执行了, 而且就执行一次

3.由此可以推断出:setup 在执行的时候, 当前的组件还没有创建出来, 也就意味着:组件实例对象 this 根本就不能用

this 是 undefined, 说明, 就不能通过 this 再去调用 data/computed/methods 中的相关内容了

1.2 setup细节

  • setup执行的时机
    • 在beforeCreate之前执行(一次), 此时组件对象还没有创建
    • this是undefined, 不能通过this来访问data/computed/methods / props
    • 其实所有的composition API相关回调函数中也都不可以
  • setup的返回值
    • 一般都返回一个对象: 为模板提供数据, 也就是模板中可以直接使用此对象中的所有属性/方法
    • 返回对象中的属性会与data函数返回对象的属性合并成为组件对象的属性
    • 返回对象中的方法会与methods中的方法合并成功组件对象的方法
    • 如果有重名, setup优先
    • 注意:
    • 一般不要混合使用: methods中可以访问setup提供的属性和方法, 但在setup方法中不能访问data和methods
    • setup不能是一个async函数: 因为返回值不再是return的对象, 而是promise, 模板看不到return对象中的属性数据
  • setup的参数
    • setup(props, context) / setup(props, {attrs, slots, emit})
    • props: 包含props配置声明且传入了的所有属性的对象
    • attrs: 包含没有在props配置中声明的属性的对象, 相当于 this.$attrs
    • slots: 包含所有传入的插槽内容的对象, 相当于 this.$slots
    • emit: 用来分发自定义事件的函数, 相当于 this.$emit
<template><h2>App</h2><p>msg: {{msg}}</p><button @click="fn('--')">更新</button><child :msg="msg" msg2="cba" @fn="fn"/>
</template><script lang="ts">
import {reactive,ref,
} from 'vue'
import child from './child.vue'export default {components: {child},setup () {const msg = ref('abc')function fn (content: string) {msg.value += content}return {msg,fn}}
}
</script>
<template><div><h3>{{n}}</h3><h3>{{m}}</h3><h3>msg: {{msg}}</h3><h3>msg2: {{$attrs.msg2}}</h3><slot name="xxx"></slot><button @click="update">更新</button></div>
</template><script lang="ts">import {ref,defineComponent
} from 'vue'export default defineComponent({name: 'child',props: ['msg'],emits: ['fn'], // 可选的, 声明了更利于程序员阅读, 且可以对分发的事件数据进行校验data () {console.log('data', this)return {// n: 1}},beforeCreate () {console.log('beforeCreate', this)},methods: {// update () {//   this.n++//   this.m++// }},// setup (props, context) {setup (props, {attrs, emit, slots}) {console.log('setup', this)console.log(props.msg, attrs.msg2, slots, emit)const m = ref(2)const n = ref(3)function update () {// console.log('--', this)// this.n += 2 // this.m += 2m.value += 2n.value += 2// 分发自定义事件emit('fn', '++')}return {m,n,update,}},
})
</script>

这是一个关于Vue 3的组件开发和setup函数使用的示例。我看到你提供了一个父组件 App.vue 和一个子组件 child.vue 的代码,以及关于setup函数的一些细节和总结。

首先,让我简要概括一下你的代码:

  • 在主组件 App.vue 中,你引入了子组件 child.vueref 函数。在模板中,你展示了一些基本的提示性语句,并包含一个更新数据的按钮和子组件 child
  • 你在 setup 函数中初始化了一个 msg 的响应式引用,并返回了这个引用,使其在模板中可用。
  • 子组件 child.vue 中,你使用 props 获取了父组件传递的值,并在 beforeCreatesetup 生命周期钩子中输出了一些信息。在模板中,你展示了父组件传递的消息。

接下来,让我帮你继续写下去:

setup函数的更多用法

setup函数中,可以执行各种初始化逻辑,包括对props的处理、引入其他模块、设置定时器等。

// 在 App.vue 的 setup 函数中
import { onMounted, onUnmounted } from 'vue';setup() {const msg = ref("1");// 添加一个计时器,每秒更新一次数据const timer = setInterval(() => {msg.value += '!';}, 1000);// 在组件挂载时启动计时器onMounted(() => {console.log('组件挂载了!');});// 在组件卸载时清除计时器onUnmounted(() => {clearInterval(timer);console.log('组件卸载了!');});return {msg,};
},

引入了onMountedonUnmounted函数,它们分别在组件挂载和卸载时执行。在挂载时,启动了一个计时器,每秒更新一次数据;在卸载时清除了计时器。

这样, App.vue 组件现在会在挂载时启动一个定时器,在卸载时清除定时器。

当然,继续讨论 Vue 3 中 setup 函数的更多用法和细节。

1.3 setup 函数的参数

在之前的例子中,我们在 setup 函数中只使用了 setup(),但实际上,setup 函数可以接受两个参数:propscontext(或者可以使用解构语法分别获取 attrsslotsemit)。这两个参数提供了更多的灵活性和访问权限。

App.vue 中,我们可以修改 setup 函数,接受 propscontext 参数:

setup(props, context) {const msg = ref("111");// 访问 propsconsole.log(props.msg);// 访问 context,包含 attrs、slots 和 emitconsole.log(context.attrs.msg2);console.log(context.slots);console.log(context.emit);return {msg,};
},

这样,我们就可以更灵活地处理传递给组件的属性以及与组件的上下文进行交互。

1.4 使用 Composition API

setup 函数是 Composition API 的一部分,它使得组件逻辑可以更灵活地组织和重用。在 setup 函数中,我们可以使用诸如 reactiverefwatch 等 Composition API 提供的功能。

setup() {const msg = ref("11");const count = ref(0);// 使用 watch 监听数据变化watch(() => msg.value, (newVal, oldVal) => {console.log(`消息从 ${oldVal} 更新为 ${newVal}`);});// 使用 reactive 创建响应式对象const state = reactive({name: "Vue 3",version: "3.0.0",});return {msg,count,state,};
},

这个例子中,我们使用了 watch 监听 msg 的变化,并使用 reactive 创建了一个包含 nameversion 的响应式对象 state

1.5 组合式函数的提取和重用

由于 setup 函数的灵活性,我们可以将一些逻辑提取为组合式函数,以便在多个组件中重用。例如,我们可以创建一个处理数据的函数:

// utilities.js
import { ref } from 'vue';export function useData(initialValue) {const data = ref(initialValue);function updateData() {data.value += '!';}return {data,updateData,};
}

然后在 setup 函数中使用:

// App.vue
import { useData } from './utilities.js';setup() {const { data: msg, updateData } = useData("111");return {msg,updateData,};
},

这样,我们可以更好地组织和重用代码。

1.6 注意事项

在使用 setup 函数时,需要注意一些事项:

  • 不要混合使用 setupdatamethods 等选项。在 setup 中可以访问 props,但在 datamethods 中无法访问 setup 中的属性和方法。
  • setup 函数不能是异步的,因为返回值将不再是一个对象,而是一个 Promise

1.7 插槽(Slots)和自定义事件

在 Vue 3 中,使用 setup 函数也能够更方便地处理插槽和自定义事件。在 child.vue 组件中,我们已经看到了如何使用插槽和自定义事件:

// child.vue
setup(props, { attrs, emit, slots }) {const m = ref(2);const n = ref(3);function update() {m.value += 2;n.value += 2;// 分发自定义事件emit('fn', '++');}return {m,n,update,};
},

在这个例子中,我们使用 emit 函数来分发自定义事件,父组件 App.vue 可以监听这个事件并执行相应的逻辑。

1.8 生命周期钩子

setup 函数中,Vue 3 提供了两个新的生命周期钩子函数:onBeforeMountonBeforeUnmount。这两个钩子分别在组件挂载前和卸载前执行:

// App.vue
setup() {const msg = ref("11");onBeforeMount(() => {console.log('组件即将挂载!');});onBeforeUnmount(() => {console.log('组件即将卸载!');});return {msg,};
},

这样,我们可以在组件生命周期的不同阶段执行特定的逻辑。

1.9 组件引入和注册

App.vue 中,我们使用 import 语句引入了 child.vue 组件,并使用 components 选项注册了这个组件:

// App.vue
import child from './components/child.vue';export default {components: {child,},// ...
};

这样,我们就可以在模板中直接使用这个组件。

1.10 总结

通过这个例子,我们更深入地了解了 Vue 3 中 setup 函数的使用方式和一些注意事项。Composition API 提供了更灵活和可复用的代码组织方式,让我们能够更好地处理组件的逻辑。

setup 函数中,我们可以访问 propscontext,使用 Composition API 的功能,处理插槽和自定义事件,以及执行一些生命周期钩子。这使得我们能够更好地组织和重用组件的代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/201236.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

爆款文章有诀窍,内容创作者如何能持续产出优质内容

内容营销人有没有这么一种共鸣&#xff1a;10 万 那么多&#xff0c;为什么不能多我一个&#xff1f; 通常&#xff0c;我们把浏览量 / 阅读量高、转评赞数量高的内容看作爆款&#xff0c;而数据如果达到 10 万 则是超级爆款。因为&#xff0c;阅读量高意味着内容得到了大量的曝…

Unsupervised Condition GAN

Unsupervised Condition GAN主要有两种做法&#xff1a; Direct Transformation 直接输入domain X图片&#xff0c;经过Generator后生成对应的domain Y的图像。这种转化input和output不能够差太多。通常只能实现较小的转化&#xff0c;比如改变颜色等。 Projection to Commo…

人工智能的时代---AI的影响

人工智能&#xff08;AI&#xff09;是当前科技领域的一个热门话题&#xff0c;它正在以前所未有的速度改变着我们的生活方式和工作方式。从智能家居到自动驾驶&#xff0c;从智能医疗到智能金融&#xff0c;人工智能正在渗透到我们生活的方方面面。在这篇文章中&#xff0c;我…

Java项目实战《苍穹外卖》 三、登录功能

测测你是什么人格吧&#xff0c;地址&#xff1a; MBTI 16种人格测试官网 系列文章目录 苍穹外卖是黑马程序员2023年的Java实战项目&#xff0c;作为业余练手用&#xff0c;需要源码或者课程的可以找我&#xff0c;无偿分享 Java项目实战《苍穹外卖》 一、项目概述Java项目实战…

10月起个税系统升级,3个月个税零申报将收到提示

近日&#xff0c;自然人电子税务局扣缴端升级了&#xff0c;升级后对于工资薪金收入连续三个月为零的纳税人&#xff0c;系统会自动出现以下提示。这个提示主要为了避免企业长期对已经离职的员工进行零申报&#xff0c;导致数据不准确和资源浪费。HR在申报个税时&#xff0c;一…

虚拟摇杆OnJoystickMove未被调用,角色不移动

更改interaction type 为 event notification

什么是应急演练脚本?其设计原则是什么?

应急演练脚本是一种系统性、有计划的模拟性文件&#xff0c;旨在测试和评估组织在紧急情况下的应对能力。这种脚本提供了一系列步骤和场景&#xff0c;以确保团队能够高效、协调地应对各种紧急事件。以下将详细探讨应急演练脚本的定义、设计原则以及实施过程。 一、应急演练脚本…

React整理总结(五、Redux)

1.Redux核心概念 纯函数 确定的输入&#xff0c;一定会产生确定的输出&#xff1b;函数在执行过程中&#xff0c;不能产生副作用 store 存储数据 action 更改数据 reducer 连接store和action的纯函数 将传入的state和action结合&#xff0c;生成一个新的state dispatc…

IPFoxy:什么是数据中心代理IP?好用吗?

数据中心代理是代理IP中最常见的类型&#xff0c;也被称为机房IP。这些代理服务器为用户分配不属于 ISP&#xff08;互联网服务提供商&#xff09;而来自第三方云服务提供商的 IP 地址。数据中心代理的最大优势——它们允许在访问网络时完全匿名。 如果你正在寻找海外代理IP&am…

【Java 进阶篇】揭秘 Jackson:Java 对象转 JSON 注解的魔法

嗨&#xff0c;亲爱的同学们&#xff01;欢迎来到这篇关于 Jackson JSON 解析器中 Java 对象转 JSON 注解的详细解析指南。JSON&#xff08;JavaScript Object Notation&#xff09;是一种常用于数据交换的轻量级数据格式&#xff0c;而 Jackson 作为一款优秀的 JSON 解析库&am…

js进阶笔记之原型,原型链

目录 1、原型对象 constructor 属性 对象原型 2、原型链 3、instanceof 4、原型继承 1、原型对象 面向过程就是分析出解决问题所需要的步骤&#xff0c;然后用函数把这些步骤一步一步实现&#xff0c;使用的时候再一个一个的依次调用就可以了。 面向对象是把事务分解成为…

python刷题笔记1(42例题)

1. split()函数 str.split([sep [, maxsplit]]) 分割字符串&#xff0c;返回一个数组 2. 判断子串 # 判断子串是否在主串里面&#xff0c;是则输出“Yes”&#xff0c;否则输出“No” str1 input("子串&#xff1a;") str2 input("主串:") if str1 in s…

最新绿豆APP源码苹果CMS影视插件版本/原生JAVA源码+反编译开源+免授权

源码简介&#xff1a; 最新绿豆APP源码苹果CMS影视插件版本&#xff0c;它是原生JAVA源码反编译开源免授权&#xff0c;绿豆影视对接苹果CMS&#xff0c;它可以支持多功能自定义DIY页面布局。 1、新版绿豆视频APP视频6.1插件版反编译指南及教程 2、后端插件开源&#xff0c;可…

创建 Springboot 项目

前言 创建 Spring Boot 项目是很多Java开发人员入门的重要一步&#xff01; 欢迎来到本篇关于创建 Spring Boot 项目的博客&#xff01;Spring Boot作为一个快速、便捷的开发框架&#xff0c;为我们提供了简化和加速应用程序开发的利器。 在这个数字化时代&#xff0c;快速响…

在Jupyter Lab中使用多个环境,及魔法命令简介

一、Jupyter Lab使用conda虚拟环境 1、给虚拟环境添加 ipykernel 方法一: 创建环境时直接添加ipykernel 方法&#xff1a;conda create -n 【虚拟环境名称】python3.8 ipykernel实例如下&#xff1a; conda create -n tensorflow_cpu python3.8 ipykernel 方法二&#xff…

解决Vision Transformer在任意尺寸图像上微调的问题:使用timm库

解决Vision Transformer在任意尺寸图像上微调的问题&#xff1a;使用timm库 文章目录 一、ViT的微调问题的本质二、Positional Embedding如何处理1&#xff0c;绝对位置编码2&#xff0c;相对位置编码3&#xff0c;对位置编码进行插值 三、Patch Embedding Layer如何处理四、使…

【0到1学习Unity脚本编程】第一人称视角的角色控制器

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;【0…

7.Gin 路由详解 - 路由分组 - 路由文件抽离

7.Gin 路由详解 - 路由分组 - 路由文件抽离 前言 在前面的示例中&#xff0c;我们直接将路由的定义全部写在 main.go 文件中&#xff0c;如果后面 路由越来越多&#xff0c;那将会越来越不好管理。 所以&#xff0c;下一步我们应该考虑将路由进行分组管理&#xff0c;并且将其抽…

腾讯云代金券怎么领取(腾讯云代金券在哪领取)

腾讯云代金券是可抵扣费用的优惠券&#xff0c;领券之后新购、续费、升级腾讯云相关云产品可以直接抵扣订单金额&#xff0c;节省购买腾讯云的费用&#xff0c;本文将详细介绍腾讯云代金券的领取方法和使用教程。 一、腾讯云代金券领取 1、新用户代金券【点此领取】 2、老用户…

SVN创建分支

一 从本地创建方式可指定版本号进行分支创建。 1、在本地目录右击 -----> 点击branch/tag(分支/标签) From: 源&#xff0c;可指定具体的版本号&#xff0c; To path: 可通过"..."选择分支路径 最后点击确定&#xff0c;交由服务器执行创建。 二 通过SVN客…