创建项目
通过HBuilderX创建
直接新建项目,选择vue的版本即可
通过命令行创建
拉取vue3+ts的版本:
npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project
然后进入项目目录,下载依赖pnpm i
(装了个pnpm)
记得加上appId
运行就用:npm run dev:mp-weixin
好好好,难道说我还要学个ts?
那这就学的太多了吧,先看看吧
用Vscode就直接导入就行了
vscode要安装些插件才能用着舒服,然后还要安装一个类型声明文件:
1
| pnpm i -D @types/wechat-miniprogram @uni-helper/uni-app-types
|
- 然后到manifest.json中配置小程序id
- 到tsconfig.json中加上以下配置,用于语法检查
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| "types": [ "@dcloudio/types", "@types/wechat-miniprogram", "@uni-helper/uni-app-types" ] }, "vueCompilerOptions": { "nativeTags": [ "block", "component", "template", "slot" ] },
|
熟悉案例
pages.json和tabBar案例
pages.json是配置页面路由,导航栏,tabBar等页面类信息
tabBar最少需要两项才有效
pages.json
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
| { "pages": [ { "path": "pages/index/index", "style": { "navigationBarTitleText": "首页" } }, { "path" : "pages/my/my", "style" : { "navigationBarTitleText" : "我的" } } ], "globalStyle": { "navigationBarTextStyle": "white", "navigationBarTitleText": "uni-app", "navigationBarBackgroundColor": "#2B9939", "backgroundColor": "#F8F8F8" }, "tabBar": { "list": [ { "pagePath": "pages/index/index", "text": "首页", "iconPath": "static/tabs/send-fill.png", "selectedIconPath": "static/tabs/send-fill.png" }, { "pagePath": "pages/my/my", "text": "我的", "iconPath": "static/tabs/消息.png", "selectedIconPath": "static/tabs/消息.png" } ] }, "uniIdRouter": {} }
|
tabBar隐藏掉头部:
1 2 3 4 5 6 7 8
| { "path": "pages/index/index", "style": { "navigationStyle": "custom", "navigationBarTextStyle": "white", "navigationBarTitleText": "首页" } },
|
但是由于现在手机都有刘海或者挖空,所以会出现这种情况:
就要进行适配:安全区域
通过小程序的api:const {safeAreaInsets} = uni.getSystemInfoSync()
来获取屏幕边界到安全区域距离
再通过动态设置样式,来实现自适应
1
| <view class="navbar" :style="{ paddingTop: safeAreaInsets?.top + 'px' }"></view>
|
轮播图案例
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
| <template> <swiper class="banner" indicator-dots circular :autoplay="true"> <swiper-item v-for="item in picture" :key="item.id"> <image @tap="onPreviewImage(item.url)" :src="item.url"></image> </swiper-item> </swiper> </template>
<script> export default { data() { return { title: 'Hello uni-app', picture: [ {id: '1',url: "http://47.109.139.173:9000/food.guide/%E5%B0%8F%E5%9B%BE.jpg"}, {id: '2',url: "http://47.109.139.173:9000/food.guide/b1ba1c68-7b43-4c9f-9082-09bfcc9d8c57.jpg"} ] } }, onLoad() {
}, methods: { onPreviewImage(url){ uni.previewImage({ urls: this.picture.map(v=>v.url), current: url }) } } } </script>
<style> .banner, .banner image{ width: 750rpx; height: 750rpx; } </style>
|
安装uni-ui组件库
安装命令
然后要配置自动导入,在pages.json中添加:
1 2 3 4 5 6 7
| "easycom": { "autoscan": true, "custom": { "^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue" } },
|
配置uni-ui类型检测
- 安装
1
| pnpm i -D @uni-helper/uni-ui-types
|
- 配置:在tsconfig.json的types中添加:
1
| "@uni-helper/uni-ui-types"
|
状态管理
配置了pinia,这个不太好说,就直接看代码比较好
毕设和这个课同步进行哈哈哈操
请求和上传文件拦截器
这个直接拿来用应该没问题吧
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
|
import { useMemberStore } from '@/stores'
const baseURL = 'https://pcapi-xiaotuxian-front-devtest.itheima.net'
const httpInterceptor = { invoke(options: UniApp.RequestOptions) { if (!options.url.startsWith('http')) { options.url = baseURL + options.url } options.timeout = 10000 options.header = { ...options.header, 'source-client': 'miniapp', } const memberStore = useMemberStore() const token = memberStore.profile?.token if (token) { options.header.Authorization = token } console.log(options) }, } uni.addInterceptor('request', httpInterceptor) uni.addInterceptor('uploadFile', httpInterceptor)
|
响应拦截器
请求成功,则提取出核心数据:res.data
请求失败:
- 网络错误
- 401,清理用户信息,跳转至登录界面
- 其他错误,根据后端错误信息轻提示
也是放到http.ts
文件内
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
| export const http = <T>(options: UniApp.RequestOptions) => { return new Promise<Data<T>>((resolve, reject) => { uni.request({ ...options, success(res) { if (res.statusCode >= 200 && res.statusCode < 300) { resolve(res.data as Data<T>) } else if (res.statusCode == 401) { const userStore = useUserStore() userStore.clearProfile() uni.navigateTo({ url: '/pages/login/login' }) uni.showToast({ title: '请登录后进行操作', icon: 'none', }) reject(res) } else { uni.showToast({ title: (res.data as Data<T>).msg || '请求错误', icon: 'none', mask: true, }) reject(res) } }, fail(err) { uni.showToast({ icon: 'none', title: '网络错误,请检查网络设置', }) reject(err) }, }) }) }
|
然后在需要发请求的地方引入:
1 2 3 4 5 6 7 8 9 10
| import { http } from '@/utils/http'
async function getData() { const res = await http({ method: 'GET', url: '/category/getAll' }) console.log(res) }
|
上面要改一下
组件封装
通用轮播图组件:轮播图组件需要在首页和分类页使用,封装成通用组件
- 准备组件
- 自动导入组件
- 添加组件类型声明
自动导入组件的配置,到pages.json中,按照uni-ui的自动导入配置,在下方写上一个这个:
1 2
| "^Xtx(.*)": "@/components/Xtx$1.vue"
|
然后直接引入,就可以了,不需要再写import
类型声明,在组件相同的目录添加components.d.ts
1 2 3 4 5 6
| import XtxSwiper from './XtxSwiper.vue' declare module 'vue' { export interface GlobalComponents { XtxSwiper: typeof XtxSwiper } }
|