阿里图标库引入
This commit is contained in:
442
docs/HBuilderX小程序编译错误解决方案.md
Normal file
442
docs/HBuilderX小程序编译错误解决方案.md
Normal file
@@ -0,0 +1,442 @@
|
||||
# HBuilderX小程序编译错误解决方案
|
||||
|
||||
## 错误信息
|
||||
|
||||
```
|
||||
[vite]: Rollup failed to resolve import "@dcloudio/uni-ui/lib/uni-button/uni-button.vue" from "components/MsgTips/MsgTips.vue".
|
||||
|
||||
[@vue/compiler-sfc] `defineExpose` is a compiler macro and no longer needs to be imported.
|
||||
[@vue/compiler-sfc] `defineProps` is a compiler macro and no longer needs to be imported.
|
||||
[@vue/compiler-sfc] `defineEmits` is a compiler macro and no longer needs to be imported.
|
||||
```
|
||||
|
||||
## 问题分析
|
||||
|
||||
### 问题1:uni-button 组件未安装
|
||||
|
||||
**原因:**
|
||||
- `uni-button` 不是 uni-app 的内置组件
|
||||
- 项目中使用了 `<uni-button>` 但没有安装 `@dcloudio/uni-ui` 完整包
|
||||
- 只安装了部分组件(uni-popup、uni-icons等)
|
||||
|
||||
**解决方案:**
|
||||
使用原生 `<button>` 替代 `<uni-button>`
|
||||
|
||||
### 问题2:Vue编译器宏错误导入
|
||||
|
||||
**原因:**
|
||||
- `defineProps`、`defineEmits`、`defineExpose` 是 Vue 3 的编译器宏
|
||||
- 它们由编译器自动注入,不需要从 vue 中导入
|
||||
- 在 `<script setup>` 中可以直接使用
|
||||
|
||||
**错误写法:**
|
||||
```javascript
|
||||
import { defineProps, defineEmits, defineExpose } from 'vue'
|
||||
```
|
||||
|
||||
**正确写法:**
|
||||
```javascript
|
||||
// 无需导入,直接使用
|
||||
const props = defineProps({...})
|
||||
const emit = defineEmits([...])
|
||||
defineExpose({...})
|
||||
```
|
||||
|
||||
## ✅ 已修复的文件
|
||||
|
||||
### 1. components/MsgTips/MsgTips.vue
|
||||
|
||||
**修改内容:**
|
||||
- ✅ 将 `<uni-button>` 替换为 `<button>`
|
||||
- ✅ 添加了 button 样式重置
|
||||
|
||||
**修改前:**
|
||||
```vue
|
||||
<uni-button class="popup-button" @click="close">确定</uni-button>
|
||||
```
|
||||
|
||||
**修改后:**
|
||||
```vue
|
||||
<button class="popup-button" @click="close">确定</button>
|
||||
```
|
||||
|
||||
**样式重置:**
|
||||
```scss
|
||||
button {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
background: none;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
button::after {
|
||||
border: none;
|
||||
}
|
||||
```
|
||||
|
||||
### 2. pages/chat/components/ai-paging.vue
|
||||
|
||||
**修改内容:**
|
||||
- ✅ 移除 `defineProps` 和 `defineEmits` 的导入
|
||||
|
||||
**修改前:**
|
||||
```javascript
|
||||
import {
|
||||
ref,
|
||||
defineProps,
|
||||
defineEmits,
|
||||
// ...
|
||||
} from 'vue';
|
||||
```
|
||||
|
||||
**修改后:**
|
||||
```javascript
|
||||
import {
|
||||
ref,
|
||||
// 移除了 defineProps 和 defineEmits
|
||||
// ...
|
||||
} from 'vue';
|
||||
```
|
||||
|
||||
### 3. components/tabbar/midell-box.vue
|
||||
|
||||
**修改内容:**
|
||||
- ✅ 移除 `defineProps` 的导入
|
||||
|
||||
### 4. pages/chat/components/popupbadFeeback.vue
|
||||
|
||||
**修改内容:**
|
||||
- ✅ 移除 `defineEmits` 的导入
|
||||
|
||||
### 5. components/selectJobs/selectJobs.vue
|
||||
|
||||
**修改内容:**
|
||||
- ✅ 移除 `defineExpose` 的导入
|
||||
|
||||
### 6. components/renderJobs/renderJobsCheckBox.vue
|
||||
|
||||
**修改内容:**
|
||||
- ✅ 移除 `defineExpose` 的导入
|
||||
|
||||
## 📋 Vue 3 Composition API 编译器宏
|
||||
|
||||
### 什么是编译器宏?
|
||||
|
||||
编译器宏是 Vue 3 在 `<script setup>` 中提供的特殊函数,由编译器在编译时处理,不是运行时的函数。
|
||||
|
||||
### 常用编译器宏
|
||||
|
||||
| 宏名称 | 作用 | 是否需要导入 |
|
||||
|--------|------|------------|
|
||||
| `defineProps` | 定义组件 props | ❌ 不需要 |
|
||||
| `defineEmits` | 定义组件事件 | ❌ 不需要 |
|
||||
| `defineExpose` | 暴露组件方法/属性 | ❌ 不需要 |
|
||||
| `withDefaults` | 为 props 设置默认值 | ❌ 不需要 |
|
||||
| `defineOptions` | 定义组件选项 | ❌ 不需要 |
|
||||
| `defineSlots` | 定义插槽类型 | ❌ 不需要 |
|
||||
| `defineModel` | 定义 v-model | ❌ 不需要 |
|
||||
|
||||
### 正确使用示例
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
// ✅ 正确:直接使用,无需导入
|
||||
const props = defineProps({
|
||||
name: String,
|
||||
age: Number
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update', 'change'])
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
close
|
||||
})
|
||||
|
||||
// ❌ 错误:不要从 vue 导入
|
||||
// import { defineProps } from 'vue'
|
||||
</script>
|
||||
```
|
||||
|
||||
## 🔧 替代方案
|
||||
|
||||
### 如果确实需要 uni-ui
|
||||
|
||||
如果项目中大量使用了 uni-ui 组件,可以安装完整的 uni-ui:
|
||||
|
||||
```bash
|
||||
npm install @dcloudio/uni-ui
|
||||
```
|
||||
|
||||
然后在 `pages.json` 中配置:
|
||||
|
||||
```json
|
||||
{
|
||||
"easycom": {
|
||||
"autoscan": true,
|
||||
"custom": {
|
||||
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 使用原生组件的优势
|
||||
|
||||
1. ✅ **更小的包体积** - 不需要引入额外的库
|
||||
2. ✅ **更好的兼容性** - 原生组件在所有平台都可用
|
||||
3. ✅ **更快的编译速度** - 减少依赖解析
|
||||
4. ✅ **更灵活的样式** - 可以完全自定义
|
||||
|
||||
## 🎯 button vs uni-button 对比
|
||||
|
||||
### 原生 button
|
||||
|
||||
```vue
|
||||
<button class="custom-btn" @click="handleClick">
|
||||
点击我
|
||||
</button>
|
||||
|
||||
<style>
|
||||
.custom-btn {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
background: #256BFA;
|
||||
color: white;
|
||||
border-radius: 12rpx;
|
||||
border: none;
|
||||
}
|
||||
|
||||
button::after {
|
||||
border: none; /* 移除默认边框 */
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
**优点:**
|
||||
- ✅ 无需安装依赖
|
||||
- ✅ 完全自定义样式
|
||||
- ✅ 支持所有平台
|
||||
- ✅ 性能更好
|
||||
|
||||
**缺点:**
|
||||
- ⚠️ 需要手动重置样式
|
||||
- ⚠️ 需要自己实现 loading、disabled 等状态
|
||||
|
||||
### uni-button
|
||||
|
||||
```vue
|
||||
<uni-button type="primary" @click="handleClick">
|
||||
点击我
|
||||
</uni-button>
|
||||
```
|
||||
|
||||
**优点:**
|
||||
- ✅ 内置多种样式
|
||||
- ✅ 自带 loading、disabled 状态
|
||||
- ✅ 统一的UI风格
|
||||
|
||||
**缺点:**
|
||||
- ❌ 需要安装 uni-ui
|
||||
- ❌ 增加包体积
|
||||
- ❌ 自定义样式受限
|
||||
|
||||
## 📝 button 样式重置模板
|
||||
|
||||
推荐在全局样式中添加 button 重置:
|
||||
|
||||
```css
|
||||
/* App.vue 或 common.css */
|
||||
|
||||
/* 重置 button 默认样式 */
|
||||
button {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
background: none;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
color: inherit;
|
||||
line-height: inherit;
|
||||
text-align: inherit;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 移除微信小程序 button 的默认边框 */
|
||||
button::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* 移除 button 按下时的背景色 */
|
||||
button:active {
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
/* 通用按钮样式 */
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 20rpx 40rpx;
|
||||
border-radius: 12rpx;
|
||||
text-align: center;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: linear-gradient(135deg, #13C57C 0%, #0FA368 100%);
|
||||
color: #FFFFFF;
|
||||
box-shadow: 0 8rpx 20rpx rgba(19, 197, 124, 0.3);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: #F7F8FA;
|
||||
color: #666666;
|
||||
}
|
||||
```
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
### 1. 编译器宏的特殊性
|
||||
|
||||
```javascript
|
||||
// ❌ 错误:不能解构或重命名
|
||||
import { defineProps as props } from 'vue'
|
||||
|
||||
// ❌ 错误:不能在条件语句中使用
|
||||
if (someCondition) {
|
||||
defineProps({...})
|
||||
}
|
||||
|
||||
// ✅ 正确:直接在顶层使用
|
||||
const props = defineProps({...})
|
||||
```
|
||||
|
||||
### 2. TypeScript 支持
|
||||
|
||||
如果使用 TypeScript,编译器宏会自动获得类型支持:
|
||||
|
||||
```typescript
|
||||
<script setup lang="ts">
|
||||
// 自动获得类型提示
|
||||
const props = defineProps<{
|
||||
name: string
|
||||
age?: number
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
update: [value: string]
|
||||
change: [id: number]
|
||||
}>()
|
||||
</script>
|
||||
```
|
||||
|
||||
### 3. 在非 setup 语法中
|
||||
|
||||
如果不使用 `<script setup>`,需要用传统方式:
|
||||
|
||||
```vue
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
name: String
|
||||
},
|
||||
emits: ['update'],
|
||||
setup(props, { emit, expose }) {
|
||||
// ...
|
||||
expose({ open, close })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## ✅ 验证修复
|
||||
|
||||
修复后,重新编译项目应该看到:
|
||||
|
||||
1. ✅ 没有 "Rollup failed to resolve import" 错误
|
||||
2. ✅ 没有 "defineXxx is a compiler macro" 警告
|
||||
3. ✅ 小程序正常编译和运行
|
||||
4. ✅ 按钮样式显示正常
|
||||
|
||||
## 🔍 排查步骤
|
||||
|
||||
如果修复后仍然有问题:
|
||||
|
||||
### 1. 清除缓存
|
||||
|
||||
```
|
||||
HBuilderX:
|
||||
运行 → 停止运行
|
||||
工具 → 清除缓存
|
||||
重新运行
|
||||
```
|
||||
|
||||
### 2. 检查所有文件
|
||||
|
||||
使用全局搜索检查是否还有遗漏:
|
||||
|
||||
```
|
||||
Ctrl + Shift + F
|
||||
搜索: import.*defineProps
|
||||
搜索: import.*defineEmits
|
||||
搜索: import.*defineExpose
|
||||
```
|
||||
|
||||
### 3. 检查 pages.json
|
||||
|
||||
确保 easycom 配置正确:
|
||||
|
||||
```json
|
||||
{
|
||||
"easycom": {
|
||||
"autoscan": true,
|
||||
"custom": {
|
||||
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 重新安装依赖
|
||||
|
||||
```bash
|
||||
# 删除 node_modules 和 lock 文件
|
||||
rm -rf node_modules
|
||||
rm package-lock.json
|
||||
|
||||
# 重新安装
|
||||
npm install
|
||||
```
|
||||
|
||||
## 📚 相关文档
|
||||
|
||||
- [Vue 3 script setup 文档](https://cn.vuejs.org/api/sfc-script-setup.html)
|
||||
- [uni-app button 组件](https://uniapp.dcloud.net.cn/component/button.html)
|
||||
- [uni-ui 文档](https://uniapp.dcloud.net.cn/component/uniui/uni-ui.html)
|
||||
- [Vite 构建优化](https://cn.vitejs.dev/guide/dep-pre-bundling.html)
|
||||
|
||||
## 🎉 总结
|
||||
|
||||
### 问题
|
||||
1. 使用了未安装的 `uni-button` 组件
|
||||
2. 错误地从 vue 导入了编译器宏
|
||||
|
||||
### 解决
|
||||
1. ✅ 将 `<uni-button>` 替换为 `<button>`
|
||||
2. ✅ 移除所有编译器宏的 import 语句
|
||||
3. ✅ 添加 button 样式重置
|
||||
|
||||
### 最佳实践
|
||||
- 优先使用原生组件
|
||||
- 不要导入 Vue 编译器宏
|
||||
- 保持依赖简洁
|
||||
- 定期清理未使用的代码
|
||||
|
||||
---
|
||||
|
||||
**所有错误已修复!** 🎉
|
||||
|
||||
现在可以正常编译和运行小程序了。
|
||||
|
Reference in New Issue
Block a user