团队开发-代码风格指南
.vue 文件行数规范 一般来说,一个 .vue
文件行数建议不超过 400
行,超过建议组件化拆分
变量命名 引用类型使用 const
定义是因为 const
声明的变量不能被重新赋值,但其内容是可以改变的。这样可以防止变量被意外重新赋值,从而提高代码的稳定性和可读性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <script setup lang="ts" > const arr = []const obj = {}const fn = ( ) => { console .log ('123' ) } let num = 10 let str = 'abc' let flag = false const loading = ref (false )const person = reactive ({ name : '张三' , age : 20 })</script>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 <script setup lang="ts" > const loading = ref (false ) const visible = ref (false ) const showAddModal = ref (false ) const showAddDrawer = ref (false ) const isShowModal = ref<boolean>(false )const isLogin = ref (false ) const isVIP = ref (false ) const isDisabled = ref (true ) const form = reactive ({ name : '' , phone : '' , remark : '' }) const userInfo = ref ({}) const tableData = ref ([]) const treeData = ref ([]) const companyList = ref ([])const checkedList = ref ([])const selectedList = ref ([])const addressList = ref ([])const userList = [ { id : '01' , name : '张三' }, { id : '02' , name : '李四' } ] const tableData = []const optionsList = [ { label : '哈哈' , value : 1 }, { label : '嘻嘻' , value : 2 } ] const ids = []const selectedIds = []const activatedKeys = []const nums = [3 , 5 , 6 ]const strs = ['aaa' , 'bbb' , 'ccc' ]function getData ( ) { return nums.map (item => ({ value : item })) } async function getUserList ( ) { try { const res = await Api .getUserPage () userList = res.data } catch (error) { console .error ('Failed to fetch user list:' , error) } } function handleEdit ( ) {}function handleAdd ( ) {}function handleDelete ( ) {}function handleRename ( ) {}function handleMulDelete ( ) {}function handleSearch ( ) {}function handleBack ( ) {}function handleSubmit ( ) {}function handleConfirm ( ) {}function handleOk ( ) {}function handleCancel ( ) {}function handleOpen ( ) {}function handleClose ( ) {}function handleSave ( ) {}function getTableData ( ) {}function getTableList ( ) {}</script>
常用前缀
前缀
前缀 + 命名
含义
get
getUserInfo
获取用户信息
del/delete
delUserInfo
删除用户信息
update/add
updateUserInfo / addUserInfo
修改用户信息 / 增加用户信息
is
isTimeout
是否超时
has
hasUserInfo
有没有用户信息
handle
handleLogin
处理登录
calc
calcAverageSpeed
计算平均速度
vue 相关的命名 1 2 3 4 5 6 7 8 9 10 11 <script setup lang="ts" > const isEdit = ref (false )const title = computed (() => { return isEdit.value ? '编辑' : '新增' }) const title = computed (() => (isEdit.value ? '编辑' : '新增' ))</script>
1 2 3 4 5 6 7 <script setup lang="ts" > const form = reactive ({ name : '' , phone : '' }) </script>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <script setup lang="ts" > function getInitForm ( ) { return { name : '' , phone : '' , email : '' , sex : 1 , age : '' , } } const form = reactive (getInitForm ())function resetForm ( ) { for (const key in form) { delete form[key] } Object .assign (form, getInitForm ()) } </script>
1 2 3 4 5 6 7 8 9 10 <script setup lang="ts" > import { useAppStore, useUserStore } from '@/stores' import { useLoading } from '@/hooks' const appStore = useAppStore ()const userStore = useUserStore ()const { loading, setLoading } = useLoading ()</script>
写法技巧 尽量使用三目表达式
1 2 3 4 5 6 7 8 9 10 11 let isEdit = true let title = '' if (isEdit) { title = '编辑' } else { title = '新增' } let title = isEdit ? '编辑' : '新增'
善用 includes 方法
1 2 3 4 5 6 7 if (type === 1 || type === 2 || type === 3 ) {} if ([1 , 2 , 3 ].includes (type)) {}
使用箭头函数简化函数
1 2 3 4 5 6 7 function add (num1, num2 ) { return num1 + num2 } const add = (num1, num2 ) => num1 + num2
1 2 3 4 5 6 7 8 9 10 11 function getProportionColor (proportion ) { if (proportion < 30 ) { return 'danger' } if (proportion < 60 ) { return 'warning' } return 'success' }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 const status = 200 const message = '' if (status === 200 ) { message = '请求成功' } else if (status === 404 ) { message = '请求出错' } else if (status === 500 ) { message = '服务器错误' } const status = 200 const messageMap = { 200 : '请求成功' , 404 : '请求出错' , 500 : '服务器错误' } const message = messageMap[status]
如果函数参数超过两个务必使用对象传参
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <script setup lang="ts" > function createUser (name, phone, age ) { console .log ('姓名' , name) console .log ('手机' , phone) console .log ('年龄' , age) } createUser ('张三' , '178****2828' , 20 )function createUser2 ({ name, phone, age } ) { console .log ('姓名' , name) console .log ('手机' , phone) console .log ('年龄' , age) } createUser2 ({ name : '张三' , phone : '178****2828' , age : 20 })</script>
接口 api 的命名 命名规范: 操作名 + 后端模块名 + 功能名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import type * as T from './type' import http from '@/utils/http' export function getUserList ( ) { return http.get <PageRes <T.UserItem []>>('/user/list' ) } export function getUserDetail ( ) { return http.get <T.UserDetail >('/user/detail' ) } export function addUser (data: any ) { return http.post <T.UserAddResult >('/user/add' , data) } export function updateUser (data: any ) { return http.post <T.UserUpdateResult >('/user/update' , data) } export function deleteUser (data: { id: string } ) { return http.post <T.UserDeleteResult >('/user/delete' , data) }
正则使用示例 文件位置:@/utils/regexp.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 export const Phone = /^1[3-9]\d{9}$/ export const Email = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/ export const Code _6 = /^\d{6}$/ export const Code _4 = /^\d{4}$/ export const ColorRegex = /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/ export const OnlyCh = /^[\u4e00-\u9fa5]+$/gi export const OnlyEn = /^[a-zA-Z]*$/ export const Password = /^[a-zA-Z0-9]{6,16}$/
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <script lang="ts" setup> import { reactive } from 'vue' import { Message } from '@arco-design/web-vue' import * as Regexp from '@/utils/regexp' const form = reactive ({ name : '' , phone : '' }) function handleSubmit ( ) { if (!Regexp .Phone .test (form.phone )) { return Message .warning ('请输入正确手机号格式' ) } } </script>
页面模板 CSS 类名采用半角连接符(-)
1 2 3 4 5 6 7 8 <template > <div class ="detail" > <h3 class ="title" > 标题</h3 > <section class ="table-box" > <table > </table > </section > </div > </template >
全局组件-命名规范 Vue3 官网-风格指南
组件命名:单文件组件的文件名要全驼峰 (PascalCase)
1 2 3 Title.vue ThemeBtn.vue SvgIcon.vue
弹窗组件 Modal、抽屉组件 Drawer 的一般封装 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <template > <a-modal v-model:visible ="visible" :title ="title" @ok ="confirm" > </a-modal > </template > <script setup lang ="ts" > import { computed, reactive, ref } from 'vue' const visible = ref (false )const detailId = ref ('' )const isEdit = computed (() => !!detailId.value ) const title = computed (() => (isEdit.value ? '编辑' : '新增' ))const add = ( ) => { detailId.value = '' visible.value = true } const edit = (id: string ) => { detailId.value = id visible.value = true } defineExpose ({ add, edit })const confirm = ( ) => { console .log ('点击了确认按钮' ) } </script >
使用
模板里使用自定义组件:使用大写开头驼峰,双击好复制,对于搜索便利
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <template > <EditModal ref ="EditModalRef" > </EditModal > </template > <script setup lang ="ts" > import EditModal from './EditModal.vue' const EditModalRef = ref<InstanceType <typeof EditModal >>()const handleAdd = ( ) => { EditModalRef .value ?.add () } const handleEdit = (item: PersonItem ) => { EditModalRef .value ?.edit (item.id ) } </script >
组件使用建议 按钮、元素之间间隔尽量使用 Space 组件或者使用原子样式(推荐)
1 2 3 4 5 6 7 8 9 10 11 12 13 <template > <a-space :size ="10" > <a-button > 返回</a-button > <a-button type ="primary" > 提交</a-button > </a-space > </template > <ul class ="flex flex-row space-x-5" > <li class ="size-16 bg-red-400" > Item 1</li > <li class ="size-16 bg-red-500" > Item 2</li > <li class ="size-16 bg-red-600" > Item 3</li > </ul >
CSS 命名规范 使用小写连字符模式或者采用或者采用BEM
命名规范 BEM 命名规范
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // good .header .footer .main .content .container .page .detail .pane-left .pane-right .list .list-item // bad .Header .listItem .list-Item .List-Item;
BEM 命名规范
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <div class ="article" > <div class ="article__body" > <button class ="article__button--primary" > </button > <button class ="article__button--success" > </button > </div > </div > <style lang ='sass' scoped > .article { max-width : 1200px ; &__body { padding : 20px ; } &__button { padding : 5px 8px ; &--primary { background : blue; } &--success { background : green; } } } </style >
CSS 的命名词汇 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 前一个 prev 后一个 next 当前的 current 显示的 show 隐藏的 hide 打开的 open 关闭的 close 选中的 selected 有效的 active 默认的 default 反转的 toggle 禁用的 disabled 危险的 danger 主要的 primary 成功的 success 提醒的 info 警告的 warning 出错的 error 大型的 lg 小型的 sm 超小的 xs
1 2 3 4 5 6 7 文档 doc 头部 header(hd) 主体 body 尾部 footer(ft) 主栏 main 侧栏 side 容器 box/container
1 2 3 4 5 6 7 8 9 10 11 列表 list 列表项 item 表格 table 表单 form 链接 link 标题 caption/heading/title 菜单 menu 集合 group 条 bar 内容 content 结果 result
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 按钮 button(btn) 下拉菜单 dropdown 工具栏 toolbar 分页 page 缩略图 thumbnail 警告框 alert 进度条 progress 导航条 navbar 导航 nav 子导航 sub-nav 面包屑 breadcrumb(crumb) 标签 label 徽章 badge 巨幕 jumbotron 面板 panel 洼地 well 标签页 tab 提示框 tooltip 弹出框 popover 轮播图 carousel 手风琴 collapse 定位浮标 affix
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 品牌 brand 标志 logo 额外部件 addon 版权 copyright 注册 register(reg) 登录 login 搜索 search 热点 hot 帮助 help 信息 info 提示 tips 开关 toggle 新闻 news 广告 advertise(ad) 排行 top 下载 download
tailwind / unocss 使用技巧 轻松截断文本 另一个漂亮的实用程序类是line-clamp
,它允许您通过简单地添加一个数字(例如line-clamp-3
来截断多行文本:
1 2 3 4 5 6 7 8 9 10 11 <article class ="mt-20 border border-slate-300 rounded-md p-4 ml-6 text-white w-60" > <p class ="line-clamp-3" > Nulla dolor velit adipisicing duis excepteur esse in duis nostrud occaecat mollit incididunt deserunt sunt. Ut ut sunt laborum ex occaecat eu tempor labore enim adipisicing minim ad. Est in quis eu dolore occaecat excepteur fugiat dolore nisi aliqua fugiat enim ut cillum. Labore enim duis nostrud eu. Est ut eiusmod consequat irure quis deserunt ex. Enim laboris dolor magna pariatur. Dolor et ad sint voluptate sunt elit mollit officia ad enim sit consectetur enim. </p > </article >
渲染结果将在 3 行文本后放置一个省略号:
元素之间的空间 我们可以仅在父级上使用space-x-*, space-y-*
属性,而不是在每个子级上使用gap, margin, padding
属性。
1 2 3 4 5 <ul class ="flex flex-row space-x-5" > <li class ="size-16 bg-red-400" > Item 1</li > <li class ="size-16 bg-red-500" > Item 2</li > <li class ="size-16 bg-red-600" > Item 3</li > </ul >
组悬停 1 2 3 4 5 6 <button className ="group" > <span > Click!</span > <span className ="ml-2 inline-block group-hover:rotate-90" > → </span > </button >
自定义输入值 很多时候,预定义的类名不足以完成这项工作。我们可能想要向预定义的顺风类添加自定义值。这可以通过使用property-[value]
语法来实现。
1 <h5 className ="text-[#007bff] text-[4rem]" > Hello World</h5 >