Vue3 写法示例与规范详细指南

 更新时间:2025年09月29日 14:29:21   作者:木易 士心  
本文给大家介绍Vue3写法示例与规范详细指南,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

一、项目结构规范

1.推荐目录结构

src/
├── assets/              # 静态资源(图片、字体等)
├── components/           # 公共组件(PascalCase命名)
│   ├── Button.vue
│   └── UserCard.vue
├── composables/          # 组合式函数(逻辑复用)
│   └── useFetch.ts
├── router/               # 路由配置
│   └── index.ts
├── store/                # 状态管理(Pinia)
│   └── user.ts
├── utils/                # 工具函数
│   └── format.ts
├── views/                # 页面级组件
│   └── Home.vue
├── App.vue               # 根组件
└── main.ts               # 入口文件

2.命名规则

组件文件:PascalCase(如 UserProfile.vue)
文件夹:复数形式(如 components/ 而非 component/)
组合式函数:useXxx 前缀(如 useAuth.ts)

二、代码编写规范

1. Script 部分(Composition API)

setup 语法糖

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import { fetchUser } from '@/api/user';
// 响应式数据
const count = ref(0);
const user = ref<UserType | null>(null);
// 计算属性
const doubleCount = computed(() => count.value * 2);
// 生命周期
onMounted(async () => {
  user.value = await fetchUser(1);
});
// 类型定义
interface UserType {
  id: number;
  name: string;
}
</script>

Props/Emits 类型化

const props = defineProps<{
  modelValue: string;
  disabled?: boolean;
}>();
const emit = defineEmits<{
  (e: 'update:modelValue', value: string): void;
  (e: 'submit'): void;
}>();

2. Template 部分

语义化标签

<template>
  <article class="article-card">
    <header class="article-header">
      <h2>{{ title }}</h2>
    </header>
    <main class="article-content">
      <p>{{ content }}</p>
    </main>
  </article>
</template>

条件渲染与列表

<template>
  <!-- 避免 v-if + v-for 同级 -->
  <template v-if="users.length">
    <ul>
      <li v-for="user in users" :key="user.id">
        {{ user.name }}
      </li>
    </ul>
  </template>
  <p v-else>No users found</p>
</template>

3. Style 部分

Scoped CSS

<style scoped>
.article-card {
  border: 1px solid #eee;
  transition: all 0.3s ease;
}
.article-card:hover {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
</style>

CSS 命名规范(BEM 示例)

.article-card {}
.article-card__header {}
.article-card__header--active {}

三、高级特性规范

1. 组合式函数(Composables)

// composables/useCounter.ts
import { ref } from 'vue';
export function useCounter(initialValue = 0) {
  const count = ref(initialValue);
  const increment = () => count.value++;
  const decrement = () => count.value--;
  return { count, increment, decrement };
}

2. 组件通信

1.父子组件通讯

1. 父传子:使用 props
父组件通过属性(Props)向子组件传递数据。

父组件 (Parent.vue):
<template>
  <div>
    <ChildComponent :title="pageTitle" :user="currentUser" />
  </div>
</template>
<script setup>
import { ref, reactive } from 'vue'
import ChildComponent from './ChildComponent.vue'
const pageTitle = ref('欢迎来到我的应用')
const currentUser = reactive({
  name: '张三',
  id: 123
})
</script>
子组件 (ChildComponent.vue):
<template>
  <div>
    <h2>{{ title }}</h2>
    <p>用户: {{ user.name }} (ID: {{ user.id }})</p>
  </div>
</template>
<script setup>
// 定义接收的 props
const props = defineProps({
  title: {
    type: String,
    required: true
  },
  user: {
    type: Object,
    default: () => ({})
  }
})
// 在模板中直接使用 props.title 和 props.user
// 注意:在 <script setup> 中,props 是一个对象,需要通过 props.xxx 访问
</script>

2. 子传父:使用 emit
子组件通过触发自定义事件向父组件传递数据。

子组件 (ChildComponent.vue):
<template>
  <div>
    <button @click="handleClick">点击我通知父组件</button>
  </div>
</template>
<script setup>
// 定义组件可以触发的事件
const emit = defineEmits(['updateUser', 'customEvent'])
const handleClick = () => {
  // 触发事件,并传递数据
  emit('updateUser', { id: 456, name: '李四' })
  // 也可以触发不带参数的事件
  emit('customEvent')
}
</script>
父组件 (Parent.vue):
<template>
  <div>
    <ChildComponent 
      @updateUser="handleUserUpdate" 
      @customEvent="handleCustomEvent" 
    />
    <p>当前用户: {{ user.name }}</p>
  </div>
</template>
<script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'
const user = ref({ name: '王五', id: 789 })
const handleUserUpdate = (newUser) => {
  // 接收子组件传递过来的数据
  user.value = newUser
  console.log('用户已更新:', newUser)
}
const handleCustomEvent = () => {
  console.log('自定义事件被触发了')
}
</script>

2.跨层级组件:provide/inject

当组件嵌套层级很深,逐层传递 props 会非常繁琐时,可以使用 provide 和 inject。

使用 provide / inject
祖先组件提供数据,后代组件(无论多深)注入并使用。

祖先组件 (App.vue 或 Layout.vue):

<template>
  <div>
    <DeeplyNestedChild />
  </div>
</template>
<script setup>
import { provide, ref } from 'vue'
import DeeplyNestedChild from './components/DeeplyNestedChild.vue'
// 提供一个响应式数据
const theme = ref('dark')
const appConfig = {
  apiUrl: 'https://api.example.com',
  version: '1.0.0'
}
// 第一个参数是 key (推荐使用 Symbol 或字符串),第二个参数是提供的值
provide('THEME', theme)
provide('APP_CONFIG', appConfig)
</script>

后代组件 (DeeplyNestedChild.vue):

浅色版本
<template>
  <div :class="theme">
    <p>当前主题: {{ theme }}</p>
    <p>API 地址: {{ config.apiUrl }}</p>
  </div>
</template>
<script setup>
import { inject } from 'vue'
// 注入数据,第二个参数是默认值(可选但推荐)
const theme = inject('THEME', 'light')
const config = inject('APP_CONFIG', {})
</script>

注意
如果 provide 的是 ref 或 reactive 对象,inject 得到的数据会保持响应性。
为避免命名冲突,建议使用 Symbol 作为 key:

浅色版本
// keys.js
export const THEME_KEY = Symbol()
export const CONFIG_KEY = Symbol()
// 在 provide 和 inject 时使用这些 Symbol

3.其他通信方式

  • $refs (子 -> 父): 父组件可以通过 ref获取子组件的实例,从而直接调用子组件的方法或访问其数据。这种方式会增加耦合度,应谨慎使用。
  • 插槽 (Slots): 主要用于内容分发,但结合作用域插槽 (Scoped Slots),可以实现父组件向子组件传递数据,同时由父组件决定如何渲染。常用于列表、表格等组件。
  • v-model: 是 props 和 emit 的语法糖,用于在表单组件上创建双向绑定。

3. 性能优化

虚拟滚动:长列表使用 vue-virtual-scroller
计算属性缓存:避免在模板中执行复杂计算
响应式优化:对大型对象使用 shallowRef

四、工具链配置

1. ESLint 配置(.eslintrc.js)

module.exports = {
  extends: [
    'plugin:vue/vue3-recommended',
    '@vue/typescript/recommended'
  ],
  rules: {
    'vue/multi-word-component-names': 'off', // 允许单文件组件名
    '@typescript-eslint/no-explicit-any': 'warn'
  }
};

2. Prettier 配置(.prettierrc)

{
  "semi": false,
  "singleQuote": true,
  "trailingComma": "es5",
  "printWidth": 100
}

3. Git 规范

提交信息格式:<_type>: <_subject>
强制检查:使用 Husky + Commitlint

feat: 添加用户登录功能
fix: 修复表单验证错误
chore: 更新依赖版本

五、反模式警示

避免混用 Options API 和 Composition API

<script>
export default {
  data() { return { count: 0 } } // 不要与 setup() 混用
}
</script>
<script setup>
const count = ref(0); //  冲突
</script>

禁止直接修改 Props

<script setup>
const props = defineProps(['count']);
//  错误方式
props.count++;
//  正确方式:通过 emits
const emit = defineEmits(['update:count']);
emit('update:count', props.count + 1);
</script>

避免深层响应式

//  性能开销大
const state = reactive({
  user: {
    profile: {
      name: 'Alice'
    }
  }
});
//  优化:对大型对象使用 shallowRef
const largeData = shallowRef({ /* ... */ });

遵循以上规范可显著提升代码可维护性和团队协作效率,建议结合 Vue Style Guide 官方文档使用。

到此这篇关于Vue3 写法示例与规范指南的文章就介绍到这了,更多相关vue规范指南内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Vue组件中常见的props默认值陷阱问题

    Vue组件中常见的props默认值陷阱问题

    这篇文章主要介绍了避免Vue组件中常见的props默认值陷阱,本文通过问题展示及解决方案给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09
  • Element ui table表格内容超出隐藏显示省略号问题

    Element ui table表格内容超出隐藏显示省略号问题

    这篇文章主要介绍了Element ui table表格内容超出隐藏显示省略号问题,具有很好的参考价值,希望对大家有所帮助,
    2023-11-11
  • Vue 3 中 toRaw 的用法详细讲解

    Vue 3 中 toRaw 的用法详细讲解

    `toRaw` 是 Vue3 提供的一个 API,用于获取响应式对象的原始非响应式对象,主要用于调试、与第三方库兼容以及避免无限递归更新等场景,使用时需要注意不要滥用,以免破坏响应式系统,感兴趣的朋友跟随小编一起看看吧
    2024-11-11
  • 聊聊对Vue中的keep-alive的理解

    聊聊对Vue中的keep-alive的理解

    keepalive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染,也就是所谓的组件缓存,这篇文章主要介绍了说说你对Vue的keep-alive的理解,需要的朋友可以参考下
    2022-11-11
  • Vue.use()和Vue.prototype使用详解

    Vue.use()和Vue.prototype使用详解

    Vue.use()主要用于注册全局插件,当插件具有install方法时,调用Vue.use()可以全局使用该插件,Vue.prototype用于注册全局变量,这些变量在项目任何位置都可以通过this.$变量名访问,两者的主要区别在于Vue.use()用于插件,Vue.prototype用于变量
    2024-10-10
  • vue-quill-editor富文本编辑器简单使用方法

    vue-quill-editor富文本编辑器简单使用方法

    这篇文章主要为大家详细介绍了vue-quill-editor富文本编辑器简单使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-09-09
  • Vue2 Watch监听操作方法

    Vue2 Watch监听操作方法

    这篇文章主要介绍了Vue2 Watch监听,通过watch监听器,我们可以实时监控数据的变化,并且在数据发生改变时进行相应的操作,需要的朋友可以参考下
    2023-12-12
  • vue实现登录时滑块验证

    vue实现登录时滑块验证

    这篇文章主要为大家详细介绍了vue实现登录时滑块验证,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • 详解如何运行vue项目

    详解如何运行vue项目

    这篇文章主要介绍了如何运行vue项目,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • Vue对象的组成和挂载方式详解

    Vue对象的组成和挂载方式详解

    这篇文章主要介绍了Vue对象的基本组成和Vue对象挂载的几种方式,文中通过代码示例给大家介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-07-07

最新评论