Vue 写法规范
下面的大纲为 Vue 组件的推荐写入顺序。
import导入props属性emits事件ref、reactive响应式变量computed计算属性composables使用(自定义)组合式函数composables编写自定义组合式函数functions自定义函数watch、watchEffect监听器(建议此处是因为watch里会用到组合式函数或自定义函数,因此先定义函数,再使用)Vue3生命周期钩子defineExpose暴露
提示
这是一个推荐的写法,并不是强制要求,如果您的团队没有一套编写规范,可以参考该推荐写法。
import 导入顺序
建议按照以下依赖顺序:
- 先引入所有
type类型(按照导入规范顺序引入,不允许类型和函数的引入混杂在一起) - 引入第三方依赖(
Vue相关生态优先,如vue、vue-router、pinia、vue-i18n、@vueuse,然后是组件库如ElementPlus,@element-plus/icons-vue,最后是第三方插件) - 引入项目目录的其他依赖(如
@/composables,路径按照目录结构顺序引入) - 引入项目目录的其他组件(如
@/components/index.vue,路径按照目录结构顺序引入) - 引入相对路径的依赖(如
./types) - 引入相对路径的组件(如
./Demo.vue) - 直接引入第三方库(如
import "vue-cropper/dist/index.css") - 直接引入绝对路径(如
import "@/common/styles/common/var.scss") - 直接引入相对路径(如
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(() => {});导入组合式函数
例如:useRouter,useRoute, 以及自行封装的组合式函数
ts
const router = useRouter();
const route = useRoute();
const userStore = useUserStore();
const { loading, startLoading, endLoading } = useLoading();自定义组合式函数
首先不建议按照 ref、computed、watch 等方式自上而下写逻辑,而是将各自的逻辑封装成组合式函数
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);