9.9 KiB
以下是一份 Vue 3 和 TypeScript 的编程规范:
1. 组件定义
- 推荐使用
defineComponent来定义组件,以获取 TypeScript 的类型支持。
import { defineComponent } from 'vue'
export default defineComponent({
// 组件选项
})
2. 数据定义
- 使用
reactive定义响应式对象。 - 使用
ref定义响应式单值。 - 使用
computed定义计算属性。
import { reactive, ref, computed } from 'vue'
const state = reactive({
count: 0,
message: 'Hello Vue 3'
})
const count = ref(0)
const doubledCount = computed(() => state.count * 2)
3. 生命周期钩子
- 使用
onMounted、onUpdated等生命周期钩子,而不是beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeUnmount、unmounted。
import { onMounted } from 'vue'
onMounted(() => {
console.log('Component is mounted.')
})
4. 组件通信
- 使用
props和emit实现父子组件通信。 - 使用
provide和inject实现祖先和后代组件通信。 - 不再推荐使用
event bus进行任意组件间的通信,可以使用 Vuex 或者全局provide/inject替代。
// 父组件
<ChildComponent @my-event="handleEvent" />
// 子组件
this.$emit('my-event', eventData)
5. 异步处理
- 使用
async/await进行异步处理。 - 使用
Suspense和async setup()处理异步依赖。
import { ref, onMounted } from 'vue'
import axios from 'axios'
onMounted(async () => {
const response = await axios.get('https://api.example.com/data')
data.value = response.data
})
6. Vue Router 和 Vuex
- 使用 Vue Router 4 和 Vuex 4,它们是为 Vue 3 重新设计的。
- 使用
useRouter和useRoute钩子函数在组件中使用 router。 - 使用
useStore钩子函数在组件中使用 Vuex store。
import { useStore } from 'vuex'
import { useRouter } from 'vue-router'
const store = useStore()
const router = useRouter()
7. 组件模板
- 使用
v-model代替.sync修饰符进行双向绑定。 - 使用
v-for和:key渲染列表。 - 使用
v-if和v-else、v-else-if进行条件渲染。 - 使用
v-on或者@监听事件。 - 使用
v-bind或者:绑定属性。
<template>
<div v-if="condition">If block</div>
<div v-else>Else block</div>
<ul>
<li v-for="(item, index) in list" :key="index">{{ item }}</li>
</ul>
<button @click="handleClick">Click me</button>
</template>
-
使用类型注解和接口
在 TypeScript 中,尽可能使用类型注解和接口来提供更完善的类型信息和类型检查。这将有助于发现和预防错误。
interface User { name: string; age: number; } const user: User = { name: 'John', age: 30 } -
模块化和组件化
尽可能将功能和逻辑模块化和组件化,使得代码更易于理解和维护。特别是使用 Composition API 时,可以将公共的逻辑封装成 composable 函数。
下面是一个使用
Suspense和axios的示例,这个示例将会从一个 JSON Placeholder API 获取数据:首先,我们创建一个 composable 函数,用于获取数据:
import { ref } from 'vue' import axios from 'axios' export function useAsyncData(url: string) { const data = ref(null) const error = ref(null) const fetchData = async () => { try { const response = await axios.get(url) data.value = response.data } catch (e) { error.value = e } } return { data, error, fetchData } }然后,我们创建一个 Vue 组件来使用这个函数:
<template> <Suspense> <template #default> <div v-if="error">{{ error.message }}</div> <div v-else>{{ data }}</div> </template> <template #fallback> <div>Loading...</div> </template> </Suspense> </template> <script lang="ts"> import { defineComponent, onMounted } from 'vue' import { useAsyncData } from './composables/useAsyncData' export default defineComponent({ setup() { const { data, error, fetchData } = useAsyncData('https://jsonplaceholder.typicode.com/posts/1') onMounted(fetchData) return { data, error } }, }) </script> <style scoped> /* 在这里添加 CSS 样式 */ </style>在这个示例中,我们在
useAsyncData函数中获取数据。当onMounted钩子函数被调用时(也就是当组件挂载完成后),我们开始获取数据。这个过程是异步的,因此我们在Suspense组件的#fallback插槽中显示一个 "Loading..." 的提示。一旦数据加载完成,Suspense组件的#default插槽就会被渲染,并显示获取到的数据。 -
良好的代码风格
遵循一致的代码风格和代码质量规则,例如使用 ESLint 和 Prettier 来检查和格式化代码。
-
单元测试和端到端测试
对关键的组件和函数编写单元测试,对用户的主要操作路径编写端到端测试,确保功能的正确性。
-
注释和文档
对复杂的逻辑和函数编写注释,提供必要的项目文档,帮助其他开发者理解和使用你的代码。
-
以下是 Vue 2 中被废弃或改变的部分API,以及在 Vue 3 中的替代方案:
| Vue 2.x | Vue 3.0 | 说明 |
|---|---|---|
Vue.set / this.$set |
响应式数据现在是默认的,无需使用这些方法 | Vue 3 的响应式系统是从头开始构建的,所有的对象和数组都是响应式的 |
Vue.delete / this.$delete |
无需使用这些方法 | 在 Vue 3 中,你只需要使用 delete 操作符即可 |
filters |
无对应项 | Vue 3 不再支持过滤器,建议使用计算属性或方法替代 |
Vue.observable |
reactive |
用 reactive 替代 Vue.observable,实现数据的响应式 |
Vue.prototype |
app.config.globalProperties |
在 Vue 3 中,全局 API 已经改变,Vue.prototype 被 app.config.globalProperties 替代 |
Vue.component, Vue.directive, Vue.mixin, Vue.use |
app.component, app.directive, app.mixin, app.use |
全局注册的 API 改变,如 Vue.component 变为 app.component |
beforeDestroy 和 destroyed 生命周期钩子 |
beforeUnmount 和 unmounted |
生命周期钩子名字变化,beforeDestroy 和 destroyed 分别改为 beforeUnmount 和 unmounted |
$on, $off, $once |
无对应项 | Event Bus方法被移除,需要用户自行实现或者使用第三方库 |
v-model 在自定义组件上使用 |
需要明确的 modelValue 和 update:modelValue |
Vue 3 对 v-model 的改动使其在自定义组件上更具灵活性 |
functional 选项 |
无对应项 | Vue 3 不再支持函数式组件的写法,而是推荐使用 render 函数或 setup 函数 |
异步组件的 functional 写法 |
defineAsyncComponent |
异步组件的创建方式更改,通过 defineAsyncComponent 方法创建 |
destroyed 和 beforeDestroy 钩子函数 |
unmounted 和 beforeUnmount |
生命周期钩子的名称已改为更直观的名称,以更好地表示其在组件实例生命周期中的角色 |
Vue.extend |
defineComponent |
Vue 3 使用 defineComponent 方法定义组件,有更好的类型推断 |
注意:Vue 3 对于 Options API 和 Composition API 提供了完全的支持,你可以在一个组件中混合使用这两种 API。不过,为了代码的一致性和可读性,建议在一个项目中选择一种 API 并坚持使用。
- 以下是 Vue 3.0 中的 Composition API 函数的基本说明,以及与 Options API 的对比
| Composition API | 说明 | 对应的 Options API |
|---|---|---|
setup |
setup 是一个新引入的组件选项,用于使用 Composition API。它是组件内部使用 Composition API 的入口。 |
无 |
ref |
ref 函数用于创建一个响应式的数据。它接收一个参数,返回一个响应式的 Ref 对象。 |
data |
reactive |
reactive 函数用于创建一个响应式的对象。它接收一个普通对象,返回一个响应式的对象。 |
data |
computed |
computed 函数用于创建一个计算属性。它接收一个 getter 函数或者一个具有 getter 和 setter 的对象,返回一个响应式的 Ref 对象。 |
computed |
watch |
watch 函数用于响应式地跟踪和触发副作用。它接收一个响应式的源和一个执行副作用的回调函数。 |
watch |
watchEffect |
watchEffect 函数用于立即执行传入的一个函数,并响应式地追踪其依赖,并在其依赖变更时重新运行该函数。 |
无 |
onMounted |
onMounted 函数在组件被挂载时调用。它接收一个在组件挂载后执行的回调函数。 |
mounted |
onUnmounted |
onUnmounted 函数在组件被卸载时调用。它接收一个在组件卸载后执行的回调函数。 |
beforeDestroy/unmounted |
onUpdated |
onUpdated 在组件更新后调用。它接收一个在组件更新后执行的回调函数。 |
updated |
provide |
provide 函数用于在组件上定义一个可以被后代组件注入的值。它接收一个提供的键和值。 |
有,与 provide/inject 相似但是属性而不是函数 |
inject |
inject 函数用于在组件中注入一个由祖先组件提供的值。它接收一个注入的键。 |
有,但与 provide/inject 相似但是属性而不是函数 |
值得注意的是,虽然一些 Composition API 函数与 Options API 的某些选项有相似之处,但它们的工作方式和使用方式可能有所不同。在实际使用中,你需要根据具体的使用场景和需求选择合适的 API。