前置核心原则(团队必看)

1. 90% 规则全站通用:命名、TS、代码顺序、事件规范、常量抽离、数据流,普通后台页面 / 数据大屏页面 完全统一,保证团队代码风格一致

2. 10% 规则场景差异化:仅组件拆分粒度、生命周期销毁、自适应、样式规则、定时器/图表处理区分普通页 & 大屏页

3. 杜绝两套混乱规范,通用规则统一遵守,差异化规则按需适配

目录

前置核心原则(团队必看)

一、全站通用强制规范(所有页面 100% 遵守)

1.1 顶级命名规范(统一,无例外)

1)文件 / 组件命名

2)响应式变量命名(强制后缀/前缀)

3)常量规范(全站统一)

4)Props / Emits 规范(全站统一)

5)方法/函数 动词前缀规范(全站最核心,统一辨识度)

1.2 全站固定代码顺序(强制统一)

1.3 全站 TS 强制规范

1.4 全站数据流规范

1.5 全站模板 & 样式规范

二、场景差异化规范(重点:普通页面 VS 大屏页面)

2.1 组件拆分规范差异

普通后台页面(列表/表单/弹窗)

数据大屏页面

2.2 生命周期 & 资源销毁差异

普通后台页面

数据大屏页面(核心差异化)

2.3 常量 & 硬编码差异

普通页面

大屏页面

2.4 样式差异

普通页面

大屏页面

三、双场景 可直接复制标准模版

3.1 普通后台页面 标准模版(列表/表单页)

3.2 数据大屏模块 专属标准模版

四、终极全站速记口诀(通用+差异化)

通用8条(所有页面)

大屏专属3条

欢迎关注:【前端小知识营地】


一、全站通用强制规范(所有页面 100% 遵守)

适用于:后台业务页、列表页、表单页、弹窗、大屏模块、大屏页面

1.1 顶级命名规范(统一,无例外)

1)文件 / 组件命名
  • 页面/组件:大驼峰 PascalCase → UserListPage、ChartTrend、CommonBox

  • 工具/钩子/TS文件:小驼峰 camelCase → useTable、formatTime

  • 文件夹:短横线 kebab-case → user-manage、chart-modules

  • CSS类名:短横线 kebab-case → table-wrap、chart-card

2)响应式变量命名(强制后缀/前缀)
  • 数组/列表:XXXList → tableList、deviceList、chartDataList

  • 业务对象:XXXData / XXXInfo → formData、userInfo、chartData

  • 布尔值:is / has 前缀 → isLoading、isVisible、hasData

  • 基础变量:语义化小驼峰 → activeTab、pageSize

3)常量规范(全站统一)
  • 全局/业务常量、颜色、配置、枚举、固定文案:全大写下划线

  • 复用常量统一抽离 src/constants,页面私有少量常量写组件内

  • 固定配置强制 as const 锁定类型

const CHART_COLORS = ['#1E88E5', '#00C48C'] as const
const STATUS_MAP = { NORMAL: '正常', ERROR: '异常' } as const
4)Props / Emits 规范(全站统一)
  • 组件内定义:小驼峰 → chartData、queryParams

  • 模板使用:短横线 → :chart-data、:query-params

  • 禁止模糊命名:data / info / item

  • 自定义事件:短横线命名 → @change-tab、@refresh-data

5)方法/函数 动词前缀规范(全站最核心,统一辨识度)

所有方法必须按前缀分类,禁止随意命名

前缀

适用场景

示例

handle

所有点击、切换、弹窗、用户交互事件

handleTabChange、handleSearch、handleModalOpen

get

请求接口、获取服务端数据

getTableList、getChartData、getUserInfo

submit

表单提交、数据保存、确认操作

submitForm、submitEdit、submitConfig

init

页面初始化、图表初始化、数据初始加载

initPage、initChart、initData

update

数据更新、图表重绘、局部刷新

updateChart、updateTable、updateStatus

reset

重置表单、重置筛选条件

resetForm、resetQuery

destroy/clear

销毁实例、清除定时器、清空数据

destroyChart、clearTimer、clearData

1.2 全站固定代码顺序(强制统一)

普通页面、大屏页面 脚本顺序完全一致

// 1. Vue 内置API
// 2. 第三方库/工具
// 3. 静态资源/图片
// 4. 组件导入/异步组件
// 5. TS类型导入
// 6. defineProps
// 7. defineEmits
// 8. 常量/配置
// 9. 响应式数据
// 10. 计算属性 computed
// 11. 业务方法(init/get/handle/submit/update)
// 12. 监听 watch
// 13. 生命周期

1.3 全站 TS 强制规范

  • 所有 ref 必须加明确泛型,禁止隐式 any

  • 后端赋值必做空值兜底val ?? [] / val ?? {} / val ?? ''

  • Props 必须定义类型 + 默认值

  • 禁止全局 any、禁止类型逃逸

  • 固定枚举、下拉选项统一 as const 锁定类型

1.4 全站数据流规范

  • Props 禁止直接修改,必须同步到本地 ref

  • 监听 Props 统一开启 deep: true, immediate: true

  • 子组件只派发事件,不修改父级数据(单向数据流)

1.5 全站模板 & 样式规范

  • 所有组件样式必须加 scoped

  • 模板禁止行内复杂逻辑,事件统一调用方法

  • 条件渲染简写:v-if="list.length"

  • 禁止 Math.random() 生成元素ID

二、场景差异化规范(重点:普通页面 VS 大屏页面)

2.1 组件拆分规范差异

普通后台页面(列表/表单/弹窗)
  • 拆分原则:复用才抽离,简单页面无需过度拆分

  • 单文件允许 300-500 行

  • 页面私有组件统一放在当前页面components 文件夹

数据大屏页面
  • 拆分原则:模块级强制拆分,一个图表/一个卡片单独组件

  • 单文件严格控制 ≤300 行,杜绝巨型页面

  • 所有图表、统计卡片、趋势模块全部抽独立组件

2.2 生命周期 & 资源销毁差异

普通后台页面
  • 无需特殊销毁,常规数据清空即可

  • 无频繁 resize 监听

数据大屏页面(核心差异化)
  • 必须监听窗口 resize 自适应

  • 页面卸载必须 dispose 销毁echarts实例

  • 所有定时器、轮询必须在 onUnmounted 清空,杜绝内存泄漏

2.3 常量 & 硬编码差异

普通页面
  • 常规状态、枚举抽常量,少量文案可酌情写内联

大屏页面
  • 零硬编码强制要求

  • 所有颜色、透明度、字体大小、背景图、图表配置、轮播时间全部抽全局常量

2.4 样式差异

普通页面
  • 常规固定尺寸、自适应均可

大屏页面
  • 根容器必须 width:100%;height:100%

  • 禁止固定死像素,适配屏幕缩放

  • 禁止JS变量与SCSS混用

三、双场景 可直接复制标准模版

3.1 普通后台页面 标准模版(列表/表单页)

<template>
  <div class="user-list-page">
    <!-- 筛选、表单、表格区域 -->
  </div>
</template>

<script setup lang="ts" name="UserListPage">
// 1. Vue API
import { ref, reactive, watch, onMounted } from 'vue'
// 2. 第三方/接口
import { getUserList } from '@/api/userApi'
// 3. 类型
import type { UserItem, UserQueryParams } from '@/types/user'
// 4. 全局常量
import { PAGE_SIZE } from '@/constants/common'

// 5. Props
const props = defineProps<{
  status?: number
}>()

// 6. Emits
const emit = defineEmits<{
  'row-click': [row: UserItem]
}>()

// 7. 页面私有常量
const STATUS_OPTIONS = [
  { label: '全部', value: 0 },
  { label: '正常', value: 1 },
  { label: '异常', value: 2 }
] as const

// 8. 响应式数据
const loading = ref(false)
const tableList = ref<UserItem[]>([])
const queryParams = reactive<UserQueryParams>({
  page: 1,
  size: PAGE_SIZE,
  status: props.status ?? 0
})

// 9. 业务方法
/** 获取表格数据 */
const getTableList = async () => {
  loading.value = true
  const res = await getUserList(queryParams)
  tableList.value = res.list ?? []
  loading.value = false
}

/** 搜索 */
const handleSearch = () => {
  queryParams.page = 1
  getTableList()
}

/** 重置 */
const resetQuery = () => {
  queryParams.page = 1
  queryParams.status = 0
  getTableList()
}

/** 行点击 */
const handleRowClick = (row: UserItem) => {
  emit('row-click', row)
}

// 10. 监听
watch(() => props.status, (val) => {
  queryParams.status = val ?? 0
  getTableList()
}, { deep: true, immediate: true })

// 11. 生命周期
onMounted(() => {
  getTableList()
})
</script>

<style lang="scss" scoped>
.user-list-page {
  width: 100%;
  padding: 20px;
}
</style>

3.2 数据大屏模块 专属标准模版

<template>
  <div class="chart-trend-module">
    <common-box title="设备趋势统计">
      <div ref="chartRef" class="chart-container"></div>
    </common-box>
  </div>
</template>

<script setup lang="ts" name="ChartTrendModule">
import { ref, watch, onMounted, onUnmounted } from 'vue'
import * as echarts from 'echarts'
import CommonBox from '@/components/common/CommonBox.vue'
import type { ChartItem } from '@/types/screen'

// Props
const props = defineProps<{
  chartData: ChartItem[]
}>()

// Emits
const emit = defineEmits<{
  'chart-click': [item: ChartItem]
}>()

// 大屏全局常量
const CHART_COLORS = ['#1E88E5', '#00C48C', '#FFC107'] as const

// 响应式
const chartRef = ref<HTMLElement>()
const chartInstance = ref<echarts.ECharts | null>(null)
const localChartData = ref<ChartItem[]>([])

// 初始化图表
const initChart = () => {
  if (!chartRef.value) return
  chartInstance.value = echarts.init(chartRef.value)
  updateChart()
}

// 更新图表
const updateChart = () => {
  if (!chartInstance.value) return
  const option = {
    color: CHART_COLORS,
    tooltip: { trigger: 'axis' },
    xAxis: { data: localChartData.value.map(item => item.time) },
    series: [{ data: localChartData.value.map(item => item.value), type: 'line' }]
  }
  chartInstance.value.setOption(option)
}

// 窗口自适应
const handleResize = () => {
  chartInstance.value?.resize()
}

// 图表点击
const handleChartClick = () => {
  chartInstance.value?.on('click', (params) => {
    emit('chart-click', params.data)
  })
}

// 监听父组件数据
watch(() => props.chartData, (val) => {
  localChartData.value = val ?? []
  updateChart()
}, { deep: true, immediate: true })

// 生命周期
onMounted(() => {
  initChart()
  handleChartClick()
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
  chartInstance.value?.dispose()
})
</script>

<style lang="scss" scoped>
.chart-trend-module {
  width: 100%;
  height: 100%;
  .chart-container {
    width: 100%;
    height: calc(100% - 36px);
  }
}
</style>

四、终极全站速记口诀(通用+差异化)

通用8条(所有页面)

1. 组件大驼峰,变量小驼峰,常量全大写

2. 数组List、对象Data、布尔is前缀

3. 交互handle、请求get、提交submit、重置reset

4. Props小驼峰模板短横线,只读不修改

5. TS必写泛型,赋值必兜底,拒绝any

6. 代码顺序固定分层,不乱序

7. 样式必加scoped,类名语义化

8. 监听必开deep+immediate

大屏专属3条

1、模块强制拆分,单文件精简

2. 零硬编码,所有样式颜色抽常量

3. 必做resize适配、销毁图表、清空定时器

欢迎关注:【前端小知识营地】

更多推荐