vue3中高阶使用与性能优化

在 Vue 3 中,setup() 是 Composition API 的核心入口,它提供了更灵活、可复用和模块化的代码组织方式。


一、setup() 高阶使用技巧

1. 使用 definePropsdefineEmits(无需导入)

Vue 3.3+ 支持自动推导 props 和 emits,无需手动引入函数。

<script setup>
const props = defineProps(['title', 'content']);
const emit = defineEmits(['update:title', 'submit']);

function handleSubmit() {
  emit('submit', { data: props.content });
}
</script>
2. 结合 TypeScript 类型推导

提升类型安全性,支持自动补全和类型检查。

interface User {
  id: number;
  name: string;
  age?: number;
}

const props = defineProps<{
  user: User;
  isActive: boolean;
}>();
3. 自定义逻辑封装为组合函数(Composable)

将可复用逻辑提取到独立函数中,便于跨组件复用。

// useUserValidation.ts
import { ref } from 'vue';

export function useUserValidation(user) {
  const isValid = ref(false);

  function validate() {
    isValid.value = !!user.name && user.age > 0;
  }

  return { isValid, validate };
}

在组件中使用:

<script setup>
import { useUserValidation } from '@/composables/useUserValidation';

const props = defineProps(['user']);
const { isValid, validate } = useUserValidation(props.user);
</script>
4. 使用 refreactive 控制响应性粒度
  • 使用 ref 管理基础类型。
  • 使用 reactive 管理对象/数组。
  • 对不需要响应式的数据使用 markRaw() 或普通变量。
import { markRaw } from 'vue';

const largeData = markRaw(JSON.parse(localStorage.getItem('bigData')));

二、性能优化策略

1. 避免不必要的响应式数据
  • 对静态或大数据量对象使用 markRaw(),防止 Vue 自动将其转换为响应式对象。
const config = markRaw({ theme: 'dark', version: '1.0.0' });
2. 控制副作用生命周期
  • 使用 onBeforeUnmount 清理副作用(如定时器、事件监听器)。
  • 使用 effectScope 管理多个响应式依赖的生命周期。
import { effectScope, onBeforeUnmount } from 'vue';

const scope = effectScope();

scope.run(() => {
  const count = ref(0);
  watchEffect(() => {
    console.log(count.value);
  });

  onBeforeUnmount(() => {
    scope.stop(); // 手动清理所有副作用
  });
});
3. 避免重复计算与渲染
  • 使用 computed 缓存计算结果。
  • 使用 v-once<keep-alive> 缓存静态内容。
  • 使用 key 控制组件重新渲染时机。
<template>
  <div :key="user.id">
    <!-- 当 user.id 变化时才会重新渲染 -->
    {{ computedName }}
  </div>
</template>
4. 减少模板中的复杂逻辑
  • 模板中应尽量只调用简单变量或 computed,避免直接写复杂表达式。
  • 将复杂逻辑封装到 methods 或 Composable 函数中。

三、开发与维护建议

1. 结构清晰、职责单一
  • 每个组件只做一件事。
  • 抽离通用逻辑到 composables/ 目录下。
2. 良好的命名规范
  • 组合函数命名以 useXxx 开头(如 useAuth, useFetch)。
  • 文件名使用大写驼峰命名法(如 UserProfile.vue)。
3. 使用 Suspense 处理异步加载状态
  • 结合异步组件实现优雅加载体验。
<template>
  <Suspense>
    <AsyncComponent />
    <template #fallback>
      加载中...
    </template>
  </Suspense>
</template>
4. 使用 Devtools 调试
  • 利用 Vue Devtools 查看组件树、响应式依赖、性能面板等信息。
  • 使用 console.warn()error 提醒潜在问题。

四、完整示例:高性能封装组件

<template>
  <div class="data-table">
    <table>
      <thead>
        <tr v-for="header in headers" :key="header.key">
          <th>{{ header.label }}</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="row in rows" :key="row.id">
          <td v-for="col in headers" :key="col.key">{{ row[col.key] }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue';
import { fetchData } from '@/api/data';

const props = defineProps({
  headers: {
    type: Array,
    required: true
  }
});

const data = ref([]);
const loading = ref(false);

async function loadData() {
  loading.value = true;
  try {
    const result = await fetchData();
    data.value = result;
  } finally {
    loading.value = false;
  }
}

onMounted(loadData);

const rows = computed(() => {
  return data.value.map(item => ({
    ...item,
    fullName: `${item.firstName} ${item.lastName}`
  }));
});
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

香蕉可乐荷包蛋

努力写有用的code

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值