介绍
这是一篇指导你如何使用Vue3进行开发的规范化指南,我将使用我多年开发vue3总结的经验来指导你如何进行大型vue3开发的规范化。 更多信息查阅引导文章
Vue组件
在Vue3项目中,始终建议将<script></script>
写在组件头部。并且始终使用ts
和setup
。
html
<script lang="ts" setup>
</script>
<template>
</template>
<style>
</style>
Vue3实际上允许Options
和Composition
同时存在。由于Composition
不能声明组件名,你可以在Options
中单独声明组件名,但不要在此添加其他逻辑。
一个组件的所有代码应不超过500行,如果超过,应该考虑拆分逻辑到其他组件,即使不需要复用。 如果你的html或者css部分过多导致文件行数难以压缩到500行以下,可以适当提升阈值。但始终不要,也完全没有必要超过1000行。
script
在script
中,应遵循如下的顺序编写代码。
ts
// 导入语句 import from
// 数据流输入语句 defineProps、defineEmits、inject、useStore
// 业务逻辑 ref、methods
// 数据流输出语句 defineExpose、 provide
- 导入语句
应包含import
- 数据流输入语句
应包含props
的定义,emit
的定义,依赖注入inject
,和状态管理的导入。
- 业务逻辑
主要包含响应式变量和方法的定义。实际上除了其他部分的代码都需要写在这里。
这部分代码不应该像Vue2一样使用data => methods => lifecycle
的顺序。而是应该将属于同一个功能点的代码聚集到一起。
ts
// 控制Dialog窗口显示
const showDialog = ref(false)
function show() {
showDialog.value = true
// 显示时需要的其他逻辑
}
function close() {
showDialog.value = false
// 清除校验的代码
// 关闭时需要的其他逻辑
}
onMounted(() => {
show() // 默认打开
// 对Dialog窗口做一些操作
})
// 表单相关逻辑
const formData = reactive({
name: '',
signature: ''
})
const formEl = ref<InstanceType<typeof HTMLFormElement>>()
const inputEl = ref<InstanceType<typeof HTMLInputElement>>()
const rule = [
// 表单校验规则...
]
onMounted(() => {
// 对表单做一些操作
})
尽管我们可以通过这种方式在同一个组件中包含多个功能点还能保持较高的可读性,但仍然建议将不同的功能拆分到其他组件中,即使不需要复用。除非多个功能点的逻辑之间存在较大的耦合关系,比如在以上例子中,我们可能需要在Dialog窗口显示时默认获取焦点;在Dialog窗口关闭时清除表单的校验,这样的耦合关系使得拆分组件的成本骤升,并且不需要复用逻辑,那么就没有必要拆分组件。
一个良好的Vue3组件的script
部分应不超过300行。
template
在template
中,可能会用到像Dialog
这样跳出组件视图之外的内容,推荐将这样的代码移动到template
的最下方,我们可以通过控制其显示的变量来快速地找到它的视图部分和逻辑部分。这样有利于进行后期维护。
html
<script setup lang="ts">
// Dialog逻辑部分
const showDialog = ref(false)
</script>
<template>
// 其他视图...
<Dialog v-model:show="showDialog">
// Dialog视图部分
</Dialog>
</template>
style
如果你正使用类似
tailwind css
这样的框架,可以忽略本节。
始终将同一部分视图的css聚集到一起,包括媒体查询和动画帧的代码,也因聚集到与之对应的部分,而不是始终定义到整个style
的最上方。
如果你使用类似sass
这样的编译器,应尽量保证class
作用域的最小化。例如我们经常使用active
类名来表示元素激活的样式,应善用&
符号。
scss
ul {
// ...
.item {
// ...
&.active {
// 在此定义激活的样式
}
}
.active {} // 不要在这里定义激活的样式
}
v-if/v-show
如何选择v-if
和v-show
一直是一个很困扰的问题。其实在大多数时候,直接选择v-show
即可,它会有相当好的表现。下文将演示一些需要用到v-if
的场景,其他情况下使用v-show
即可。
什么时候使用v-if
- 独立于组件视图存在、很少被渲染时时,例如作为悬浮窗口(如
Dialog
),通常需要配合defineAsyncComponent
使用,大大提升首次加载的速度,在大型项目中的优化效果非常明显。 - 用于控制显示的变量在整个组件的生命周期都不会改变时。例如用于控制适配不同屏幕的变量,屏幕大小一般在组件加载后就不会再改变了,因此可以看作在整个组件的生命周期都不会改变。
- 需要大量流程控制时。如果你需要大量的
else-if
、v-else
时,使用v-show
会非常不方便,其实在视图量小的时候,使用v-if
和v-show
的性能差距可以忽略不计,因此在考虑到可读性的情况下,可以使用v-if/v-else
来简化代码。
如果你需要对显示的元素使用无缝动画,那么应该始终使用
v-show
,因为v-if
在显示的时候需要等待组件渲染完全,会有明显的卡顿,更适合使用加载动画。
术语
在切换显示的过程中需要同时显示旧视图和新视图,营造平滑切换的视觉效果,称为无缝动画
在切换显示的过程中,需要等待新视图加载完成,并渲染一段加载动画,称为加载动画
v-for
使用v-for
时,应始终定义key
,并且最好不要使用索引作为key
,除非源数据的顺序始终不会发生改变。如果你没有好的key
,但又必须更改数据的顺序,可以生成一个唯一的随机数当作key
。
更多文章查看Vue3深度规范化专栏
专栏正在更新中...