vue3的单组件编写【一】

文章目录

  • :tiger: 单组件的编写
    • :rainbow:全新的 setup 函数
      • :rocket: setup 的含义
      • :rocket:setup 的参数使用
      • :rocket: defineComponent 的作用
    • :rainbow: 组件的生命周期
      • :rocket: 升级变化
      • :rocket: 使用 3.x 的生命周期
    • :rainbow: 组件的基本写法
      • :rocket: 回顾 Vue 2
      • :rocket: 了解 Vue 3

🐯 单组件的编写

项目搭好了,第一个需要了解的是 Vue 组件的变化,由于这部分篇幅会非常大,所以会分成很多个小节,一部分一部分按照开发顺序来逐步了解。

因为 Vue 3 对 TypeScript 的支持真的是太完善了,并且 TypeScript 的发展趋势和市场需求度越来越高,所以接下来都将直接使用 TypeScript 进行编程。

对 TypeScript 不太熟悉的开发者,建议先阅读 快速上手 TypeScript 一章,有了一定的语言基础之后,再一边写代码一边加深印象。

🌈全新的 setup 函数

在开始编写 Vue 组件之前,需要了解两个全新的前置知识点:

  • 全新的 setup 函数,关系到组件的生命周期和渲染等问题
  • 写 TypeScript 组件离不开的 defineComponent API

🚀 setup 的含义

Vue 3 的 Composition API 系列里,推出了一个全新的 setup 函数,它是一个组件选项,在创建组件之前执行,一旦 props 被解析,并作为组合式 API 的入口点。

说的通俗一点,就是在使用 Vue 3 生命周期的情况下,整个组件相关的业务代码,都可以放在 setup 里执行。

因为在 setup 之后,其他的生命周期才会被启用。

基本语法:

// 这是一个基于 TypeScript 的 Vue 组件
import { defineComponent } from 'vue'export default defineComponent({setup(props, context) {// 在这里声明数据,或者编写函数并在这里执行它return {// 需要给 `<template />` 用的数据或函数,在这里 `return` 出去}},
})

可以发现在这段代码里还导入了一个 defineComponent API ,也是 Vue 3 带来的新功能,下文的defineComponent 的作用 将介绍其用法。

在使用 setup 的情况下,请牢记一点:不能再用 this 来获取 Vue 实例,也就是无法和 Vue 2 一样,通过 this.foothis.bar() 这样来获取实例上的数据,或者执行实例上的方法。

在使用 setup 的情况下 , 不能再用 this 来获取 Vue 实例;

在使用 setup 的情况下 , 不能再用 this 来获取 Vue 实例’;

在使用 setup 的情况下 , 不能再用 this 来获取 Vue 实例;

🚀setup 的参数使用

setup 函数包含了两个入参:

参数类型含义是否必传
propsobject由父组件传递下来的数据
contextobject组件的执行上下文

第一个参数 props

它是响应式的,当父组件传入新的数据时,它将被更新。

⭐️ ⭐️⭐️ 请不要解构它,这样会让数据失去响应性,一旦父组件发生数据变化,解构后的变量将无法同步更新为最新的值。

可以使用 Vue 3 全新的响应式 API toRef / toRefs 进行响应式数据转换,下文将会介绍全新的响应式 API 的用法。

第二个参数 context

context 只是一个普通的对象,它暴露三个组件的 Property :

属性类型作用
attrs非响应式对象未在 Props 里定义的属性都将变成 Attrs
slots非响应式对象组件插槽,用于接收父组件传递进来的模板内容
emit方法触发父组件绑定下来的事件

因为 context 只是一个普通对象,所以可以直接使用 ES6 解构。

平时使用可以通过直接传入 { emit } ,即可用 emit('xxx') 来代替使用 context.emit('xxx'),另外两个功能也是如此。

但是 attrsslots 请保持 attrs.xxxslots.xxx 的方式来使用其数据,不要进行解构,虽然这两个属性不是响应式对象,但对应的数据会随组件本身的更新而更新。

两个参数的具体使用,可查阅 组件之间的通信 一章详细了解。

🚀 defineComponent 的作用

defineComponent 是 Vue 3 推出的一个全新 API ,可用于对 TypeScript 代码的类型推导,帮助开发者简化掉很多编码过程中的类型声明。

比如,原本需要这样才可以使用 setup 函数:

import { Slots } from 'vue'// 声明 `props` 和 `return` 的数据类型
interface Data {[key: string]: unknown
}// 声明 `context` 的类型
interface SetupContext {attrs: Dataslots: Slotsemit: (event: string, ...args: unknown[]) => void
}// 使用的时候入参要加上声明, `return` 也要加上声明
export default {setup(props: Data, context: SetupContext): Data {// ...return {// ...}},
}

每个组件都这样进行类型声明,会非常繁琐,如果使用了 defineComponent , 就可以省略这些类型声明:

import { defineComponent } from "vue"
// 使用 `defineComponent` 包裹组件的内部逻辑
export default defineComponent({setup(props, context) {// ...return {// ...}},
})

代码量瞬间大幅度减少,只要是 Vue 本身的API , defineComponent 都可以自动推导其类型,这样开发和在编写组件的过程中,只需要维护自己定义的数据类型就可以了,可专注于业务。

🌈 组件的生命周期

在了解了 Vue 3 组件的两个前置知识点后,不着急写组件,还需要先了解组件的生命周期,这个知识点非常重要,只有理解并记住组件的生命周期,才能够灵活的把控好每一处代码的执行,使程序的运行结果可以达到预期。

🚀 升级变化

从 Vue 2 升级到 Vue 3 ,在保留对 Vue 2 的生命周期支持的同时,Vue 3 也带来了一定的调整。

Vue2 的生命周期写法名称是 Options API (选项式API) , Vue3 的生命周期写法名称叫 Composition API (组合式API) 。

Vue 3 组件默认支持 Options API ,而 Vue 2 可以通过 @vue/composition-api 插件获得 Composition API 的功能支持(其中 Vue 2.7 版本内置了该插件, 2.6 及以下的版本需要单独安装)。

为了减少理解成本,笔者将从读者的使用习惯上,使用 “ Vue 2 的生命周期” 代指 Options API 写法,用 “ Vue 3 的生命周期” 代指 Composition API 写法。

关于 Vue 生命周期的变化,可以从下表直观地了解:

Vue 2 生命周期Vue 3 生命周期执行时间说明
beforeCreatesetup组件创建前执行
createdsetup组件创建后执行
beforeMountonBeforeMount组件挂载到节点上之前执行
mountedonMounted组件挂载完成后执行
beforeUpdateonBeforeUpdate组件更新之前执行
updatedonUpdated组件更新完成之后执行
beforeDestroyonBeforeUnmount组件卸载之前执行
destroyedonUnmounted组件卸载完成后执行
errorCapturedonErrorCaptured当捕获一个来自子孙组件的异常时激活钩子函数

可以看到 Vue 2 生命周期里的 beforeCreatecreated ,在 Vue 3 里已被 setup 替代。

熟悉 Vue 2 的开发者应该都知道 Vue 有一个全局组件 <KeepAlive /> ,用于在多个组件间动态切换时缓存被移除的组件实例,当组件被包含在 <KeepAlive /> 组件里时,会多出两个生命周期钩子函数:

Vue 2 生命周期Vue 3 生命周期执行时间说明
activatedonActivated被激活时执行
deactivatedonDeactivated切换组件后,原组件消失前执行

⭐️ 虽然 Vue 3 依然支持 Vue 2 的生命周期,但是不建议混搭使用,前期可以继续使用 Vue 2 的生命周期作为过度阶段慢慢适应,但还是建议尽快熟悉并完全使用 Vue 3 的生命周期编写组件。

🚀 使用 3.x 的生命周期

在 vue3 的 Composition API 写法里, 每个生命周期函数都要先导入才可以使用,并且所有的生命周期函数统一放在 setup 里面运行。

如果需要达到vue2 的 beforeCreatecreated 生命周期的执行时机。 直接在 setup 里执行函数即可。

以下是几个生命周期的执行顺序对比:

import { defineComponent, onBeforeMount, onMounted } from 'vue'export default defineComponent({setup() {console.log(1)onBeforeMount(() => {console.log(2)})onMounted(() => {console.log(3)})console.log(4)},
})

最终将按照生命周期的顺序输出:

// 1
// 4
// 2
// 3

🌈 组件的基本写法

如果想在 Vue 2 里使用 TypeScript 编写组件,需要通过 Options API 的 Vue.extend 语法,或者是另外一种风格 Class Component 的语法声明组件,其中为了更好的进行类型推导, Class Component 语法更受开发者欢迎。

但是 Class Component 语法和默认的组件语法相差较大,带来了一定的学习成本,对于平时编写 JavaScript 代码很少使用 Class 的开发者,适应时间应该也会比较长。

因此 Vue 3 在保留对 Class Component 支持的同时,推出了全新的 Function-based Component ,更贴合 JavaScript 的函数式编程风格,这也是接下来要讲解并贯穿全文使用的 Composition API 新写法。

Composition API 虽然也是一个变化比较大的改动,但其组件结构并没有特别大的变化,区别比较大的地方在于组件生命周期和响应式 API 的使用,只要掌握了这些核心功能,上手 Vue 3 非常容易!

看到这里可能有开发者心里在想:

“这几种组件写法,加上视图部分又有 Template 和 TSX 的写法之分,生命周期方面 Vue 3 对 Vue 2 的写法又保持了兼容,在 Vue 里写 TypeScript 的组合方式一只手数不过来,在入门时选择合适的编程风格就遇到了困难,可怎么办?”

不用担心!笔者将九种常见的组合方式以表格的形式进行对比, Vue 3 组件最好的写法一目了然!

🚀 回顾 Vue 2

下三种写法声明 TypeScript 组件:

适用版本基本写法视图写法
Vue 2Vue.extendTemplate
Vue 2Class ComponentTemplate
Vue 2Class ComponentTSX

使用 TypeScript 来声明三种不同的组件,可以按照以下方式编写:

  1. 使用 Vue.extend 和模板(Template)的基本写法:
import Vue from 'vue';const MyComponent: Vue = Vue.extend({template: '<div>{{ message }}</div>',data() {return {message: 'Hello, Vue!'};}
});export default MyComponent;
  1. 使用 Class Component 和模板(Template)的写法:

为了更好地获得 TypeScript 类型推导支持,通常使用 Class Component 的写法,这是 Vue 官方推出的一个装饰器插件(需要单独安装):

import Vue from 'vue';
import Component from 'vue-class-component';// @Component 修饰符注明了此类为一个 Vue 组件
@Component({// 所有的组件选项都可以放在这里template: '<div>{{ message }}</div>'
})// 使用 Class 声明一个组件
export default class MyComponent extends Vue {// 初始数据可以直接声明为实例的 propertymessage: string = 'Hello, Vue!';// 组件方法也可以直接声明为实例的方法onClick(): void {window.alert(this.message)}
}
  1. 使用 Class Component 和 TSX 的写法:
import Vue, { VueConstructor } from 'vue';
import Component from 'vue-class-component';// @Component 修饰符注明了此类为一个 Vue 组件
@Component
export default class MyComponent extends Vue {message: string = 'Hello, Vue!';render(h: VueConstructor['createElement']) {return <div>{this.message}</div>;}
}

可在 Vue 2 官网的 TypeScript 支持 一章了解更多配置说明。

🚀 了解 Vue 3

Vue 3 从设计初期就考虑了 TypeScript 的支持,其中 defineComponent 这个 API 就是为了解决 Vue 2 对 TypeScript 类型推导不完善等问题而推出的。

在 Vue 3 ,至少有以下六种写法可以声明 TypeScript 组件:

适用版本基本写法视图写法生命周期版本官方是否推荐
Vue 3Class ComponentTemplateVue 2×
Vue 3defineComponentTemplateVue 2×
Vue 3defineComponentTemplateVue 3
Vue 3Class ComponentTSXVue 2×
Vue 3defineComponentTSXVue 2×
Vue 3defineComponentTSXVue 3

其中 defineComponent + Composition API + Template 的组合是 Vue 官方最为推荐的组件声明方式,本书接下来的内容都会以这种写法作为示范案例,也推荐开发者在学习的过程中,使用该组合进行入门。

下面看看如何使用 Composition API 编写一个最简单的 Hello World 组件:

<!-- Template 代码和 Vue 2 一样 -->
<template><p class="msg">{{ msg }}</p>
</template><!-- Script 代码需要使用 Vue 3 的新写法-->
<script lang="ts">
// Vue 3 的 API 需要导入才能使用
import { defineComponent } from 'vue'// 使用 `defineComponent` 包裹组件代码
// 即可获得完善的 TypeScript 类型推导支持
export default defineComponent({setup() {// 在 `setup` 方法里声明变量const msg = 'Hello World!'// 将需要在 `<template />` 里使用的变量 `return` 出去return {msg,}},
})
</script><!-- CSS 代码和 Vue 2 一样 -->
<style scoped>
.msg {font-size: 14px;
}
</style>

可以看到 Vue 3 的组件也是 <template /> + <script /> + <style /> 的三段式组合,上手非常简单。

其中 Template 沿用了 Vue 2 时期类似 HTML 风格的模板写法, Style 则是使用原生 CSS 语法或者 Less 等 CSS 预处理器编写。

⭐️ 需要注意的是,在 Vue 3 的 Composition API 写法里,数据或函数如果需要在 <template /> 中使用,就必须在 setup 里将其 return 出去,而仅在 <script /> 里被调用的函数或变量,不需要渲染到模板则无需 return

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

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

相关文章

DPAFNet:一种用于多模式脑肿瘤分割的残差双路径注意力融合卷积神经网络

DPAFNet: A Residual Dual-Path Attention-Fusion Convolutional Neural Network for Multimodal Brain Tumor Segmentation DPAFNet&#xff1a;一种用于多模式脑肿瘤分割的残差双路径注意力融合卷积神经网络背景贡献实验方法ulti-scale context feature extraction block&…

【Spring】之IoC与对象存取

未来的几周时间&#xff0c;大概率我会更新一下Spring家族的一些简单知识。而什么是Spring家族&#xff0c;好多同学还不是很清楚&#xff0c;我先来简单介绍一下吧&#xff1a; 所谓Spring家族&#xff0c;它其实就是一个框架&#xff0c;是基于Servlet再次进行封装的内容。为…

VMware——WindowServer2012R2环境安装mysql5.7.14解压版_互为主从(图解版)

目录 一、服务器信息二、192.168.132.35服务器上安装mysql&#xff08;主&#xff09;2.1、环境变量配置2.2、安装2.2.1、修改配置文件内容2.2.2、初始化mysql并指定超级用户密码2.2.3、安装mysql服务2.2.4、启动mysql服务2.2.5、登录用户管理及密码修改2.2.6、开启远程访问 三…

C++函数

转载知呼大佬06 - C函数 - 知乎 (zhihu.com) 06 - C函数 本期我们讨论的是 C 中的函数。 函数到底是什么呢&#xff0c;函数就是我们写的代码块&#xff0c;被设计用来执行特定的任务&#xff0c;以后我们学习 class 类的时候&#xff0c;这些块会被称为方法&#xff0c;但是…

windows电脑连接Android和iPhone真机调试

windows电脑连接Android和iPhone真机调试 目前用的是Hbuilder X编辑器&#xff0c;在正常情况下&#xff0c;Android手机需要在 "设置 ----> 更多设置 ----->关于手机 ------> 版本号&#xff08;手指点击5-7下即可打开开发者模式&#xff09;"(我的是vivo的…

hosts 配置本地映射不生效

关闭所有科学上网工具&#xff01;&#xff01;刷新 DNS 解析缓存&#xff1a;ipconfig /flushdns关闭所有浏览器访问映射地址时&#xff0c;带上端口号

给ORACLE创建一个用新用户并且给部分视图或表查询权限

这里写自定义目录标题 视图或表属于哪个用户查询登录所属账户 打开 cmd输入 sqlplus/nologconn 账号/密码 as sysdba创建用户赋予用户视图权限赋予用户视图权限连接数据库权限 视图或表属于哪个用户查询 表&#xff1a; SELECT * FROM ALL_OBJECTS WHERE OBJECT_TYPETABLE a…

MATLAB | 绘图复刻(十三) | 带NaN图例的地图绘制

有粉丝问我地图绘制如何添加NaN&#xff0c;大概像这样&#xff1a; 或者这样&#xff1a; 直接上干货&#xff1a; 原始绘图 假设我们有这样的一张图地图&#xff0c;注意运行本文代码需要去matlab官网下载Mapping Toolbox工具箱&#xff0c;但是其实原理都是相似的&…

C#的LINQ查询

当使用LINQ&#xff08;Language Integrated Query&#xff09;查询时&#xff0c;我们可以在C#中以一种类似于SQL的语法来查询数据。LINQ提供了一种统一的方式来查询各种数据源&#xff0c;如集合、数据库、XML等。 在上述示例中&#xff0c;我们使用LINQ查询来将两个列表根据…

LeetCode8-字符串转换整数(atoi)

目录 1.大神解法2.我的辣鸡解法:3.整数相加的溢出判断(chaGPT代码)4.整数相乘溢出判断(chatGPT代码) 到目前为止比较简单容易理解的一个代码: 参考链接: &#x1f517;:【8. 字符串转换整数 String to Integer (atoi) 【LeetCode 力扣官方题解】-哔哩哔哩】 1.大神解法 累乘和…

mysql redolog

一、什么是redolog日志 redolog又叫重做日志&#xff0c;处于存储引擎层&#xff0c;是innodb特有的日志。主要是为了实现事务的持久性而存在的。事务的持久性&#xff1a;只要提交了事务&#xff0c;出现停机或者崩溃的情况&#xff0c;都能将提交事务的数据修改正常持久化到…

被环境变量虐过一遍获得的启示

Oracle数据库环境存在两个数据库版本12C及19C&#xff0c;在执行一些操作时需要设置对应版本的环境变量 计划登录12C环境&#xff0c;于是按如下方式设置环境变量 export ORACLE_BASE/u01/app/oracle export ORACLE_HOME$ORACLE_HOME/product/12.2.0/dbhome_1 export ORACLE_S…

springboot踩坑一:添加webapp文件夹能访问jsp却找不到静态资源404

参考一下链接解决问题&#xff1a; https://www.xjx100.cn/news/670143.html?actiononClick

人工智能基础_机器学习046_OVR模型多分类器的使用_逻辑回归OVR建模与概率预测---人工智能工作笔记0086

首先我们来看一下什么是OVR分类.我们知道sigmoid函数可以用来进行二分类,那么多分类怎么实现呢?其中一个方法就是使用OVR进行把多分类转换成二分类进行计算. OVR,全称One-vs-Rest,是一种将多分类问题转化为多个二分类子问题的策略。在这种策略中,多分类问题被分解为若干个二…

【JS】Chapter14-深入面向对象

站在巨人的肩膀上 黑马程序员前端JavaScript入门到精通全套视频教程&#xff0c;javascript核心进阶ES6语法、API、js高级等基础知识和实战教程 &#xff08;十四&#xff09;深入面向对象 1. 编程思想 1.1 面向过程介绍 面向过程就是分析出解决问题所需要的步骤&#xff0c…

【Python百宝箱】Python测试工具大揭秘:从单元测试到Web自动化

前言 在现代软件开发中&#xff0c;测试是确保代码质量和稳定性的关键步骤。Python作为一门广泛应用的编程语言&#xff0c;拥有丰富的测试工具和库&#xff0c;从单元测试到Web自动化&#xff0c;覆盖了多个测试层面。本文将介绍一系列Python测试工具&#xff0c;帮助开发者选…

计算机毕业设计 基于SpringBoot的社区物资交易互助平台/系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

日志门面slf4j与常用的日志框架Log4j,Logback和Log4j2

slf4j 是众多日志框架接口的集合(俗称日志门面)&#xff0c;它不负责具体的日志实现&#xff0c;只在编译时负责寻找合适的日志框架进行绑定,各日志框架通过扩展jar包中的适配器与slf4j建立适配 SLF4J可以和Log4j、Logback、Log4j2、JUL等日志框架配合使用&#xff0c;这里主要…

【C++】泛型编程 ⑩ ( 类模板的运算符重载 - 函数实现 写在类外部的同一个 cpp 代码中 | 类模板 的 外部友元函数二次编译问题 )

文章目录 一、类模板 - 函数声明与函数实现分离1、类模板 外部 实现 构造函数2、类模板 外部 实现 普通函数3、类模板 外部 实现 友元函数( 1 ) 错误示例及分析 - 类模板 的 外部友元函数 二次编译 问题( 2 ) 正确写法 二、代码示例 - 函数声明与函数实现分离1、代码示例2、执行…

go同步锁 sync mutex

goroutine http://127.0.0.1:3999/concurrency/11 go tour 到此 就结束了. 继续 学习 可以 从 以下网站 文档 https://golang.org/doc/ https://golang.org/doc/code https://golang.org/doc/codewalk/functions/ 博客 https://go.dev/blog/ wiki 服务器教程 服务器…