Vue3 setup 写法最佳实践

文章比较了Vue3中使用SFC的setup方法与组合式API的setup方法在代码组织、类型声明、维护性和性能上的差异。作者认为SFCsetup提供了更清晰的模块化,更简洁的代码和更好的类型推导,因此更利于维护。Vue3官方也推荐使用SFC配合setup语法糖,以减少样板代码并提高性能。

Vue3 setup 写法最佳实践

为什么一定要用SFC而不用 组合式API setup()?

两种方式最终都能满足我们搭建组件的需求,但经过实践setup() 形式的组件往往要比SFC 形式的组件多出很多代码且不易维护,下面我会阐述出案例以证实结论

我们先来看 组合式 setup()

<template>
  <Select v-model:value="selectValue" />
</template>
<script lang="ts">
import { ref } from 'vue'
import { getBusinessByProject } from '@/api/versionControl/business'
import { KeyItem, RES_CODE } from '@/type'
import { Key } from 'ant-design-vue/es/_util/type'
import { SelectValue } from 'ant-design-vue/lib/select'
 
export default {
  props: {
    value: {
      type: String,
      default: '',
    },
  },
  emits: ['eventBusinessChange'],
  setup() {
    const options = ref<KeyItem[]>([])
    const selectValue = ref<SelectValue>(undefined)
    const loading = ref(false)
 
    const getData = async (key: Key): Promise<void> => {
      try {
        loading.value = true
        const res = await getBusinessByProject({ project: key })
        loading.value = false
        const { status, data } = res || {}
        if (status !== RES_CODE.SUCCESS) return
        options.value = data || []
      } catch (error) {
        loading.value = false
        console.error('getData->', error)
      }
    }
 
    // 返回值会暴露给模板和其他的选项式 API 钩子
    return {
      selectValue,
      getData,
      options,
    }
  },
  mounted() {
    console.log(this.getData) // 0
  },
}
</script>

看完上述代码给我感受:

1.类型声明过于繁琐

2.emits 声明只能 声明函数,而不能具体到具体到函数入参与返回值

3.通过return的方式将所有变量和函数都暴露出去了,这样的方式每声明一个变量或者函数模版渲染中所需,都需要暴露出去,如果是一个复杂且状态较多的组件,这样的方式就会变得难以维护

4.return 所暴露出去的函数与变量再父组件往往不需要那么多,对于一个刚入门vue3同学,这样的方式可能会导致大量无用的变量暴露而这些变量其实是无用的,久而久之代码就会变得难以维护…

看完了 组合式 setup 我们再来看看SFC setup

<template>
  <Select
    v-model:value="selectValue"
  />
</template>
<script lang="ts" setup>
import { ref } from "vue";
import { Select } from "ant-design-vue";
 
 
interface MyProps {
  data?: ApiQoData;
  needAssert?: boolean;
}
 
const props = withDefaults(defineProps<MyProps>(), {
  needAssert: () => true,
  data: () => {
    return {} as ApiQoData;
  },
});
 
interface MyEmit {
  (e: "eventBusinessChange", key: Key, option: KeyItem): void;
}
 
const emit = defineEmits<MyEmit>();
const options = ref<KeyItem[]>([]);
const selectValue = ref<SelectValue>(undefined);
const loading = ref(false);
 
 
const getData = async (key: Key): Promise<void> => {
  try {
    loading.value = true;
    const res = await api({ project: key });
    loading.value = false;
    const { status, data } = res || {};
    if (status !== RES_CODE.SUCCESS) return;
    options.value = data || [];
  } catch (error) {
    loading.value = false;
    console.error("getData->", error);
  }
};
 
 
defineExpose({
  getData
});
</script>

SFC形式的setup给我们的感觉 模块化更清晰,类型声明更清晰,暴露变量函数也会更简单易维护,这样的方式也更加靠近函数式编程

Vue3 官方也给出了很好建议与阐述

<script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。当同时使用 SFC 与组合式 API 时该语法是默认推荐。相比于普通的

更少的样板内容,更简洁的代码。
能够使用纯 TypeScript 声明 props 和自定义事件。
更好的运行时性能 (其模板会被编译成同一作用域内的渲染函数,避免了渲染上下文代理对象)。
更好的 IDE 类型推导性能 (减少了语言服务器从代码中抽取类型的工作)。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值