[uni-app]小兔鲜-01项目起步

莱莱  论坛元老 | 2024-9-26 13:12:23 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1850|帖子 1850|积分 5550

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
项目先容

结果演示


技能架构


创建项目

HBuilderX创建

下载HBuilderX编辑器



HBuilderX/创建项目: 选择模板/选择Vue版本/创建



安装插件: 工具/插件安装/uni-app(Vue3)编译器
vue代码不能直接运行在小步伐环境, 编译插件资助我们进行代码转换





绑定微信开发者工具: 指定微信开发者工具安装目录后, HBX才能启动微信开发者工具



开启服务端口: 微信开发者工具/设置/安全设置/开启服务端口, 开启服务端口后HBX才能启动微信开发者工具





运行项目: 运行/小步伐模仿器/微信开发者工具
开发技巧: 模仿器窗口分离/置顶



目录分析



tabbar切换案例

  • 创建页面: page/右键新建页面



  • 设置tabbar和窗口表现
  1. // 页面配置文件
  2. {
  3.     // 页面路由和窗口表现, 创建页面自动添加
  4.         "pages": [
  5.                 // pages数组中第一项表示应用启动页
  6.                 {
  7.                         "path": "pages/index/index",
  8.                         "style": {
  9.                                 "navigationStyle": "custom", // 隐藏默认导航
  10.                                 "navigationBarTextStyle": "white",
  11.                                 "navigationBarTitleText": "首页"
  12.                         }
  13.                 },
  14.                 {
  15.                         "path": "pages/my/my",
  16.                         "style": {
  17.                                 "navigationStyle": "custom",
  18.                                 "navigationBarTextStyle": "white",
  19.                                 "navigationBarTitleText": "我的"
  20.                         }
  21.                 },
  22.         ],
  23.     // 全局页面设置
  24.         "globalStyle": {
  25.                 "navigationBarTextStyle": "black",
  26.                 "navigationBarTitleText": "",
  27.                 "navigationBarBackgroundColor": "#F8F8F8",
  28.                 "backgroundColor": "#F8F8F8"
  29.         },
  30.         // 设置 TabBar, 至少两个
  31.         "tabBar": {
  32.                 "color": "#333",
  33.                 "selectedColor": "#27ba9b",
  34.                 "backgroundColor": "#fff",
  35.                 "borderStyle": "white",
  36.                 "list": [
  37.                         {
  38.                                 "text": "首页",
  39.                                 "pagePath": "pages/index/index",
  40.                                 "iconPath": "static/tabs/home_default.png",
  41.                                 "selectedIconPath": "static/tabs/home_selected.png"
  42.                         },
  43.                         {
  44.                                 "text": "我的",
  45.                                 "pagePath": "pages/my/my",
  46.                                 "iconPath": "static/tabs/user_default.png",
  47.                                 "selectedIconPath": "static/tabs/user_selected.png"
  48.                         }
  49.                 ]
  50.         }
  51. }
复制代码

  • 配置应用信息: 配置微信appid后, 才能利用微信开发者工具进行真机预览





uniapp对比原生小步伐: 每个页面都是.vue文件, 数据绑定和变乱处理遵循 vue 规范就可以了

  • 属性绑定 src="{{ url }}" 升级为 :src="url"
  • 变乱绑定 bindtap="xxx" 升级为 @tap="xxx" , 支持()传参
  • 支持Vue常用指令 v-for/v-if/v-show/v-model
  • 多端开发利用 uni 替换 wx 调用接口能力

实现轮播图结果和大图预览结果
  1. <template>
  2.   <swiper class="banner" indicator-dots circular :autoplay="false">
  3.     <swiper_item v-for="item in pictures" :key="item.id">
  4.       <image @tap="onPreviewImage(item.url)" :src="item.url"></image>
  5.     </swiper-item>
  6.   </swiper>
  7. </template>
  8. <script>
  9. export default {
  10.    data() {
  11.       return {
  12.         // 轮播图数据
  13.         pictures:[
  14.           { id: '1',url: "https://pcapi-xiaotuxian-front-devtest.itheima.net/miniapp/uploads/goods_preview 1.jpg"},
  15.           { id: '2',url: "https://pcapi-xiaotuxian-front-devtest.itheima.net/miniapp/uploads/goods_preview 2.jpg"},
  16.           { id: '3',url: "https://pcapi-xiaotuxian-front-devtest.itheima.net/miniapp/uploads/goods_preview 3.jpg"},
  17.         ]
  18.       }
  19.    },
  20.   methods: {
  21.     onPreviewImage(url) {
  22.       uni.previewImage({
  23.         urls:this.pictures.map(v=>v.url),
  24.         current:url
  25.       })
  26.     }
  27.   }
  28. }
  29. </scripr>
复制代码



命令行创建

创建项目



  • 打开cmd, 实行命令: npx degit dcloudio/uni-preset-vue#vite-ts 自界说项目名称
  • npx是node自带的包管理工具
  • 官网链接: uni-app官网创建uni-app
  • 假如下载失败可以去官网下载, 大概切换网络尝试

运行项目

  • 项目中src目录下存放的就是uni-app工程代码



  • 添加appid: 在manifest.json文件配置appid
  • 安装依赖: pnpm install
  • 项目编译: pnpm dev:mp-weixin
  • 项目运行: 把编译后的文件 dist/dev/mp-weixin 导入微信开发者工具

vscode编译器配置: 现在vscode对TS类型支持友好



  • 插件安装uni-app插件
安装uni-create-view插件


功能: 快速创建页面


安装uni-helper插件


功能: uniapp代码提示, ctrl + i


安装 uniapp小步伐扩展 插件


功能: 鼠标悬停查看文档



  • 配置ts类型校验


  • 作用: 利用uniapp或微信组件时, 假如属性配置错误, 在编码阶段直接爆红, 开发效率更高
  • 依赖安装: pnpm i -D @types/wechat-miniprogram @uni-helper/uni-app-types
  1. {
  2.   "compilerOptions": {
  3.     ... ...
  4.     "types": [
  5.       "@dcloudio/types",  // 默认的TS类型文件
  6.       "miniprogram-api-typings", //微信小程序组件类型增强文件
  7.       "@uni-helper/uni-app-types", //uniapp组件类型增强文件
  8.     ]
  9.   },
  10.   "vueCompilerOptions": {
  11.     // 配置vue的编辑器模式为uniapp
  12.     // 已废弃,现调整为 nativeTags,请升级 Volar 插件至最新版本
  13.     // experimentalRuntimeMode: "runtime-uni-app",
  14.     "nativeTags": [
  15.       "block",
  16.       "component",
  17.       "template",
  18.       "slot"
  19.     ]
  20.   },
  21. }
复制代码

  • 解决json注释问题


  • HBX中, 答应JSON文件中出现注释
  • vscode中, JSON文件默认是严格JSON模式, 把JSON配置文件配置成jsonc模式, 就可以精确辨认注释了
  • uniapp中, 只有pages.json和manifest.json文件支持注释, 其他的json文件不要配置


基础架构

模版代码: git clone http://gititcast.cn/heimagianduan/erabbit-uni-app-vue3-ts.git heima-shop
安装依赖: pnpm install
配置appid:
  1. {
  2.     /* 小程序特有相关 */
  3.     "mp-weixin" : {
  4.         "appid" : "wxb161c259ad057faaaa",
  5.         "setting" : {
  6.             "urlCheck" : false
  7.         },
  8.         "usingComponents" : true
  9.     },
  10. }
复制代码
编译代码: pnpm dev:mp-weixin
运行代码: 微信小步伐打开dist/dev/mp-weixin

安装uni-ui组件库, 并配置uni-ui组件的自动按需导入
  1. {
  2.         // 组件自动引入规则
  3.         "easycom": {
  4.                 // 开启自动扫描
  5.                 "autoscan": true,
  6.                 // 以正则方式自定义组件匹配规则
  7.                 "custom": {
  8.                         // uni-ui 规则如下配置
  9.                         "^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue",
  10.                 }
  11.         },
  12.         "pages": [
  13.     ... ...
  14.   ],
  15. }
复制代码

  • 实行 pnpm i @dcloudio/uni-ui 命令安装组件库
  • 自动导入原理: 当我们利用uni-cart 组件时, 由于组件名以 uni- 开头, 就会被custom规则匹配到, 把组件的名称提取出来, 然后交给$1变量读取, 拼接后是完整组件地点, 就能被引入到项目中

uni ui是基于JS开发的, 本身没有提供TS类型支持, 第三方社区开源了uni-ui的类型加强文件, 供我们利用
  1. {
  2.   "extends": "@vue/tsconfig/tsconfig.json",
  3.   "compilerOptions": {
  4.     ... ...
  5.     "types": [
  6.        // 默认的类型增强文件也是必须的
  7.       "@dcloudio/types",
  8.        // 添加安装的uni-ui类型增强文件
  9.       "@uni-helper/uni-ui-types"
  10.     ]
  11.   },
  12.   "include": [
  13.     "src/**/*.ts",
  14.     "src/**/*.d.ts",
  15.     "src/**/*.tsx",
  16.     // 要确保包含使用uni组件的vue文件
  17.     "src/**/*.vue"
  18.   ]
  19. }
复制代码

  • 安装命令: pnpm i -D @uni-helper/uni-ui-types
  • 安装配置完成后需要重启项目, 才能生效

状态管理: 基础代码中已经集成了pinia堆栈, 我们只进行恒久化配置就可以了
  1. // 定义 Store
  2. export const useMemberStore = defineStore(
  3.   'member',
  4.   () => { },
  5.   // 持久化配置
  6.   {
  7.     // 网页端配置
  8.     // persist: true,
  9.     // 小程序端配置
  10.     persist: {
  11.       storage: {
  12.         setItem(key, value) {
  13.           uni.setStorageSync(key, value)
  14.         },
  15.         getItem(key) {
  16.           return uni.getStorageSync(key)
  17.         },
  18.       },
  19.     },
  20.   },
  21. )
复制代码

  • 由于网页端和小步伐利用差别的本地存储API, 所以恒久化配置的方式略有差别



请求拦截器: 拦截request/uploadFile请求, 配置基地点,超时时间, 请求头表示和token
  1. import { useMemberStore } from '@/stores'
  2. /**
  3. * 请求拦截
  4. */
  5. // 封装请求
  6. const baseURL = 'https://pcapi-xiaotuxian-front-devtest.itheima.net'
  7. // 请求拦截器
  8. const httpInterceptor = {
  9.     // 拦截前触发
  10.     invoke(options: UniApp.RequestOptions) {
  11.         // 1,非http开头需要拼接地址
  12.         if (!options.url.startsWith('http')) {
  13.             options.url = baseURL + options.url
  14.         }
  15.         // 2, 请求超时(10s)
  16.         options.timeout = 10000
  17.         // 3,添加小程序端请求头标识
  18.         options.header = {
  19.             ...options.header,
  20.             'source-client': 'miniapp',
  21.         }
  22.         // 4,添加token
  23.         const memberStore = useMemberStore()
  24.         const token = memberStore.profile?.token
  25.         if (token) {
  26.             options.header.Authorization = token
  27.         }
  28.     },
  29. }
  30. // 添加拦截器
  31. uni.addInterceptor('request', httpInterceptor)
  32. uni.addInterceptor('uploadFile', httpInterceptor)
复制代码

请求函数: 二次封装uni.request函数, 对返回结果进行promise化


  1. /**
  2. * 请求函数
  3. */
  4. // 接口(定义后台返回数据的类型)
  5. interface Data<T> {
  6.     code: string
  7.     msg: string
  8.     result: T
  9. }
  10. export const http = <T>(options: UniApp.RequestOptions) => {
  11.     // 1,返回Promise对象
  12.     return new Promise<Data<T>>((resolve, reject) => {
  13.         uni.request({
  14.             ...options,
  15.             // 响应成功(uni.requres中只要服务器有响应,就执行success回调)
  16.             success(res) {
  17.                 if (res.statusCode >= 200 && res.statusCode < 300) {
  18.                     // 2,成功
  19.                     resolve(res.data as Data<T>)
  20.                 } else if (res.statusCode === 401) {
  21.                     // 清理用户信息,调整到登录页
  22.                     const memberStore = useMemberStore()
  23.                     memberStore.clearProfile()
  24.                     uni.navigateTo({
  25.                         url: '/pages/login/login',
  26.                     })
  27.                     reject(res)
  28.                 } else {
  29.                     // 其他错误
  30.                     uni.showToast({
  31.                         title: (res.data as Data<T>).msg || '请求错误',
  32.                         icon: 'none',
  33.                     })
  34.                     reject(res)
  35.                 }
  36.             },
  37.             fail(err) {
  38.                 // 3,失败
  39.                 uni.showToast({
  40.                     title: '请求失败,换个网络试试',
  41.                     icon: 'none',
  42.                 })
  43.                 reject(err)
  44.             },
  45.         })
  46.     })
  47. }
复制代码

  • uni.request函数的sucess成功回调, 只要服务有响应就会实行, 我们需要对状态码进行更正确的判断
  • 假如状态码是401就跳转到登录页, 假如是其他错误就展示后台返回的错误信息
  • 假如网络出现问题, 服务器不会响应, 就会触发fail失败回调, 提示网络错误就行了
首页导航栏

安全地区: 通过 uni.getSystemInfoSync() 方法获取差别机型导航栏的安全距离



准备导航栏组件, 利用导航栏组件
  1. <script setup lang="ts">
  2. // 获取屏幕边界到安全区域距离
  3. const { safeAreaInsets } = uni.getSystemInfoSync()
  4. </script>
  5. <template>
  6.   <view class="navbar" :style="{ paddingTop: safeAreaInsets!.top + 10 + 'px' }">
  7.     <!-- logo文字 -->
  8.     <view class="logo">
  9.       <image class="logo-image" src="@/static/images/logo.png"></image>
  10.       <text class="logo-text">新鲜 · 亲民 · 快捷</text>
  11.     </view>
  12.     <!-- 搜索条 -->
  13.     <view class="search">
  14.       <text class="icon-search">搜索商品</text>
  15.       <text class="icon-scan"></text>
  16.     </view>
  17.   </view>
  18. </template>
  19. <style lang="scss">
  20. /* 自定义导航条 */
  21. .navbar {
  22.   background-image: url(@/static/images/navigator_bg.png);
  23.   background-size: cover;
  24.   position: relative;
  25.   display: flex;
  26.   flex-direction: column;
  27.   padding-top: 20px;
  28.   .logo {
  29.     display: flex;
  30.     align-items: center;
  31.     height: 64rpx;
  32.     padding-left: 30rpx;
  33.     .logo-image {
  34.       width: 166rpx;
  35.       height: 39rpx;
  36.     }
  37.     .logo-text {
  38.       flex: 1;
  39.       line-height: 28rpx;
  40.       color: #fff;
  41.       margin: 2rpx 0 0 20rpx;
  42.       padding-left: 20rpx;
  43.       border-left: 1rpx solid #fff;
  44.       font-size: 26rpx;
  45.     }
  46.   }
  47.   .search {
  48.     display: flex;
  49.     align-items: center;
  50.     justify-content: space-between;
  51.     padding: 0 10rpx 0 26rpx;
  52.     height: 64rpx;
  53.     margin: 16rpx 20rpx;
  54.     color: #fff;
  55.     font-size: 28rpx;
  56.     border-radius: 32rpx;
  57.     background-color: rgba(255, 255, 255, 0.5);
  58.   }
  59.   .icon-search {
  60.     &::before {
  61.       margin-right: 10rpx;
  62.     }
  63.   }
  64.   .icon-scan {
  65.     font-size: 30rpx;
  66.     padding: 15rpx;
  67.   }
  68. }
  69. </style>
复制代码
  1. <script setup lang="ts">
  2. import CustomNavbar from './components/CustomNavbar.vue'
  3.   
  4. </script>
  5. <template>
  6.   <!-- 自定义导航组件 -->
  7.   <CustomNavbar />
  8. </template>
复制代码

隐藏首页的默认导航栏
  1. {
  2.         "pages": [
  3.                 {
  4.                         "path": "pages/index/index",
  5.                         "style": {
  6.                                 "navigationStyle": "custom", // 隐藏默认导航
  7.                                 "navigationBarTextStyle": "white",
  8.                                 "navigationBarTitleText": "首页"
  9.                         }
  10.                 },
  11.         ],
  12. }
复制代码

实现结果



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

莱莱

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表