# uniapp-template **Repository Path**: superhan/uniapp-template ## Basic Information - **Project Name**: uniapp-template - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-01-14 - **Last Updated**: 2024-01-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 创建项目 uni-app提供了两种创建项目的方式: 1.通过HBuilderX可视化工具创建 2.通过vue-cli命令创建 ⚠️需要注意的是,一定要根据项目需求来选择项目的创建方式;如果只是单独的开发小程序或App,且开发环境单一,可以使用HBuilderX可视化工具创建。如果多端开发,以及同一套代码可能会打包生成多个小程序建议使用vue-cli进行创建,不然后期想搞自动化构建以及按指定条件进行编译比较痛苦。关于按条件编译,文章后面会有详细说明。 使用vue-cli安装和运行比较简单: 1.全局安装 vue-cli ```js npm install -g @vue/cli ``` 2.创建uni-app ```js vue create -p dcloudio/uni-preset-vue 项目名称 ``` 3.进入项目文件夹 ```js cd 项目名称 ``` 4.运行项目,如果是已微信小程序为主,可以在package.json中的命令改为: ```json "scripts": { "serve": "npm run dev:mp-weixin" } ``` 然后执行 ```js npm run serve ``` 使用cli创建项目默认不带css预编译,需要手动安装一下,这里已sass为例: ```js npm i sass --save-dev npm i sass-loader --save-dev ``` 整体项目架构 通过HBuilderX或者vue-cli创建的项目,目录结构有稍许不同,但基本没什么差异,这里就按vue-cli创建的项目为例,整体架构配置如下: ```tree ├──dist 编译后的文件路径 ├──package.json 配置项 ├──src 核心内容 ├──api 项目接口 ├──components 全局公共组件 ├──config 项目配置文件 ├──pages 主包 ├──static 全局静态资源 ├──store vuex ├──mixins 全局混入 ├──utils 公共方法 ├──App.vue 应用配置,配置App全局样式以及监听 ├──main.js Vue初始化入口文件 ├──manifest.json 配置应用名称、appid等打包信息 ├──pages.json 配置页面路由、导航条、选项卡等页面类信息 └──uni.scss 全局样式 ``` 封装方法 工欲善其事,必先利其器。在开发之前,我们可以把一些全局通用的方法进行封装,以及把uni-app提供的api进行二次封装,方便使用。全局的公共方法我们都会放到/src/utils文件夹下。 封装常用方法 下面这些方法都放在/src/utils/utils.js中,文章末尾会提供github链接方便查看。如果项目较大,建议把方法根据功能定义不同的js文件。 小程序Toast提示 ```js /** * 提示方法 * @param {String} title 提示文字 * @param {String} icon icon图片 * @param {Number} duration 提示时间 */ export function toast(title, icon = 'none', duration = 1500) { if(title) { uni.showToast({ title, icon, duration }) } } ``` 缓存操作(设置/获取/删除/清空) ```js /** * 缓存操作 * @param {String} val */ export function setStorageSync(key, data) { uni.setStorageSync(key, data) } export function getStorageSync(key) { return uni.getStorageSync(key) } export function removeStorageSync(key) { return uni.removeStorageSync(key) } export function clearStorageSync() { return uni.clearStorageSync() } ``` 页面跳转 ```js /** * 页面跳转 * @param {'navigateTo' | 'redirectTo' | 'reLaunch' | 'switchTab' | 'navigateBack' | number } url 转跳路径 * @param {String} params 跳转时携带的参数 * @param {String} type 转跳方式 **/ export function useRouter(url, params = {}, type = 'navigateTo') { try { if (Object.keys(params).length) url = `${url}?data=${encodeURIComponent(JSON.stringify(params))}` if (type === 'navigateBack') { uni[type]({ delta: url }) } else { uni[type]({ url }) } } catch (error) { console.error(error) } } 图片预览 js复制代码/** * 预览图片 * @param {Array} urls 图片链接 */ export function previewImage(urls, itemList = ['发送给朋友', '保存图片', '收藏']) { uni.previewImage({ urls, longPressActions: { itemList, fail: function (error) { console.error(error,'===previewImage') } } }) } 图片下载 js复制代码/** * 保存图片到本地 * @param {String} filePath 图片临时路径 **/ export function saveImage(filePath) { if (!filePath) return false uni.saveImageToPhotosAlbum({ filePath, success: (res) => { toast('图片保存成功', 'success') }, fail: (err) => { if (err.errMsg === 'saveImageToPhotosAlbum:fail:auth denied' || err.errMsg === 'saveImageToPhotosAlbum:fail auth deny') { uni.showModal({ title: '提示', content: '需要您授权保存相册', showCancel: false, success: (modalSuccess) => { uni.openSetting({ success(settingdata) { if (settingdata.authSetting['scope.writePhotosAlbum']) { uni.showModal({ title: '提示', content: '获取权限成功,再次点击图片即可保存', showCancel: false }) } else { uni.showModal({ title: '提示', content: '获取权限失败,将无法保存到相册哦~', showCancel: false }) } }, fail(failData) { console.log('failData', failData) } }) } }) } } }) } ``` 更多函数就不在文章中展示了,已经放到/src/utils/utils,js里面,具体可以到github查看。 请求封装 为了减少在页面中的请求代码,所以我们要对uni-app提供的请求方式进行二次封装,在/src/utils文件夹下建立request.js,具体代码如下: ```js import {toast, clearStorageSync, getStorageSync, useRouter} from './utils' import {BASE_URL} from '@/config/index' const baseRequest = async (url, method, data, loading = true) =>{ header.token = getStorageSync('token') || '' return new Promise((reslove, reject) => { loading && uni.showLoading({title: 'loading'}) uni.request({ url: BASE_URL + url, method: method || 'GET', header: header, timeout: 10000, data: data || {}, success: (successData) => { const res = successData.data uni.hideLoading() if(successData.statusCode == 200){ if(res.resultCode == 'PA-G998'){ clearStorageSync() useRouter('/pages/login/index', 'reLaunch') }else{ reslove(res.data) } }else{ toast('网络连接失败,请稍后重试') reject(res) } }, fail: (msg) => { uni.hideLoading() toast('网络连接失败,请稍后重试') reject(msg) } }) }) } const request = {}; ['options', 'get', 'post', 'put', 'head', 'delete', 'trace', 'connect'].forEach((method) => { request[method] = (api, data, loading) => baseRequest(api, method, data, loading) }) export default request ``` 请求封装好以后,我们在/src/api文件夹下按业务模块建立对应的api文件,拿获取用户信息接口举例子: 在/src/api文件夹下建立user.js,然后引入request.js ```js import request from '@/utils/request' //个人信息 export const info = data => request.post('/v1/api/info', data) 在页面中直接使用: ``` ```js import {info} from '@/api/user.js' export default { methods: { async getUserinfo() { let info = await info() console.log('用户信息==', info) } } } ``` 版本切换 很多场景下,需要根据不同的环境去切换不同的请求域名、APPID等字段,这时候就需要通过环境变量来进行区分。下面案例我们就分为三个环境:开发环境(dev)、测试环境(test)、生产环境(prod)。 建立env文件 在项目根目录建立下面三个文件并写入内容(常量名要以VUE开头命名): .env.dev(开发环境) ```ini VUE_APP_MODE=build VUE_APP_ID=wxbb53ae105735a06b VUE_APP_BASE=https://www.baidu.dev.com ``` .env.test(测试环境) ```ini VUE_APP_MODE=build VUE_APP_ID=wxbb53ae105735a06c VUE_APP_BASE=https://www.baidu.test.com ``` .env.prod(生产环境) ```ini VUE_APP_MODE=wxbb53ae105735a06d VUE_APP_ID=prod VUE_APP_BASE=https://www.baidu.prod.com ``` 修改package.json文件 ```json "scripts": { "dev:mp-weixin": "cross-env UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --mode dev", "build:mp-weixin": "cross-env UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --mode prod" }, ``` 然后执行 ```js npm run dev:mp-weixin ``` 在/src/pages/index/index.vue下,打印: ```js onLoad() { console.log(process.env.VUE_APP_MODE, '====VUE_APP_BASE') console.log(process.env.VUE_APP_BASE, '====VUE_APP_BASE') }, ``` 此时输出结果就是 ```js dev ====VUE_APP_BASE https://www.baidu.dev.com ====VUE_APP_BASE ``` 动态修改appid 如果同一套代码,需要打包生成多个小程序,就需要动态修改appid了;文章开头说过appid在/src/manifest.json文件中配置,但json文件又不能直接写变量,这时候就可以参考官方 提出的解决方案:建立vue.config.js文件,具体操作如下。 在根目录下建立vue.config.js文件写入以下内容: ```js // 读取 manifest.json ,修改后重新写入 const fs = require('fs') const manifestPath = './src/manifest.json' let Manifest = fs.readFileSync(manifestPath, { encoding: 'utf-8' }) function replaceManifest(path, value) { const arr = path.split('.') const len = arr.length const lastItem = arr[len - 1] let i = 0 let ManifestArr = Manifest.split(/\n/) for (let index = 0; index < ManifestArr.length; index++) { const item = ManifestArr[index] if (new RegExp(`"${arr[i]}"`).test(item)) ++i if (i === len) { const hasComma = /,/.test(item) ManifestArr[index] = item.replace( new RegExp(`"${lastItem}"[\\s\\S]*:[\\s\\S]*`), `"${lastItem}": ${value}${hasComma ? ',' : ''}` ) break } } Manifest = ManifestArr.join('\n') } // 读取环境变量内容 replaceManifest('mp-weixin.appid', `"${process.env.VUE_APP_ID}"`) fs.writeFileSync(manifestPath, Manifest, { flag: 'w' }) ```