web前端代码指南(vue3)

一、命名规范

市面上常用的命名规范:

  • camelCase(小驼峰式命名法 —— 首字母小写)
  • PascalCase(大驼峰式命名法 —— 首字母大写)
  • kebab-case(短横线连接式)
  • Snake(下划线连接式)

1.1 项目文件命名

1.1.1 项目命名

全部采用小写方式, 以短横线分隔。

  • 正例:mall-management-system
  • 反例:mall_management-system / mallManagementSystem

1.1.2 目录名

参照项目命名规则,有复数结构时,要采用复数命名法。

  • 正例:docs、assets、images、icons、components、directives、enums、hooks、utils、views
  • 反例:script / style / demo_scripts / demoStyles

1.VUE 的项目中的组件components 中的组件使用 PascalCase 命名

  • 正例: HeadSearch / PageLoading / Authorized / NoticeIcon
  • 反例: headSearch / page-loading

2. VUE 的项目中的页面目录使用 camelCase 命名

  • 正例:pageOne / shoppingCar / userManagement
  • 反例: shopping-car / UserManagement

1.1.3 图像文件名: Snake方式

全部采用Snake命名方式, 优先选择单个单词命名,多个单词命名以下划线连接。

banner_sina.gif
menu_aboutus.gif
menutitle_news.gif
logo_police.gif
logo_national.gif
pic_people.jpg
pic_TV.jpg

1.1.4 HTML 文件名: camelCase方式

优先选择单个单词命名,多个单词命名以camelCase方式。

|- errorReport.html
|- successReport.html

1.1.5 CSS 文件名: camelCase方式

全部采用camelCase方式, 优先选择单个单词命名,多个单词命名以短横线分隔。

|- index.scss
|- userCenter.scss

1.1.6 JavaScript 文件名: camelCase方式

全部采用camelCase写方式,优先选择单个单词命名,多个单词命名以短横线分隔。

|- index.js
|- util.js
|- userCenter.js

1.1.6 TypeScript 文件名: camelCase方式

全部采用camelCase写方式,优先选择单个单词命名,多个单词命名以短横线分隔。

|- index.ts
|- util.ts
|- userCenter.ts

除特定配置文件和依赖除外

1.2 Vue组件名

1.2.1 单文件组件名

文件扩展名为 .vuesingle-file components (单文件组件)。单文件组件名应该PascalCase方式。

components/
|- MyComponent.vue

1.2.2 紧密耦合的组件名

和父组件紧密耦合的子组件应该以父组件名作为前缀命名。 因为编辑器通常会按字母顺序组织文件,所以这样做可以把相关联的文件排在一起。

components/
|- RoleList.vue
|- RoleListItem.vue
|- RoleListItemButton.vue

1.2.3 组件名中单词顺序

组件名应该以高级别的 (通常是一般化描述的) 单词开头,以描述性的修饰词结尾。 因为编辑器通常会按字母顺序组织文件,所以现在组件之间的重要关系一目了然。如下组件主要是用于搜索和设置功能。

components/
|- SearchButtonClear.vue
|- SearchButtonRun.vue
|- SearchInputQuery.vue
|- SearchInputExcludeGlob.vue
|- SettingsCheckboxTerms.vue
|- SettingsCheckboxLaunchOnStartup.vue

1.2.4 完整单词的组件名

组件名应该倾向于完整而不是缩写。 编辑器中的自动补全已经让书写长命名的代价非常之低了,而其带来的明确性却是非常宝贵的。不常用的缩写尤其应该避免。

components/
|- StudentDashboardSettings.vue
|- RoleAuthorization.vue

1.2.5 全局组件命名

**全局组件应采用文件夹加index.vue格式。文件夹名称采用PascalCase格式命名。**其内部组件和页面内部组件采取组件规范。

全局组件
components/
|- ProTable
|  |- index.vue
|  |- components/
|  |  |- ProTableHeader.vue
|  |  |- ProTableBody.vue

1.2.8 api文件

  • api 目录
    文件、变量命名要与模块保持一致,注释明确。
  • 示例:Role模块
// api目录
api/modules/role.ts:// 添加角色  
addRole: (data) => { return postAxios('/role/add', data)  
}, // 删除角色 
deleteRole: (roleId) => {   return postAxios('/role/delete/' + roleId)   
},

1.2.9 Vue3项目文件资源目录示例:

my-project-name/
├─ .husky                             # husky 配置文件
├─ .vscode                            # VSCode 推荐配置
├─ build                              # Vite 配置项
├─ public                             # 静态资源文件
├─ docs                               # 项目的细化文档目录(可选)
├─ node_modules                       # 下载的依赖包
├─ src                                # 源码目录
│  ├─ api                             # http 请求目录
│  │  ├─ config                       # http 配置项
│  │  ├─ helper                       # http 封装
│  │  ├─ interface                    # http 接口类型
│  │  │  ├─ userCenter.ts             # http 用户接口
│  │  ├─ modules                      # http 接口模块
│  │  │  ├─ userCenter.ts             # http 用户api模块
│  │  └─ index.ts                     # http 请求入口
│  ├─ assets                          # 静态资源目录
│  ├─ components                      # 全局组件
│  │  ├─ ProTable                     # ProTable组件文件夹
│  │  │  ├─ index.vue                 # ProTable组件
│  │  │  ├─ interface                 # ProTable公共接口
│  │  │  │  ├─ index.ts               # ProTable公共接口文件
│  │  │  ├─ components                # ProTable内部组件
│  │  │  │  ├─ Pagination.vue         # ProTable内部分页组件
│  │  │  │  ├─ TableColumn.vue        # ProTable内部列组件
│  ├─ config                          # 全局配置项
│  ├─ constants                       # 全局常量
│  ├─ enums                           # 项目常用枚举
│  ├─ hooks                           # 常用 Hooks 封装
│  ├─ languages                       # 语言国际化 i18n
│  ├─ directives                      # 全局指令文件
│  ├─ mockApi                         # 模拟接口,临时存放
│  ├─ mockData                        # 模拟数据,临时存放
│  ├─ plugins                         # 插件
│  ├─ routers                         # 路由管理
│  ├─ stores                          # pinia store
│  ├─ styles                          # 全局样式文件
│  ├─ utils                           # 常用工具库
│  ├─ views                           # 页面存放目录
│  │  ├─ role                         # role模块名
│  │  │  ├─ userRole                  # 用户role
│  │  │  │  ├─ index.vue              # 用户role首页/列表
│  │  │  │  ├─ index.scss             # 用户role css
│  │  │  │  └─ detail.vue             # role详情页面
│  │  │  ├─ systemRole                # 系统role
│  │  │  ├─ components                # role模块通用组件文件夹
│  │  │  │  └─ RoleAuthorization.vue  # role授权组件
│  │  │  └─ interface                 # role公共接口文件夹
│  │  └─ user                         # user模块名
│  ├─ App.vue                         # 项目根组件
│  ├─ main.ts                         # 入口文件
│  └─ vite-env.d.ts                   # 指定 ts 识别 vue
├─ .editorconfig                      # 统一不同编辑器的编码风格
├─ .env                               # vite 常用配置
├─ .env.development                   # 开发环境配置
├─ .env.production                    # 生产环境配置
├─ .env.test                          # 测试环境配置
├─ .eslintignore                      # 忽略 Eslint 校验
├─ .eslintrc.cjs                      # Eslint 校验配置文件
├─ .gitignore                         # 忽略 git 提交
├─ .prettierignore                    # 忽略 Prettier 格式化
├─ .prettierrc.cjs                    # Prettier 格式化配置
├─ .stylelintignore                   # 忽略 stylelint 格式化
├─ .stylelintrc.cjs                   # stylelint 样式格式化配置
├─ CHANGELOG.md                       # 项目更新日志
├─ commitlint.config.cjs              # git 提交规范配置
├─ index.html                         # 入口 html
├─ LICENSE                            # 开源协议文件
├─ lint-staged.config.cjs             # lint-staged 配置文件
├─ package-lock.json                  # 依赖包包版本锁
├─ package.json                       # 依赖包管理
├─ postcss.config.cjs                 # postcss 配置
├─ README.md                          # README 介绍
├─ tsconfig.json                      # typescript 全局配置
└─ vite.config.ts                     # vite 全局配置文件

1.3 代码参数命名

1.3.1 name

组件名应该始终是多个单词,应该始终是 PascalCase 的。 根组件 App 以及 <transition>、<component> 之类的 Vue 内置组件除外。

<script setup lang="ts" name="ProTable"></script>

1.3.2 prop

在声明 prop 的时候,其命名应该始终使用 camelCase,而在模板和 JSX 中应该始终使用 kebab-case。我们单纯的遵循每个语言的约定,在 JavaScript 中更自然的是 camelCase。而在 HTML 中则是 kebab-case

<TableColumn col-setting="colSetting"/><script>defineProps<{ colSetting: ColumnProps[] }>();
</script>

1.3.3 router

**Vue Router Path 命名采用 camelCase 格式。**和views页面尽量保持一致。

// good
{"path": "/proTable","name": "proTable","redirect": "/proTable/useProTable","meta": {"icon": "MessageBox",},"children": [{"path": "/proTable/useProTable","name": "useProTable","component": "/proTable/useProTable/index","meta": {"icon": "Menu",}]
},
// bad
{path: '/user_info', // user_info 当成一个单词name: 'UserInfo',meta: {title: ' - 用户',desc: ''},component: () => import('@/views/file/user-Info.vue')
},

path除了采用camelCase命名规范以外,必须以 / 开头,即使是children里的path也要以 / 开头

目的:
经常有这样的场景:某个页面有问题,要立刻找到这个vue文件,如果不用以/开头,pathparentchildren组成的,可能经常需要在router文件里搜索多次才能找到,而如果以/开头,则能立刻搜索到对应的组件

1.3.4 模板中组件

对于绝大多数项目来说,在 单文件组件 和 字符串模板 中 组件名 应该总是 PascalCase 的 ,
但是在 DOM 模板中总是 kebab-case 的。

<!-- 在单文件组件、字符串模板和 JSX 中 -->
<MyComponent /><Row><table :column="data"/></Row><!-- 在 DOM 模板中 --> 
<my-component></my-component>

1.3.5 变量

  • 命名方法:camelCase
  • 命名规范:类型 + 对象描述或属性的方式
// good
let tableTitle = "LoginTable"
let mySchool = "我的学校"// bad
var getTitle = "LoginTable"

1.3.6 常量

  • 命名方法:全部大写下划线分割
  • 命名规范:使用大写字母和下划线来组合命名,下划线用以分割单词
const MAX_COUNT = 10
const URL = 'http://test.host.com'

1.3.7 方法

  • 命名方法:camelCase
  • 命名规范:统一使用动词或者动词 + 名词形式
// 1、普通情况下,使用动词 + 名词形式
// good
jumpPage、openCarInfoDialog// bad
go、nextPage、show、open、login// 2、请求数据方法,以 data 结尾
// good
getListData、postFormData// bad
takeData、confirmData、getList、postForm// 3、单个动词的情况
init、refresh
动词含义返回值
can判断是否可执行某个动作 (权 )函数返回一个布尔值。true:可执行;false:不可执行;
has判断是否含有某个值函数返回一个布尔值。true:含有此值;false:不含有此值;
is判断是否为某个值函数返回一个布尔值。true:为某个值;false:不为某个值;
get获取某个值函数返回一个非布尔值
set设置某个值无返回值、返回是否设置成功或者返回链式对象

附: 函数方法常用的动词:

get 获取/set 设置,
add 增加/remove 删除
create 创建/destory 移除
start 启动/stop 停止
open 打开/close 关闭,
read 读取/write 
load 写入/save 保存,
create 创建/destroy 销毁
begin 开始/end 结束,
backup 备份/restore 恢复,
import 导入/export 导出,
split 分割/merge 合并,
inject 注入/extract 提取,
attach 附着/detach 脱离,
bind 绑定/separate 分离,
view 查看/browse 浏览,
edit 编辑/modify 修改,
select 选取/mark 标记,
copy 复制/paste 粘贴,
undo 撤销/redo 重做,
insert 插入/delete 移除,
add 加入/append 添加,
clean 清理/clear 清除,
index 索引/sort 排序,
find 查找/search 搜索,
increase 增加/decrease 减少,
play 播放/pause 暂停,
launch 启动/run 运行,
compile 编译/execute 执行,
debug 调试/trace 跟踪,
observe 观察/listen 监听,
build 构建/publish 发布,
input 输入/output 输出,
encode 编码/decode 解码,
encrypt 加密/decrypt 解密,
compress 压缩/decompress 解压缩,
pack 打包/unpack 解包,
parse 解析/emit 生成,
connect 连接/disconnect 断开,
send 发送/receive 接收,
download 下载/upload 上传,
refresh 刷新/synchronize 同步,
update 更新/revert 复原,
lock 锁定/unlock 解锁,
check out 签出/check in 签入,
submit 提交/commit 交付,
push 推/pull 拉,
expand 展开/collapse 折叠,
begin 起始/end 结束,
start 开始/finish 完成,
enter 进入/exit 退出,
abort 放弃/quit 离开,
obsolete 废弃/depreciate 废旧,
collect 收集/aggregate 聚集

1.3.8 自定义事件

自定义事件应始终使用 kebab-case 的事件名。

不同于组件和 prop,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称。

// 父组件中调用
<MyComponent @my-event="handleDoSomething" /><script>
// 子组件中定义
const emit = defineEmits<{"my-event": [];
}>();emit("my-event", data);
</script>

1.3.10 事件方法

  • 命名方法:camelCase
  • 命名规范:handle + 名称(可选)+ 动词
<template><div @click="handleClick(data)" ></div>
</template><script>
/*** @description 点击事件* @param data 所需要的参数* */
const handleClick = (data: DataInterface) => {...
};
</script>

1.3.11 api命名

变量命名要与尽可能与模块保持一致,写好注释。

// 添加角色  
addRole: (data) => { return postAxios('/role/add', data)  
}, // 删除角色 
deleteRole: (roleId) => {   return postAxios('/role/delete/' + roleId)   
},

1.3.12 TS接口命名

  • 类型使用 PascalCase 命名。不要使用I做为接口名前缀。接口成员使用 camelCase 方式命名
// Good
interface Foo {bar: number;baz(): number;
}// Bad
interface IFoo {Bar: number;Baz(): number;
}
  • 枚举值使用 PascalCase 命名。
// 推荐
enum StatusEnum {SUCCESS = 'success'
}// Good
enum StatusEnum {Success = 'success'
}// Bad
enum Status {success = 'success'
}

二、代码规范

2.1 Vue

2.1.1 代码结构

  1. script标签内部加上name属性, 用于定义组件名称
  2. script 标签内部结构顺序:
    1. import引入顺序
      1. 官方/生态 方法、类型
      2. 全局方法、类型、组件
      3. 依赖方法、类型、组件
      4. 局部方法、类型、组件
    2. 接收参数
      1. 定义类型接口
      2. 设置props
    3. 功能代码(推荐将统一功能的代码写在聚集在一起)
      1. 功能一
        1. 定义接口类型
        2. 定义数据
        3. 定义计算属性
        4. 定义方法
        5. 定义数据监视
      2. 功能二
    4. 生命周期
    5. 其他方法
    6. 导出内容

示例:

<script setup lang="ts" name="home">
{/* 1.引入 */}{/* 引入官方方法 */}import { reactive, ref, withDefaults } from "vue";{/* 引入路由 */}import { useRouter } from "vue-router";{/* 全局方法 */}import { useGlobalStore } from "@/stores/modules/global";{/* 引入工具类 */}import { globalUtils } from "@/utils";{/* {引入api} */}import { loginApi } from "@/api/modules/login";{/* 引入全局组件 */}import { DefaultComponents } from "@/components/DefaultComponents";{/* 引入依赖类型 */}import type { FormInstance, FormRules } from "element-plus";{/* 引入依赖组件 */}import { ElMessage } from "element-plus";{/* 引入自定义组件 */}import { TableComponents } from "./components/TableComponents";{/* 引入自定义接口类型 */}import { TableData } from "./interface/index.ts";{/* 2.接收传参 */}interface Props {}const props = withDefaults(defineProps<Props>(), {...默认值});{/* 3.功能代码 */}{/* 功能一 */}type StringType = 'string'const stringData: StringType = 'string';const stringDataComputed = computed(() => {stringData});const setStringData = () => {console.log(stringDataComputed)};watch(props, () => {setStringData()});{/* 功能二 */}interface RuleForm {name: string;date1: string;date2: string;}const ruleForm = reactive<RuleForm>({});const rules = reactive<FormRules<RuleForm>>({});{/* 功能三 */}const globalStore = useGlobalStore();const {isLoading} = globalStore;const isLoadingSync = () => {console.log(isLoading)};{/* 4.生命周期 */}onMounted(() => {init()});{/* 5.其他方法 */}const init = () => {};const submitForm = async (formEl: FormInstance | undefined) => {};const resetForm = (formEl: FormInstance | undefined) => {};{/* 6.导出内容 */}defineExpose({})
</script>

2.1.2 data

  1. 若需要一个基本类型的响应式数据,必须使用ref
  2. 若需要一个响应式对象,层级不深,ref、reactive都可以
  3. 若需要一个响应式对象,且层级较深,推荐使用reactive,(form表单数据推荐使用reactive
<script>
const num = ref<number>(0);const ruleForm = reactive<RuleForm>({});
</script>

2.1.3 computed

应该把复杂计算属性分割为尽可能多的更简单的属性。 小的、专注的计算属性减少了信息使用时的假设性限制,所以需求变更时也用不着那么多重构了。

<script>
// good
const basePrice = computed(() => manufactureCost / (1 - profitMargin))
const discount = computed(() => basePrice * (discountPercent || 0))
const finalPrice = computed(() => basePrice - discount)// bad
const price = computed(() => { var basePrice = manufactureCost / (1 - profitMargin) return ( basePrice - basePrice * (discountPercent || 0) ) 
})
</script>

2.1.4 为 v-for 设置键值

在组件上必须用 key 搭配 v-for,以便维护内部组件及其子树的状态。

<ul><liv-for="todo in todos":key="todo.id">{{ todo.text }}</li>
</ul>

2.1.5 禁止v-ifv-for 放在同一个元素上

永远不要把 v-ifv-for 同时用在同一个元素上。因为这可能导致渲染逻辑变得复杂且难以预测。
Vue3中: 当它们同时存在于一个节点上时,v-if 比 v-for 的优先级更高。这意味着 v-if 的条件将无法访问到 v-for 作用域内定义的变量别名:

<!--这会抛出一个错误,因为属性 todo 此时没有在该实例上定义
-->
<li v-for="todo in todos" v-if="!todo.isComplete">{{ todo.name }}
</li>

在外先包装一层 <template> 再在其上使用 v-for 可以解决这个问题 (这也更加明显易读):

<template v-for="todo in todos"><li v-if="!todo.isComplete">{{ todo.name }}</li>
</template>

一般我们在两种常见的情况下会倾向于这样做:

  • 为了过滤一个列表中的项目 (比如 v-for="user in users" v-if="user.isActive")。在这种情形下,请将 users 替换为一个计算属性 (比如 activeUsers),让其返回过滤后的列表。
<ul><liv-for="user in activeUsers":key="user.id">{{ user.name }}</li>
</ul>
const activeUsers = computed(() => users.filter(user => user.isActive))
  • 为了避免渲染本应该被隐藏的列表 (比如 v-for="user in users" v-if="shouldShowUsers")。这种情形下,请将v-if移动至容器元素上 (比如 ul, ol)。
// good
<ul v-if="shouldShowUsers"><liv-for="user in users":key="user.id">{{ user.name }}</li>
</ul>// bad
<ul><liv-for="user in users"v-if="shouldShowUsers":key="user.id">{{ user.name }}</li>
</ul>

2.1.6 多个 attribute 的元素

多个 attribute 的元素占满一行之后应该分多行撰写,每个 attribute 一行。

//good
<img src="https://vuejs.org/images/logo.png" alt="Vue Logo" title="vue" width="100" height="100" align="right"loading="lazy"><MyComponent foo="a" bar="b" baz="c"/>//bad
<img src="https://vuejs.org/images/logo.png" alt="Vue Logo" title="vue" width="100" 
height="100" align="right" loading="lazy">
<MyComponent foo="a" bar="b" baz="c"
/>

2.1.7 模板中简单的表达式

组件模板应该只包含简单的表达式,复杂的表达式则应该重构为计算属性或方法。

复杂表达式会让你的模板变得不那么声明式。我们应该尽量描述应该出现的是什么,而非如何计算那个值。而且计算属性和方法使得代码可以重用。

// good
// 在模板中
{{ normalizedFullName }}// 复杂表达式已经移入一个计算属性
const normalizedFullName = computed(() => {return fullName.split(' ').map(function (word) {return word[0].toUpperCase() + word.slice(1)}).join(' ')
})// bad
{{fullName.split(' ').map((word) => {return word[0].toUpperCase() + word.slice(1)}).join(' ')
}}

2.1.8 指令缩写

  • : 表示 v-bind:
  • @ 表示 v-on:
  • # 表示 v-slot:
<input:value="newTodoText":placeholder="newTodoInstructions"><input@input="onInput"@focus="onFocus"><template #header><h1>Here might be a page title</h1>
</template><template #footer><p>Here's some contact info</p>
</template><Child #default="params">...
</Child>

2.2 HTML

2.2.1 文件模板

HTML5 文件模板:

<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><title>HTML5标准模版</title></head><body></body>
</html>

移动端:

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no"><meta name="format-detection" content="telephone=no"><title>移动端HTML模版</title><!-- S DNS预解析 --><link rel="dns-prefetch" href=""><!-- E DNS预解析 --><!-- S 线上样式页面片,开发请直接取消注释引用 --><!-- #include virtual="" --><!-- E 线上样式页面片 --><!-- S 本地调试,根据开发模式选择调试方式,请开发删除 --><link rel="stylesheet" href="css/index.css"><!-- /本地调试方式 --><link rel="stylesheet" href="http://srcPath/index.css"><!-- /开发机调试方式 --><!-- E 本地调试 --></head>
<body>
</body>
</html>

PC 端:

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="keywords" content="your keywords"><meta name="description" content="your description"><meta name="author" content="author,email address"><meta name="robots" content="index,follow"><meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"><meta name="renderer" content="ie-stand"><title>PC端HTML模版</title><!-- S DNS预解析 --><link rel="dns-prefetch" href=""><!-- E DNS预解析 --><!-- S 线上样式页面片,开发请直接取消注释引用 --><!-- #include virtual="" --><!-- E 线上样式页面片 --><!-- S 本地调试,根据开发模式选择调试方式,请开发删除 --><link rel="stylesheet" href="css/index.css"><!-- /本地调试方式 --><link rel="stylesheet" href="http://srcPath/index.css"><!-- /开发机调试方式 --><!-- E 本地调试 -->
</head>
<body>
</body>
</html>

2.2.2 元素及标签闭合

HTML 元素共有以下5种:

  • 空元素:area、base、br、col、command、embed、hr、img、input、keygen、link、meta、param、source、track、wbr
  • 原始文本元素:script、style
  • RCDATA 元素:textarea、title
  • 外来元素:来自 MathML 命名空间和 SVG 命名空间的元素
  • 常规元素:其他 HTML 允许的元素都称为常规元素

为了能让浏览器更好的解析代码以及能让代码具有更好的可读性,有如下约定:

  • 所有具有开始标签和结束标签的元素都要写上起止标签,某些允许省略开始标签或和束标签的元素亦都要写上。
  • 空元素标签都不加 / 字符。
<!-- good -->
<div><h1>我是h1标题</h1><p>我是一段文字,我有始有终,浏览器能正确解析</p>
</div><br data-tomark-pass><!-- bad -->
<div><h1>我是h1标题</h1><p>我是一段文字,我有始无终,浏览器亦能正确解析
</div><br/>

2.2.3 代码嵌套

元素嵌套规范,每个块状元素独立一行,内联元素可选。

<!-- good -->
<div><h1></h1><p></p>
</div> 
<p><span></span><span></span></p><!-- bad -->
<div><h1></h1><p></p>
</div> 
<p> <span></span><span></span>
</p>

段落元素与标题元素只能嵌套内联元素。

<!-- good -->
<h1><span></span></h1>
<p><span></span><span></span></p><!-- bad -->
<h1><div></div></h1>
<p><div></div><div></div></p>

2.3 CSS

2.3.1 样式文件

样式文件必须写上 @charset 规则,并且一定要在样式文件的第一行首个字符位置开始写,编码名用 “UTF-8”

Vite构建工具的编码设置通常是基于项目的配置文件和构建过程中的默认设置。在大多数情况下,Vite默认使用UTF-8编码,这是现代Web开发中广泛使用的字符编码标准

  • 推荐:
@charset "UTF-8";
.demo {}
  • 不推荐:
/* @charset规则不在文件首行首个字符开始 */
@charset "UTF-8";
.demo {}/* @charset规则没有用小写 */
@CHARSET "UTF-8";
.demo {}/* 无@charset规则 */
.demo {}

2.3.2 代码格式化

样式书写一般有两种:一种是紧凑格式 (Compact),一种是展开格式(Expanded)。

  • 推荐:展开格式(Expanded
.demo {display: block;width: 50px;
}
  • 不推荐:紧凑格式 (Compact
.demo { display: block; width: 50px;}

2.3.3 代码大小写

样式选择器,属性名,属性值关键字全部使用小写字母书写,属性字符串允许使用大小写。

  • 推荐:
.demo {display: block;
}
  • 不推荐:
.demo {DISPLAY: BLOCK;
}

2.3.4 代码易读性

  1. 左括号与类名之间一个空格,冒号与属性值之间一个空格。
  • 推荐:
.demo {width: 100%;
}
  • 不推荐:
.demo{width:100%;
}
  1. 逗号分隔的取值,逗号之后一个空格。
  • 推荐:
.demo {box-shadow: 1px 1px 1px #333, 2px 2px 2px #ccc;
}
  • 不推荐:
.demo {box-shadow: 1px 1px 1px #333,2px 2px 2px #ccc;
}
  1. 为单个 CSS 选择器或新声明开启新行。
  • 推荐:
.demo, .demo_logo, .demo_hd {color: #ff0;
}.nav{color: #fff;
}
  • 不推荐:
.demo, .demo_logo, .demo_hd {color: #ff0;
}.nav{color: #fff;
}
  1. 颜色值 rgb() rgba() hsl() hsla() rect() 中不需有空格,且取值不要带有不必要的 0
  • 推荐:
.demo {color: rgba(255,255,255,.5);
}
  • 不推荐:
.demo {color: rgba( 255, 255, 255, 0.5 );
}
  1. 属性值十六进制数值不推荐使用简写。
  • 推荐:
.demo {color: #ffffff;
}
  • 不推荐:
.demo {color: #fff;
}
  1. 不要为 0 指明单位。
  • 推荐:
.demo {margin: 0 10px;
}
  • 不推荐:
.demo {margin: 0px 10px;
}

2.3.5 属性值引号

CSS 属性值需要用到引号时,统一使用双引号。

  • 推荐:
.demo {font-family: "Hiragino Sans GB";
}
  • 不推荐:
.demo {font-family: 'Hiragino Sans GB';
}

2.3.6 属性书写顺序建议

样式建议遵循以下顺序:

  1. 位置属性: position、top、right、z-index
  2. 显示和框模型 box-sizing、display、float、width、height、margin、padding
  3. 字体,行间距,颜色,文本 font、line-height、color、text-align
  4. 光标属性 cursor
  5. 背景和边框 background、border、border-radius、box-shadow
  6. 其他一些视觉或动画属性 opacity、transition、transform、animation
.demo {position,top,right,bottom,left,z-index,box-sizing,display,flex,flex-align,flex-basis,flex-direction,flex-wrap,flex-flow,flex-shrink,flex-grow,flex-order,flex-pack,align-content,align-items,align-self,justify-content,order,float,width,min-width,max-width,height,min-height,max-height,padding,padding-top,padding-right,padding-bottom,padding-left,margin,margin-top,margin-right,margin-bottom,margin-left,overflow,overflow-x,overflow-y,-webkit-overflow-scrolling,-ms-overflow-x,-ms-overflow-y,-ms-overflow-style,columns,column-count,column-fill,column-gap,column-rule,column-rule-width,column-rule-style,column-rule-color,column-span,column-width,orphans,widows,clip,clear,font,font-family,font-size,font-style,font-weight,font-variant,font-size-adjust,font-stretch,font-effect,font-emphasize,font-emphasize-position,font-emphasize-style,font-smooth,src,hyphens,line-height,color,text-align,text-align-last,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-decoration,text-indent,text-justify,text-outline,-ms-text-overflow,text-overflow,text-overflow-ellipsis,text-overflow-mode,text-shadow,text-transform,text-wrap,-webkit-text-size-adjust,-ms-text-size-adjust,letter-spacing,-ms-word-break,word-break,word-spacing,-ms-word-wrap,word-wrap,overflow-wrap,tab-size,white-space,vertical-align,direction,unicode-bidi,list-style,list-style-position,list-style-type,list-style-image,pointer-events,-ms-touch-action,touch-action,cursor,visibility,zoom,table-layout,empty-cells,caption-side,border-spacing,border-collapse,content,quotes,counter-reset,counter-increment,resize,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,background,background-color,background-image,filter,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,border,border-color,border-style,border-width,border-top,border-top-color,border-top-style,border-top-width,border-right,border-right-color,border-right-style,border-right-width,border-bottom,border-bottom-color,border-bottom-style,border-bottom-width,border-left,border-left-color,border-left-style,border-left-width,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,box-shadow,opacity,-ms-interpolation-mode,page-break-after,page-break-before,page-break-inside,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,perspective,appearance,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,animation-fill-mode,fill,stroke
}

3.3.7 CSS3 浏览器私有前缀

CSS3 浏览器私有前缀在前,标准前缀在后。

.demo {-webkit-border-color: #ffffff;-moz-border-color: #ffffff;-o-border-color: #ffffff;-ms-border-color: #ffffff;border-color: #ffffff;
}

3.3.8 scss、lesscss预处理语言

  1. 代码组织

    1. @import
    2. 变量声明
    3. 样式声明
    @import "mixins/size.less"; 
    @default-text-color: #ffffff; 
    .page { width: 960px; margin: 0 auto;
    }
    
  2. 避免嵌套层级过多

    将嵌套深度限制在3级。对于超过4级的嵌套,给予重新评估。这可以避免出现过于详实的CSS选择器。避免大量的嵌套规则。当可读性受到影响时,将之打断。推荐避免出现多于20行的嵌套规则出现

  • 推荐
.main-title{   .demo{      ...}
}.demo{.title{    .name{       color:#fff}  }
} 
  • 不推荐
.main{ .demo{.title{    .name{       color:#fff}  }} 
}

2.4 JavaScript

2.4.1 单行代码块

在单行代码块中使用空格。

  • 推荐:
const a = () => true
if (condition) return;
  • 不推荐:
function foo () {return true}
if (foo) {bar = 0}

2.4.2 大括号风格

在编程过程中,大括号风格与缩进风格紧密联系,用来描述大括号相对代码块位置的方法有很多。在 JavaScript 中,主要有三种风格,如下:

  • 【推荐】One True Brace Style
if (foo) {bar()
} else {baz()
}
  • Stroustrup
if (foo) {bar()
}
else {baz()
}
  • Allman
if (foo)
{bar()
}
else
{baz()
}

下列关键字后必须有大括号:if, else, for, while, do, switch, try, catch, finally, with。,若是单行代码块,则不写大括号。

  • 推荐:
const condition = Math.random() > 0.5;
if (condition) {return;
}
或者
if (condition) return;
  • 不推荐:
if (condition) { return };

2.4.3 代码中的空格

  1. 逗号前后的空格可以提高代码的可读性,团队约定在逗号后面使用空格,逗号前面不加空格。
  • 推荐:
let foo = 1, bar = 2
  • 不推荐:
let foo = 1,bar = 2let foo = 1 , bar = 2let foo = 1 ,bar = 2
  1. 对象字面量的键和值之间不能存在空格,且要求对象字面量的冒号和值之间存在一个空格。
  • 推荐:
let obj = { "foo": "haha" }
  • 不推荐:
let obj = { "foo" : "haha" }
  1. 代码块前要添加空格。
  • 推荐:
if (a) {b()
}function a () {}
  • 不推荐:
if (a){b()
}function a (){}
  1. 函数声明括号前要加空格。
  • 推荐:
function func (x) {// ...
}
  • 不推荐:
function func(x) {// ...
}
  1. 在函数调用时,禁止使用空格。
  • 推荐:
func()
  • 不推荐:
func ()func
()
  1. 在操作符前后都需要添加空格。
  • 推荐:
let sum = 1 + 2
  • 不推荐:
let sum = 1+2

2.4.4 undefined 判断

永远不要直接使用 undefined 进行变量判断;使用 typeof 和字符串'undefined'对变量进行判断。

  • 推荐:
if (typeof person === 'undefined') {  ...
}
  • 不推荐:
if (person === undefined) {...
}

2.4.5 函数参数不能超过 3 个

超过 3 个的情况使用对象的方式进行传递。

  • 推荐
const foo = args => {const { a, b, c, d } = args;console.log(a, b, c, d);
};
  • 不推荐
const foo = (a, b, c, d) => {console.log(a, b, c, d);
};

2.4.6 注册事件与卸载事件的代码必须同时存在

  • 推荐
<script>
onMounted(() => {window.addEventListener('resize', resizeHandler);
});
onUnmounted(() => {window.removeEventListener("resize", resize);
});
</script>

2.4.7 条件判断和循环最多三层

条件判断能使用三目运算符和逻辑运算符解决的,就不要使用条件判断,但是谨记不要写太长的三目运算符。如果超过 3 层请抽成函数,并写清楚注释。

2.4.8 避免无意义的条件判断

优先使用 ||&& 运算符。

  • 推荐
function createMicrobrewery(name) {let breweryName = name || 'Hipster Brew Co.';
}
  • 不推荐
function createMicrobrewery(name) {let breweryName;if (name) {breweryName = name;} else {breweryName = 'Hipster Brew Co.';}
}

2.4.9 使用模板字符串

避免直接拼接字符串带来的代码可读性降低、易出现 bug 等问题。

  • 推荐
const date = '2011-01-01';
const time = '12:00';const fullTime = `${date} ${time}`;
  • 不推荐
const fullTime = date + ' ' + time;

三、代码注释

注释的目的:

  • 提高代码的可读性,从而提高代码的可维护性

注释的原则:

  • 如无必要,勿增注释 ( As short as possible )
  • 如有必要,尽量详尽 ( As long as necessary )

3.1 HTML 文件注释

3.1.1 单行注释

一般用于简单的描述,如某些状态描述、属性描述等。
注释内容前后各一个空格字符,注释位于要注释代码的上面,单独占一行。

  • 推荐:
<!-- Comment Text -->
<div>...</div>
  • 不推荐
<div>...</div><!-- Comment Text --><div><!-- Comment Text -->...
</div>

3.1.2 模块注释

一般用于描述模块的名称以及模块开始与结束的位置。

注释内容前后各一个空格字符, <!-- S Comment Text -->表示模块开始, <!-- E Comment Text -->表示模块结束,模块与模块之间相隔一行。

  • 推荐:
<!-- S Comment Text A --> 
<div class="mod_a">...
</div>
<!-- E Comment Text A --><!-- S Comment Text B --> 
<div class="mod_b">...
</div>
<!-- E Comment Text B -->
  • 不推荐
<!-- S Comment Text A -->
<div class="mod_a">...
</div>
<!-- E Comment Text A -->
<!-- S Comment Text B --> 
<div class="mod_b">...
</div>
<!-- E Comment Text B -->

3.1.3 嵌套模块注释

当模块注释内再出现模块注释的时候,为了突出主要模块,嵌套模块不再使用。

<!-- S Comment Text -->
<!-- E Comment Text -->

而改用

<!-- /Comment Text -->

注释写在模块结尾标签底部,单独一行。

<!-- S Comment Text A -->
<div class="mod_a"><div class="mod_b">...</div><!-- /mod_b --><div class="mod_c">...</div><!-- /mod_c --></div>
<!-- E Comment Text A -->

3.2 CSS 文件注释

3.2.1 单行注释

注释内容第一个字符和最后一个字符都是一个空格字符,单独占一行,行与行之间相隔一行。

  • 推荐:
/* Comment Text */ 
.demo {} /* Comment Text */ 
.demo {}
  • 不推荐:
/*Comment Text*/
.demo {display: block;
}.demo {display: block;/*Comment Text*/
}

3.2.2 模块注释

注释内容第一个字符和最后一个字符都是一个空格字符,/* 与 模块信息描述占一行,多个横线分隔符 -*/ 占一行,行与行之间相隔两行。

  • 推荐:
/* Module A
---------------------------------------------------------------- */
.mod_a {}/* Module B
---------------------------------------------------------------- */
.mod_b {}
  • 不推荐:
/* Module A ---------------------------------------------------- */
.mod_a {}
/* Module B ---------------------------------------------------- */
.mod_b {}

3.2.3 文件注释

在样式文件编码声明 @charset 语句下面注明页面名称、作者、创建日期等信息。

@charset "UTF-8";
/*** @description File Info* @author Author Name* @date 2015-10-10*/

3.3 JavaScript 文件注释

3.3.1 单行注释

单行注释使用 //,注释应单独一行写在被注释对象的上方,不要追加在某条语句的后面。

  • 推荐:
// is current tab
const active = true
  • 不推荐:
const active = true // is current tab

注释行的上方需要有一个空行(除非注释行上方是一个块的顶部),以增加可读性。

  • 推荐:
function getType () {  console.log('fetching type...')// set the default type to 'no type'const type = this.type || 'no type'return type
}
// 注释行上面是一个块的顶部时不需要空行
function getType () {  // set the default type to 'no type'const type = this.type || 'no type'   return type
}
  • 不推荐:
function getType () {  console.log('fetching type...')// set the default type to 'no type'const type = this.type || 'no type'return type
}

3.3.2 多行注释

多行注释使用 /** ... */,而不是多行的 //

  • 推荐:
/*** @name make() returns a new element* @description based on the passed-in tag name* @param { Boolean } tag tag name* @returns { String } element name*/
function make (tag) {// ...return element
}
  • 不推荐:
// make() returns a new element
// based on the passed in tag name
function make (tag) {// ...return element
}

3.3.3 注释空格

注释内容和注释符之间需要有一个空格,以增加可读性。eslint: spaced-comment。

  • 推荐:
// is current tab
const active = true/*** @name make() returns a new element* @description based on the passed-in tag name* @param { Boolean } tag tag name* @returns { String } element name*/
function make(tag) {  // ...return element
}
  • 不推荐:
//is current tab
const active = true/***make() returns a new element*based on the passed-in tag name*/
function make(tag) {  // ...return element
}

3.3.4 特殊标记

有时我们发现某个可能的 bug,但因为一些原因还没法修复;或者某个地方还有一些待完成的功能,这时我们需要使用相应的特殊标记注释来告知未来的自己或合作者。常用的特殊标记有两种:

  • // FIXME : 说明问题是什么

  • // TODO : 说明还要做什么或者问题的解决方案

class Calculator extends Abacus {constructor () {super ()// FIXME: shouldn’t use a global heretotal = 0// TODO: total should be configurable by an options paramthis.total = 0}
}

3.3.5 文档类注释

文档类注释,如函数、类、文件、事件等;尽量使用 jsdoc 规范。

/*** Book类,代表一个书本.* @constructor* @param {string} title - 书本的标题.* @param {string} author - 书本的作者.*/
function Book (title, author) {this.title = titlethis.author = author
}Book.prototype = {/*** 获取书本的标题* @returns {string|*}*/getTitle: function () {return this.title},/*** 设置书本的页数* @param pageNum {number} 页数*/setPageNum: function (pageNum) {this.pageNum=pageNum}
}

四、编码风格

4.1 禁止使用var定义变量,使用let定义变量,const定义常量
  • 推荐
const bar = 1;
  • 不推荐
var a = 1;
bar = 1;
4.2 缩进换行请使用两个空格
4.3 结尾使用分号
const sortTable = () => {console.log(newIndex, oldIndex);console.log(proTable.value?.tableData);ElMessage.success("修改成功");
};
4.4 使用双引号
<div class="loading-wrap"></div><script setup lang="ts">
const ruleForm = reactive({name: "",sex: "",grade: "",desc: ""
});
</script>
4.5 将 > 多行元素放在最后一行的末尾,而不是放在下一行
  • 推荐:
<MyComponent title="vue" width="100" height="100" loading="lazy">...#slot
</MyComponent>
  • 不推荐:
<MyComponent title="vue" width="100" height="100" loading="lazy"
>...#slot
</MyComponent>
4.6 箭头函数参数只有一个时省略括号
const handleClick = param => {...
}const getArrList = param => param * 2
4.7 代码块之间不允许多个空行
  • 推荐
const myArray = ref(['item1', 'item2', 'item3']) const address = reactive<Address>({province: "",city: "",district: "",address: "",lnglat: [114.525918, 38.032612],
});const handleClick = () => {...
}
  • 不推荐
const myArray = ref(['item1', 'item2', 'item3'])  
const address = reactive<Address>({...
});const handleClick = () => {...
}
  • 若相邻两个同功能的表达式,第一个表达式一行内完成,与第二个表达式中间可不需要空格
// 推荐
const treeRef = ref<InstanceType<typeof ElTree>>();
const treeData = ref<{ [key: string]: any }[]>([]);
const treeAllData = ref<{ [key: string]: any }[]>([]);// 栅格间隔与样式
const gutter = 10;
const gutterStyle = computed(() => {return {width: `calc(100% + ${gutter}px)`,"margin-bottom": `${gutter}px`};
});// 亦可
const amapFlag = ref<boolean>(false);const handleAmapChange = () => {amapFlag.value = true;
};defineExpose({iMap
});
4.8 禁止定义未使用的变量和空函数
const unused = 1;
const empty = () => {};
4.9 禁止使用 @ts-ignore
  • 不推荐
// @ts-ignore: Object is possibly 'null'.  
const value = possiblyNullValue.someProperty;

五、GIT提交规范

  • commit 规范:(类型和描述之间加空格

    1. 提交类型 + 描述
    feat: 新功能
    
    1. 提交类型 + 图标 + 描述
    feat: 🚀 新功能
    
  • types: 提交类型

  { value: "feat", name: "特性:   🚀  新增功能", emoji: "🚀" },{ value: "fix", name: "修复:   🧩  修复缺陷", emoji: "🧩" },{ value: "docs", name: "文档:   📚  文档变更", emoji: "📚" },{ value: "style", name: "格式:   🎨  代码格式(不影响功能,例如空格、分号等格式修正)", emoji: "🎨" },{ value: "refactor", name: "重构:   ♻️  代码重构(不包括 bug 修复、功能新增)", emoji: "♻️" },{ value: "perf", name: "性能:    ⚡️  性能优化", emoji: "⚡️" },{ value: "test", name: "测试:   ✅  添加疏漏测试或已有测试改动", emoji: "✅" },{ value: "build", name: "构建:   📦️  构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)", emoji: "📦️" },{ value: "ci", name: "集成:   🎡  修改 CI 配置、脚本", emoji: "🎡" },{ value: "revert", name: "回退:   ⏪️  回滚 commit", emoji: "⏪️" },{ value: "chore", name: "其他:   🔨  对构建过程或辅助工具和库的更改(不影响源文件、测试用例)", emoji: "🔨" },{ value: "wip", name: "开发:   🕔  正在开发中", emoji: "🕔" },{ value: "workflow", name: "工作流:   📋  工作流程改进", emoji: "📋" },{ value: "types", name: "类型:   🔰  类型定义文件修改", emoji: "🔰" }

六、 写在最后

规范的目的在于确保一致性、减少错误、提高工作效率,让大家能编写出高质量的代码,更好促进沟通和协作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/827548.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux安装部署Tomcat

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ Linux安装部署Tomcat //将tomcat压缩包解压到对…

python识别电脑是windows还是linux

代码实现 import osif os.name nt:print(当前操作系统是 Windows) elif os.name posix:print(当前操作系统是 Linux 或 Unix 类型的系统) else:print(未知的操作系统)

kubernetes中的副本控制器rc(replicationcontrollers)和rs(replicasets)

一、rc控制器replicationcontrollers rc控制器就是控制相同pod副本数量 使用rc控制器资源创建pod&#xff0c;设定创建pod资源的数量 1.1 案例 1.1.1、创建资源清单 [rootmaster rc-demo]# cat rc.yaml apiVersion: v1 kind: ReplicationController metadata: name: rc01 …

个人搭建alist网盘的经验记录备忘

1、搭建宝塔LINUX面板&#xff0c;安装Docker 2、添加仓库 3、从镜像拉取xhofe/alist:latest 4、添加容器 5、新建一个网站&#xff0c;别忘记申请个SSL证书&#xff0c;重要的是反向代理 6、新建个mysql数据库 7、修改alist数据库的链接地址&#xff0c;方便自己备份&a…

如何有效地进行汽车制造业文件共享,一文了解

随着数字化转变&#xff0c;企业的业务文件大多通过电子形式在内外部流转。这增加了外发文件数据泄露或被篡改的风险&#xff0c;如何保护外发文件安全已成为企业不容忽视的课题。其中汽车制造业是一个高度依赖文件共享与协作的行业&#xff0c;涉及设计图纸、技术文件、供应链…

Docker命令总结

一.Docker常用命令总结 1.镜像命令管理 指令描述ls列出镜像build构建镜像来自Dockerfilehistory查看历史镜像inspect显示一个或多个镜像的详细信息pull从镜像仓库拉取镜像push推送一个镜像到仓库rm移除一个或多个镜像prune一处未使用的的镜像&#xff0c;没有被标记或被任何容…

【用户投稿】Apache SeaTunnel 2.3.3+Web 1.0.0版本安装部署

项目概要 Apache SeaTunnel 是一个分布式、高性能、易扩展的数据集成平台&#xff0c;用于实时和离线数据处理,支持多种数据源之间的数据迁移和转换。 其中&#xff0c;Apache-seatunnel-web-1.0.0-bin.tar.gz和apache-seatunnel-2.3.3-bin.tar.gz代表了 Apache SeaTunnel Web…

RTT学习 开发环境搭建

添加文件到工程 BSP下的applications文件夹用于存放用户自己的应用代码&#xff0c;目前只有一个main.c文件&#xff0c;如果用户的应用代码不是很多&#xff0c;建议相关源文件都放在这个文件夹下面&#xff0c;在applications文件夹下新增两个简单的文件hello.c和hello.h。 …

什么是正向代理和反向代理

正向代理和反向代理是两种不同的代理服务器配置方式&#xff0c;它们在代理的方向和作用上有所不同。 一、正向代理&#xff08;Forward Proxy&#xff09; 代表客户端发送请求到其他服务器的代理服务器。客户端将请求发送给正向代理服务器&#xff0c;然后由正向代理服务器代…

如何使用OSI七层模型的思路进行Linux网络问题排障?

在运维工作中&#xff0c;我们可能经常遇到诸如服务器无法远程连接、网站无法访问等各种网络问题。此时你是否想过&#xff0c;我们常背的OSI七层模型&#xff0c;能在处理这样的实际问题中发挥什么样的作用呢&#xff1f; 基于OSI架构的方法论&#xff0c;我们可以使用自下而…

ATFX汇市:欧元区和美国的制造业PMI将发布,市场预期乐观

ATFX汇市&#xff1a;今日16:00&#xff0c;市场研究机构Markit将发布欧元区4月制造业PMI初值&#xff0c;前值为46.1&#xff0c;预期值46.6&#xff0c;预期将增加0.5个百分点。历史数据看&#xff0c;最近三个月&#xff0c;欧元区的制造业PMI均处于较高水平&#xff0c;期间…

Springboot+Vue项目-基于Java+MySQL的房屋租赁系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

前端开发攻略---封装日历calendar组件(纯手搓),可以根据您的需求任意改变,可玩性强

1、演示 2、代码 <template><div class"box" v-if"startMonth.year"><div class"left"><div class"top"><span class"iconfont" click"changeMonth(-1)">左</span><span&…

Python学习从0开始——项目一day02数据库连接

Python学习从0开始——项目一day02数据库连接 一、在线云数据库二、测试数据库连接三、数据库驱动介绍四、SQL执行4.1插入测试数据4.2安装数据库连接模块4.3测试SQL语句执行4.4执行SQL的固定步骤及示例 一、在线云数据库 找了一个在线数据库&#xff0c;需要邮箱注册&#xff…

甄美天使1+3退休模式开发|最新升级模式

我是新零售商业架构师肖琳&#xff0c;易创客社交新零售创始‌‌‌‌‌人&#xff0c;擅长品牌从0-1、1-10起盘全过程。易创客新零售&#xff0c;提供商业模式解决方案系统&#xff0c;包括分销系统、微商系统、新零售系统&#xff1b;提供社交新零售陪跑代运营&#xff0c;提供…

Uds的0x10服务

0x10为诊断会话控制&#xff0c;该服务下有三种子功能&#xff0c;分别为默认会话&#xff0c;扩展会话&#xff0c;编程会话。 如果长时间在非默认会话下&#xff0c;没有用诊断仪跟ECU通讯&#xff0c;那么ECU会调回或者是返回到默认会话下。一般UDS协议上推荐是5000毫秒&…

云原生的基石:containerd引领未来容器发展趋势

文章目录 一、Containerd简介&#xff1a;容器技术的心脏二、Containerd核心原理解析三、Containerd与Docker的关系四、Containerd在云原生应用部署中的作用五、Containerd的扩展性和插件机制六、Containerd的安全特性七、Containerd的性能优化八、Containerd的社区和生态系统九…

C++面向对象程序设计 - 运算符重载

函数重载就是对一个已有的函数赋予新的含义&#xff0c;使之实现新的功能。因此一个函数名就可以用来代表不同功能的函数&#xff0c;也就是一名多用。运算符也可以重载&#xff0c;即运算符重载&#xff08;operator overloading&#xff09;。 一、运算符重载的方法 运算符重…

indexDB 大图缓存

背景 最近在项目中遇到了一个问题&#xff1a;由于大屏背景图加载速度过慢&#xff0c;导致页面黑屏时间过长&#xff0c;影响了用户的体验。从下图可以看出加载耗时将近一分钟 IndexDB 主要的想法就是利用indexDB去做缓存&#xff0c;优化加载速度&#xff1b;在这之前&am…