全局单例状态
我们写组件时,有时会遇到需要将数据通过 props 层层向下传递,或者是 emit 通过事件层层向上传递的情况。或者会遇到同级组件之间需要共享一些数据。
为了避免这种情况,我们可以使用全局单例状态来管理数据。
当然在 Vue3 中,我们可以使用 Pinia 来进行此操作。
import { ref, toRefs } from 'vue' const globalState = ref({ darkMode: false, sidebarCollapsed: false, theme: 'green', }) export default () => { // 一些逻辑处理 return { ...toRefs(globalState) } }
<script setup lang="ts"> import useSettings from '@/composables/useSettings' const { darkMode, sidebarCollapsed, theme } = useSettings() function toggleDarkMode() { darkMode.value = !darkMode.value } </script>
传递整个对象
- 将整个数据对象作为 prop 传递,而不是逐个字段传递。我们经常会遇到添加一些字段到组件中,这样会导致 props 的数量不断增加。 为了避免这种情况,我们可以将整个对象传递给组件。
- 这样我们可以复用 TypeScript 的类型定义到组件中。
之前
<template> <Article :title="article.title" :content="article.content" /> </template>
<script setup lang="ts"> import { IArticle } from '@/types/article' const props = defineProps<{ title: IArticle['title'] content: IArticle['content'] }>() </script> <template> <!-- 内部实现 --> </template>
之后
<template> <Article :article="article" /> </template>
<script setup lang="ts"> import { IArticle } from '@/types/article' const props = defineProps<{ article: IArticle }>() </script> <template> <!-- 内部实现 --> </template>
如果此时我们的 article 要增加一个创建日期的字段,旧的写法需要修改 Article.vue 的 props 定义,而新的写法只需要修改 Article.vue 的展示逻辑即可(因为我们的类型是全局复用的)。
使用不同的组件处理 v-if 分支
<template> <div v-if="showSomething"> <div>一些代码,很长很长</div> </div> <div v-else> <div>另一些代码,很长很长</div> </div> </template>
<template> <div v-if="showSomething"> <ComponentA /> </div> <div v-else> <ComponentB /> </div> </template>
每一个分支都会做不同的事,所以将他们拆分成不同的组件是更好的选择。 这样不仅会使每个组件专注于特定的任务,还可以提高代码的可读性和可维护性。
将使用 v-for 的组件提取成 List 组件单独维护
有时候我们并不关心组件的循环的细节,我们可以将它提取成一个 List 组件来单独维护。
Before
<template> <Article v-for="article in articles" :key="article.id" :article="article" /> </template>
After
<template> <ArticleList :articles="articles" /> </template>