前端注意事项
# 前端开发注意事项
# 规范建议
# 建议等级
参考vue2风格指南 (opens new window),提出四类建议等级:优先级A(必要的)、优先级B(强烈推荐)、优先级C(推荐)、优先级D(谨慎使用)。
# 优先级 A:必要的 (规避错误)
提示
这些规则会帮你规避错误,所以学习并接受它们带来的全部代价吧。这里面可能存在例外,但应该非常少,且只有你精通前端技术栈才可以这样做。
# 1、未定义的属性,导致控制台警告
在代码中使用未定义的变量或属性,本地开发时浏览器控制台会出现警告,不排除在某些情况下导致程序报错,甚至网页崩溃。在本地开发时,看到明确的编码错误导致警告时,应该极力避免。

# 2、vue3双向绑定失效
- 使用
SieForm时双向绑定失效(57446)。
<template>
<!-- 其他代码…… -->
<sie-form ref="formRef" v-model="formData" :form-item-list="formItemList" label-position="right"></sie-form>
<!-- 其他代码…… -->
</template>
<script setup>
// 其他代码……
// 错误示例:
const formData = ref();
// 正确示例:
const formData = ref({});
// 其他代码……
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 优先级 B:强烈推荐 (增强可读性)
提示
这些规则能够在绝大多数工程中改善可读性和开发体验。即使你违反了,代码还是能照常运行,但例外应该尽可能少且有合理的理由。
# 1、代码提交前,格式化代码
当前大部分项目下已配置.prettierrc文件,若没有可联系前端同事添加。若使用VSCode,导入配置即自动安装插件。
- 提升代码可读性:统一的缩进、换行和括号对齐,使代码层次清晰。
- 减少低级语法错误:格式化工具会修正以下问题(缺少分号、括号不匹配;缩进混乱导致的逻辑歧义;多余的空格或换行符)
- 增强团队协作效率:统一团队规范(如单/双引号、尾逗号),避免无意义的代码审查争论。减少因格式差异导致的 Git 冲突。
- 提高代码维护性:格式化后,Git 变更记录仅显示实际逻辑改动,而非格式调整。
- 提升代码审查质量:审查者无需关注格式问题,集中检查算法、安全性和设计模式。

# 2、打包时,代码中的对象存在重复的属性声明
重复字段可能会导致打包出现大量警告甚至报错,虽然有些警告和报错不会中止打包,但这样写显然是不规范的,这种简单的错误应该避免。

# 优先级 C:推荐 (将选择和认知成本最小化)
提示
当存在多个同样好的选项,选任意一个都可以确保一致性。在这些规则里,我们描述了每个选项并建议一个默认的选择。也就是说只要保持一致且理由充分,你可以随意在你的代码库中做出不同的选择。
# 优先级 D:谨慎使用 (有潜在危险的模式)
注意
有些特性的存在是为了照顾极端情况或帮助老代码的平稳迁移。当被过度使用时,这些特性会让你的代码难于维护甚至变成 bug 的来源。这些规则是为了给有潜在风险的特性敲个警钟,并说明它们什么时候不应该使用以及为什么。
# 常见问题
# 1、提示找不到依赖、运行报错、启动报错
- 现象:
Failed to resolve import "xxx(依赖)" from "xxx(文件路径)". Does the file exist?'@dme/xxx' is not in this registry.error An unexpected error occurred: "http://xxx/@dme/xxx: Not found".
- 原因:
- 某些组件已上传到私库,在默认的公共npm、yarn源是没有的,因此安装依赖报错。
- 其他人提交了代码依赖更新,但某些人本地没有安装依赖,导致找不到依赖。

- 解决方法:
前置条件:已全局安装yarn。
- 方法一:(推荐)使用项目中的依赖安装脚本
yarn run ins:all
- 方法二:临时用私库源安装依赖
yarn install --registry=http://nexus.dme.com/repository/npm-group/
- 方法三:修改为私库的npm源再安装
yarn config set registry http://nexus.dme.com/repository/npm-group/
yarn install
2
# 2、@dme/snack-ui组件库中的组件不知道怎么使用
查看组件库文档:Snack 工业业务组件库 (opens new window)
# 3、移动端H5发版问题
查看移动端底座二开流程文档: 三、业务包发布
# 4、移动端APK发布问题
查看移动端底座二开流程文档: 四、APK 打包发布
# 5、本地开发,前端调用后端接口报错 401
现象:
原因:
华为MBM的token过期。
- 解决方法:
- 方法一:删除浏览器缓存的token
按F12或ctrl+shift+i打开浏览器的开发者工具,切换至Application(中文显示为应用程序)页签,找到Session storage(中文显示为会话存储),将xxxmbmtoken,重新刷新页面会自动获取token。此操作仅限于dev或loc环境启动的页面(即使用npm run dev或npm run loc命令启动)。

# 6、PC端前端页面显示的值不更新
检查是否已声明vue3的响应式变量,如ref。
<template>
<div>
<div>{{ count }}</div>
<button @click="handleClick">+</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
// 建议
const count = ref(0);
// 不建议
let count = ref(0);
function handleClick() {
// 正确的写法
count.value++;
// 错误的写法
count++;
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 7、移动端使用 app-scan-bar 扫码回车后重新聚焦不生效
移动端使用app-scan-bar组件时,因为聚焦focus数据是单向数据流传递,因此回车后要手动处理失焦事件时将focus设置为false,再设置focus为true。
<template>
<app-scan-bar :focus="inputFocus" @blur="inputFocus = false" @search="handleSearch" />
</template>
<script>
export default {
data() {
return {
inputFocus: true
}
},
methods: {
/**
* 回车搜索事件
* @param {string} value 输入框的值
*/
handleSearch(value) {
// 业务逻辑...
// 异步处理...
this.inputFocus = true;
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 8、移动端使用 app-scan-bar 扫码回车获取v-model绑定值与条码值不一致
移动端使用app-scan-bar组件时,因为vue2及uni-app框架性能问题,可能会出现:
- 扫描条码、二维码等,从
v-model获取的扫码值,扫码值过长被截断了。 - 扫描条码、二维码等,从
v-model获取的扫码值为空。 解决方法:从app-scan-bar组件的@search、@scan事件中获取扫码值。
<template>
<div>
<app-scan-bar v-model="scanCode" @search="handleSearch" @scan="handleScan" />
</div>
</template>
<script>
export default {
data() {
return {
scanCode: ''
}
}
methods: {
handleSearch(value) {
console.log('回车搜索,输入框的值:', value);
},
handleScan(value) {
console.log('扫码,输入框的值:', value);
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 9、移动端使用 app-scan-bar 扫码回车结果过长被截断了
参考:移动端使用 app-scan-bar 扫码回车获取v-model绑定值与条码值不一致
# 10、移动端在h5与apk(PDA)获取路由参数不一致
原因:由于uni-app框架的限制,在apk中获取路由参数需要用onLoad方法获取,参考uni-app官网:页面 onLoad 生命周期 (opens new window)。
解决方案:由于进行了脚手架级别封装,因此在获取路由参数时,对
onLoad生命周期、路由参数获取进行了封装,参考行业包移动端二开流程文档:6.3 注意事项。
<script>
export default {
mounted() {
// 错误示例:仅兼容h5端,不兼容app端
console.log(this.$route.query.id);
// 正确示例:兼容h5端与app端
console.log(this.onLoadOption.id)
}
}
</script>
2
3
4
5
6
7
8
9
10
11
# 11、项目运行报错出现类似报错:No matching export in "node_modules/@opentiny/vue-icon/index.js" for import "IconStretchCrosswise"
升级@opentiny/vue版本到3.18.0以上即可解决。
# 12、组件库组件有bug、有使用问题
- 查看当前项目组件库版本:


- 升级组件库版本:
yarn run @dme/snack-ui@xxx
# xxx为组件库具体版本号,如
yarn run @dme/snack-ui@0.0.75
2
3
- 组件库更新日志没有标明解决的,联系组件库开发者。
# 13、在电脑使用模拟器安装移动端APP的问题、安装说明
因为模拟器注册了.apk文件打开方式,所以双击.apk文件会打开模拟器并安装APP。当已经安装了同包名的APP时,不会卸载旧APP,而是覆盖安装。
使用双击.apk文件安装APP的方式,在需要卸载重新安装的时候并不适用,因为没有经过卸载不会删除缓存数据。
要全新安装APP时,应该先打开模拟器,在模拟器中删除APP,然后再安装.apk文件。
虽然APP的更新逻辑会自动检测是否有新版本,并根据条件安装新版本,但某些特殊情况下的更新内容,需要全新安装APP。
# 14、Vue3 如何使用双向绑定
- 基本用法:通过v-model指令结合响应式变量实现,变量需用ref或reactive声明
<template>
<input v-model="username" />
</template>
<script setup>
import { ref } from 'vue'
const username = ref('') // 初始值为空字符串
</script>
2
3
4
5
6
7
8
- 组件间双向绑定:子组件通过modelValue接收值,通过update:modelValue事件更新
- 子组件通过modelValue接收父组件值
- 监听props.modelValue变化,同步到子组件内部状态
- 监听子组件内部状态变化,通过update:modelValue事件同步给父组件
<!-- 子组件 -->
<template>
<input v-model="innerValue" />
</template>
<script setup>
import { watch, ref } from 'vue'
// 1. 定义接收父组件v-model的prop
const props = defineProps({
modelValue: {
type: [String, Number],
default: ''
}
})
// 2. 定义内部状态并初始化
const innerValue = ref(props.modelValue)
const emit = defineEmits(['update:modelValue'])
// 3. 监听父组件值变化,同步到子组件
watch(
() => props.modelValue,
(newVal) => {
innerValue.value = newVal
}
)
// 4. 监听子组件内部变化,同步到父组件
watch(
innerValue,
(newVal) => {
emit('update:modelValue', newVal)
}
)
</script>
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>
<CustomInput v-model="userInfo.name" />
</template>
2
3
4
- 与 Vue2 区别:移除.sync修饰符,统一使用v-model:参数名实现多字段绑定
<!-- 多字段绑定示例 -->
<FormComponent
v-model:username="name"
v-model:age="userAge"
></FormComponent>
2
3
4
5
# 15、出现警告:Invalid prop: type check failed for prop "xxx". Expected Boolean, got String with value "xx"
- 问题分析:父组件通过变量绑定子组件的属性,子组件的属性类型为Boolean,但父组件传递的属性值不是Boolean,而是String。
- 解决方法:在子组件的props中定义属性类型为String,然后通过
v-bind:xx="xxx"或:xx="xxx"将父组件的属性值传递给子组件。有个别情况是变量传入的值是字符串"true",需要改成。
<template>
<!-- ...其他代码 -->
<!-- 正确代码1 -->
<ChildComponent :isShow="isShow" />
<!-- 错误代码1 -->
<ChildComponent isShow="isShow" />
<!-- 正确代码2 -->
<ChildComponent :isShow="true" />
<!-- 错误代码2 -->
<ChildComponent isShow="true" />
<!-- ...其他代码 -->
</template>
<script setup>
// ...其他代码
// 正常代码
const isShow = ref(true);
// 错误代码
const isShow = ref('true');
// ...其他代码
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 16、出现警告:Property "xxx" was accessed during render but is not defined on instance.
- 问题分析:绑定到组件上的属性未定义。
- 解决方法:在
<script>中定义属性。
<template>
<ChildComponent :xxx="xxx" />
</template>
<script setup>
// 定义属性
const xxx = ref('xxx');
</script>
2
3
4
5
6
7
8

# 17、vue3中,兄弟组件通信
在 Vue 3 中,兄弟组件通信可以通过父组件作为中介来实现。具体步骤如下:
- 子组件 A 使用 $emit 向父组件发送事件。
- 父组件 监听该事件,并处理数据。
- 父组件 使用 $emit 将数据传递给 子组件 B。
<!-- 父组件 ParentComponent.vue -->
<template>
<div class="parent-component">
<ChildComponentA @send-data="handleData" />
<ChildComponentB ref="childB" :data="sharedData" />
</div>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponentA from './ChildComponentA.vue';
import ChildComponentB from './ChildComponentB.vue';
const sharedData = ref(null);
const childB = ref(null);
const handleData = (data) => {
sharedData.value = data;
childB.value.receiveData(data);
};
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- 子组件 A ChildComponentA.vue -->
<template>
<div class="child-component-a">
<button @click="sendData">Send Data to Brother</button>
</div>
</template>
<script setup>
sendData() {
this.$emit('send-data', 'Hello from Component A');
}
</script>
2
3
4
5
6
7
8
9
10
11
12
<!-- 子组件 B ChildComponentB.vue -->
<template>
<div class="child-component-b">
<p>Received Data: {{ data }}</p>
</div>
</template>
<script setup>
const props = defineProps({
data: {
type: String,
default: ""
}
});
const receiveData = (data) => {
console.log('Received Data:', data);
console.log('Data from Child A:', props.data);
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 18、命令行运行脚本报错:xxx : 无法加载文件 C:\Users\xxx\xxx.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 https:/go.microsoft.com/fwlink/?LinkID=135170 中的 about_Execution_Policies。
- 问题分析:Windows的安全策略限制了PowerShell脚本的运行。
- 解决方法:在PowerShell中执行以下命令,将执行策略设置为RemoteSigned。
具体说明可阅读微软文档的about_Execution_Policies (opens new window)
# 以管理员权限执行以下命令
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
2