Skip to content

Vue 写法规范

下面的大纲为 Vue 组件的推荐写入顺序。

  1. import 导入
  2. props 属性
  3. emits 事件
  4. refreactive 响应式变量
  5. computed 计算属性
  6. composables 使用(自定义)组合式函数
  7. composables 编写自定义组合式函数
  8. functions 自定义函数
  9. watchwatchEffect 监听器(建议此处是因为 watch 里会用到组合式函数或自定义函数,因此先定义函数,再使用)
  10. Vue3 生命周期钩子
  11. defineExpose 暴露

提示

这是一个推荐的写法,并不是强制要求,如果您的团队没有一套编写规范,可以参考该推荐写法。

import 导入顺序

建议按照以下依赖顺序:

  1. 先引入所有 type 类型(按照导入规范顺序引入,不允许类型和函数的引入混杂在一起)
  2. 引入第三方依赖(Vue 相关生态优先,如 vuevue-routerpiniavue-i18n@vueuse,然后是组件库如 ElementPlus@element-plus/icons-vue,最后是第三方插件)
  3. 引入项目目录的其他依赖(如 @/composables,路径按照目录结构顺序引入)
  4. 引入项目目录的其他组件(如 @/components/index.vue,路径按照目录结构顺序引入)
  5. 引入相对路径的依赖(如 ./types
  6. 引入相对路径的组件(如 ./Demo.vue
  7. 直接引入第三方库(如 import "vue-cropper/dist/index.css"
  8. 直接引入绝对路径(如 import "@/common/styles/common/var.scss"
  9. 直接引入相对路径(如 import "./index.scss"

如:

vue
<script setup lang="ts">
import type { xx } from "xx";
import { xx } from "xx";
import { xx } from "@/xx";
import { xx } from "@/xx.vue";
import { xx } from "../xx";
import { xx } from "../xx.vue";

import "xxx";
import "@/xxx";
import "./xxx";
</script>

Props 类型定义

使用 TypeScript 语法:

ts
interface Props {
  prop1: string;
  prop2: number;
}

defineProps<Props>();
const props = defineProps<Props>(); // 用到 props 时

Emits 类型定义

使用 TypeScript 语法:

ts
interface Emits {
  emit1: [];
  emit2: [arg1: string, arg2: number];
}

defineEmits<Emits>();
const emit = defineEmits<Emits>(); // 用到 emit 时

ref 类型定义

ts
const count = ref(0);
const state = reactive({});

computed 类型定义

ts
const count = computed(() => {});

导入组合式函数

例如:useRouteruseRoute, 以及自行封装的组合式函数

ts
const router = useRouter();
const route = useRoute();
const userStore = useUserStore();

const { loading, startLoading, endLoading } = useLoading();

自定义组合式函数

首先不建议按照 refcomputedwatch 等方式自上而下写逻辑,而是将各自的逻辑封装成组合式函数

ts
const { count, ratio, increase } = useCount();
const { http, request } = useRequest();

function useCount() {
  const count = ref(0);

  const ratio = computed(() => count.value / 100);

  function increase() {
    count.value++;
  }

  return {
    count,
    ratio,
    increase,
  };
}

function useRequest() {
  const http = useHttp();

  watch(http.state, () => {
    console.log(http.state);
  });

  function request(url: string) {
    return (data = http.get(url));
  }

  return {
    http,
    request,
  };
}
ts
const count = ref(0);

const ratio = computed(() => count.value / 100);

const http = useHttp();

function increase() {
  count.value++;
}

function request(url: string) {
  return (data = http.get(url));
}

watch(http.state, () => {
  console.log(http.state);
});

自定义函数

ts
const init = () => {};

const handleClick = () => {};

watch 和 watchEffect

ts
watchEffect(() => {
  console.log(count.value);
});

watch(
  () => count.value,
  (newValue, oldValue) => {
    console.log(newValue, oldValue);
  }
);

生命周期钩子

ts
// 相当于在 `created` 钩子中执行
init();

// 或者
onMounted(() => {
  init();
});

defineExpose

ts
const exposed = {
  count,
  increment,
};

defineExpose(exposed);