vue3 中 defineComponent 的作用
这篇文章主要介绍了vue3中defineComponent 的作用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
vue3中,新增了 defineComponent ,它并没有实现任何的逻辑,只是把接收的 Object 直接返回,它的存在是完全让传入的整个对象获得对应的类型,它的存在就是完全为了服务 TypeScript 而存在的。
我都知道普通的组件就是一个普通的对象,既然是一个普通的对象,那自然就不会获得自动的提示,
import { defineComponent } from 'vue'
const component = {
name: 'Home',
props:{
data: String,
},
setup // 没有该有的提示,这非常的不友好
}
export default component
但是当我们加上 defineComponent() 之后,就完全不一样了,可以获得自动提示,vue2、vue3的自动提示都有
import { defineComponent } from 'vue'
const component = {
name: 'Home',
props:{
data: String,
},
setup(){
// setup 可接受两个参数,一个props,和 context
}
}
export default component
接下来看看 setup 中的两个参数 props 与 context ,
props指组件传递来的参数,并且ts可以推论出props的类型.props也就是 vue2 中组件中的 props
context 有三个属性 attrs slots emit 分别对应vue2中的attrs属性、slots插槽、$emit发送事件
import { defineComponent } from 'vue'
const component = {
name: 'Home',
props:{
data: String,
},
setup(props, context){
// props.data
// context.attrs context.slots context.emit
}
}
export default component
扩展知识:
vue3之组件结构(defineComponent,setup函数)
在vue3中,对组件整体结构做一些调整,先看一个组件案例:
import {ref, reactive, defineComponent, Ref, onMounted} from "vue";
import {settingsStore} from "/@/store/module/settings";
import {IRoleList} from "/@/interface/role/list.interface";
import {IHttpResult} from "/@/interface/common.interface";
import { ILogListParams } from "/@/interface/settings/log.interface";
export default defineComponent({
name: "LogList",
setup() {
const logList: Ref<IRoleList[]> = ref([]);
const columns = [
...
];
const pagination = ref({
"show-quick-jumper": true,
total: 100,
current: 1,
"show-size-changer": true,
"show-total": (total: number, range: number[]) => `${range[0]}-${range[1]} 共 ${total} 条`,
"pageSize": 10
});
const columnsList = ref(columns);
const params: ILogListParams = reactive({
page: 1,
pageSize: 10
});
onMounted(() => {
findLogList();
});
/*查询日志列表*/
const findLogList = () => {
settingsStore.findLogList(params).then((res: IHttpResult) => {
const data = res.data;
pagination.value.total = data.total;
logList.value = data.list;
});
};
/*修改状态*/
const onChange = (pagination: {current: number, pageSize: number}) => {
params.page = pagination.current;
params.pageSize = pagination.pageSize;
};
/*删除*/
const onDelete = (id: number) => {
alert(id);
};
return {
columnsList,
logList,
onDelete,
onChange,
pagination
};
}
});
从上面组件代码中,可以看出在vue3中没有this对象, 所有的逻辑代码都写在setup方法里面.
若是要在HTML模板页面中使用变量或者方法, 需要在setup方法return出去.
setup是Vue3 的一大特性函数, 它有几个特性:
1、setup函数是处于 生命周期函数 beforeCreate 和 Created 两个钩子函数之间的函数
2、setup函数是 Composition API(组合API)的入口
3、在setup函数中定义的变量和方法最后都是需要 return 出去的 不然无法再模板中使用
setup函数的注意点:
vue3虽然支持vue2.x版本的写法,但也有一些要注意的地方
1、由于在执行 setup函数的时候,还没有执行 Created 生命周期方法,所以在 setup 函数中,无法使用 data 和 methods 的变量和方法
2、由于我们不能在 setup函数中使用 data 和 methods,所以 Vue 为了避免我们错误的使用,直接将 setup函数中的this修改成了 undefined
3、setup函数只能是同步的不能是异步的
- 上面的组件中用defineComponent包裹了组件;
- defineComponent函数,只是对setup函数进行封装,返回options的对象;
- defineComponent最重要的是:在TypeScript下,给予了组件 正确的参数类型推断 。
- defineComponent可以给组件的setup方法准确的参数类型定义.
- defineComponent 可以接受显式的自定义 props 接口或从属性验证对象中自动推断
- defineComponent 可以正确适配无 props、数组 props 等形式
- 引入 defineComponent() 以正确推断 setup() 组件的参数类型
延申:
文档中第一句话很容易看懂,说白了就是从实现上看,用了或者跟不用这个api没多大区别但是呢,第二句话说的好像又有一些区别,不过我没太看懂。。。于是我自己的第一个问题就来了:
问题一:defineComponent 这个API用起来到底和不用有什么区别???
1. 显示 Vue Options 提示。
这个API一般是在ts或者tsx文件中使用的,所以,当我们创建了一个这种类型的文件后,它是不知道我们是要去写 vue 实例代码的,所以在这种情况下,我们需要defineComponent来帮我们做内部的一些options的提示,我们可以看一个使用了defineComponent和没有使用defineComponent的例子:
当然这背后的原理是利用 TypeScript 定义了defineComponent 参数类型实现的。
2. 给予正确的参数类型推断。
拿 setup 来说,defineComponent 可以为 setup 函数的 props 传参做出正确的类型推断,看下图:
如果没有使用 defineComponent 的话,是没有办法推断出来的,需要自己显式地去定义类型。
3. 可返回一个合成类型的构造函数。
这也是官方文档中所说的,我在代码中尝试了一下,发现确实可以在其返回的构造函数中去定义一些钩子和属性等,如下图:
这就是目前我对这个API的一些理解吧~后续有新发现再补充
到此这篇关于vue3中defineComponent 的作用的文章就介绍到这了,
更新补充:
推荐阅读
-
vue3 中的 toRaw
-
询问如何直观比较损失在连体网络 EN 中的作用
-
分析 "扫荡 "过程中的相互作用
-
西门子 PLC 中各组织模块 OB 的作用 (OB1, OB100 ......)
-
常用模块在 python 中的作用
-
Yu, C. / Yu, M. / Liang, H. J. BM:光激活脂质体在缺氧肿瘤治疗中的重复按需释药和免疫增强作用
-
什么是数据库事物?为什么需要数据库事物,事物有哪些特征?事物的隔离级别是什么?-1.什么是数据库事务? 1.事务是作为一个逻辑单元执行的一系列操作。一个逻辑工作单元必须具备四个属性,即ACID(原子性、一致性、隔离性和持久性)属性,只有这样才能成为事务: 原子性 2.事务必须是一个原子工作单元;它的数据修改要么全部执行,要么全部不执行。 一致性 3.事务完成时,所有数据必须保持一致。在相关数据库中,所有规则都必须适用于事务的修改,以保持所有数据的完整性。事务结束时,所有内部数据结构(如 B 树索引或双向链接表)必须正确无误。 隔离 4.并发事务的修改必须与其他并发事务的修改隔离。一个事务会在另一个并发事务修改之前或之后查看某一状态下的数据,而不会查看中间状态下的数据。这就是所谓的可序列化,因为它允许重新加载起始数据和重放一系列事务,从而使数据最终处于与原始事务执行时相同的状态。 持久性 5.事务完成后,它对系统的影响是永久性的。即使在系统发生故障的情况下,修改也会保留。 2. 为什么需要数据库事物,事物有哪些特征? 事物对数据库的作用是对数据进行一系列操作,要么全部成功,要么全部失败,防止出现中间状态,确保数据库中的数据始终处于正确、和谐的状态。 特征:原子性、一致性、隔离性、持久性,以及其他特征 原子性(Atomicity):所有操作在事务开始后,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出现错误时,会回滚到事务开始前的状态,所有操作就像没有发生一样。也就是说,事务是一个不可分割的整体,就像化学中的原子一样,是物质的基本单位。 一致性(Consistency):在事务开始之前和结束之后,数据库的完整性约束都没有被破坏。例如,如果 A 转钱给 B,A 不可能扣除这笔钱,但 B 却没有收到这笔钱。 隔离:在同一时间内,只允许一个事务请求相同的数据,不同事务之间没有干扰。例如,甲正在从一张银行卡上取款,在甲取款过程结束之前,乙不能向这张卡转账。 持久性(耐用性):事务完成后,事务对数据库的所有更新都将保存到数据库中,无法回滚 3.事务的隔离级别有哪些? 数据库事务有四种隔离级别,从低到高分别是未提交读取(Read uncommitted)、已提交读取(Read committed)、可重复读取(Repeatable read)、可序列化(Serializable)。此外,事务的并发操作中可能会出现脏读、不可重复读、幽灵读等情况。事务并发问题 脏读:事务 A 读取事务 B 更新的数据,然后事务 B 回滚操作,那么事务 A 读取的数据就是脏数据。 不可重复读取:事务 A 多次读取同一数据,事务 B 在事务 A 多次读取期间更新并提交数据,导致事务 A 多次读取同一数据时结果不一致。 幻影读取:系统管理员 A 将数据库中所有学生的具体分数改为 ABCDE 等级,但系统管理员 B 在此时插入了具体分数的记录,当系统管理员 A 更改结束后发现仍有一条记录未被更改,仿佛发生了幻觉,这称为幻影读取。 小结:不可重复读和幻读容易混淆,不可重复读侧重于修改,幻读侧重于增删。解决不可重复读问题只需锁定满足条件的行,解决幻读问题则需要锁定表 MySQL 事务隔离级别
-
Python 中的 "枚举 "函数有什么作用?
-
介绍枚举在 Java 开发中的作用和用法
-
hdfs 在 hadoop 中的作用是什么?