1.前言 最近的一个项目就是使用 uni-app 进行开发,一开始的时候,就是找不清楚到底如何才能引入uni-app 的组件,
2.底部导航按钮 底部的tabbar导航栏,我刚开始的使用就是使用这个 custom-tab-bar 组件,但是我直接写的话,好像还是有问题的:TypeError: instance.update is not a function。
1 2 3 4 5 <template > <view > <custom-tab-bar direction ="horizontal" :show-icon ="false" :selected ="selected" @onTabItemTap ="onTabItemTap" /> </view > </template >
问题总是很多的,不知道该如何才能配置成功。
后来我换了一个方式,就是使用tabbar的方式进行配置。
(1)创建三个文件。 (2)编写page.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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 { "pages" : [ { "path" : "pages/index/index" , "style" : { "navigationBarTitleText" : "uni-app" } } , { "path" : "pages/renfang/index" , "style" : { "navigationBarTitleText" : "" , "enablePullDownRefresh" : false } } , { "path" : "pages/map/index" , "style" : { "navigationBarTitleText" : "" , "enablePullDownRefresh" : false } } ] , "globalStyle" : { "navigationBarTextStyle" : "black" , "navigationBarTitleText" : "uni-app" , "navigationBarBackgroundColor" : "#F8F8F8" , "backgroundColor" : "#F8F8F8" } , "uniIdRouter" : { } , "tabBar" : { "color" : "#7A7E83" , "selectedColor" : "#3cc51f" , "borderStyle" : "black" , "backgroundColor" : "#ffffff" , "list" : [ { "pagePath" : "pages/index/index" , "iconPath" : "static/image/icon_component.png" , "selectedIconPath" : "static/image/icon_component_HL.png" , "text" : "全局" } , { "pagePath" : "pages/renfang/index" , "iconPath" : "static/image/icon_API.png" , "selectedIconPath" : "static/image/icon_API_HL.png" , "text" : "设施" } , { "pagePath" : "pages/map/index" , "iconPath" : "static/image/icon_API.png" , "selectedIconPath" : "static/image/icon_API_HL.png" , "text" : "" } ] } }
(3)自动生成了导航栏。
参考文章:
1.
custom-tab-bar 我仔细的阅读了这个文章:在小程序和App端,为提升性能,在 pages.json 里配置固定的原生tabBar。但在H5端,这一设计并不会提升性能。同时,H5端尤其是PC宽屏,对tabBar的位置和样式有更灵活的需求,tabBar作为一级导航,更多的时候是在PC网页顶部而不是底部。自定义tabBar组件应需而生,它仍然读取 pages.json 里配置的tabBar信息,但这个组件可以自定义摆放的位置,可以灵活的配置各种css。该组件支持 pages.json 中 tabBar 相关配置(兼容性和 H5 保持一致), 其中不支持 borderStyle 配置。
该组件支持所有 tabBar 相关 API,例如设置 tab 徽标、显示红点、以及 switchTab 等。
2.
tabbar添加list报错 已找到原因,需要添加2个以上才不会报错….
3.
tabBar 这里是一个讨论,算是bug报告吧。tabBar 中的 list 是一个数组,只能配置最少2个、最多5个 tab,tab 按数组的顺序排序。
4.
2020-11-16 uni-app tabbar底部导航配置 这篇文章没有自定义,只是使用了uniapp自带的,另外加了字体。
3.引入字体 引入字体的方式和在web端引入的方式一样。
(1) 在组件仓库中进行安装
(2) 重新编译运行
(3) 引入
1 <uni-icons type="contact" size="30" ></uni-icons>
4.自定义导航按钮 我想实现的功能就是类似于京东、天猫一样的在顶部导航栏下面的一排的导航按钮的形式。
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 <template> <view class ="main" > <view class ="navigator" > <view class ="navigator-item" v-for ="(item,index) in dataState.tabBar.list" :key ="item.pagePath" @click ="switchTab(index,item)" > <img :src ="item.iconPath" class ="icon" v-if ="dataState.selectedIndex !== index" > <img :src ="item.selectedIconPath" class ="icon" v-else > <text :class ="['item-text',{'text-active':dataState.selectedIndex === index}]" > {{item.text}}</text > </view > </view > <view class ="content" > </view > </view > </template > <script setup > import { reactive } from "vue" ; const dataState=reactive ({ tabBar :{ color :"#000" , selectedColor :"#ff161a" , list :[ { "pagePath" :"static/image/icon-gcgl" , "iconPath" :"static/image/icon-gcgl.png" , "selectedIconPath" :"static/image/icon-gcgl.png" , "text" :"空间管理" }, { "pagePath" :"static/image/icon-gcmj" , "iconPath" :"static/image/icon-gcmj.png" , "selectedIconPath" :"static/image/icon-gcmj.png" , "text" :"工程面积\n年增长" }, { "pagePath" :"static/image/icon-" , "iconPath" :"static/image/icon-gcgn.png" , "selectedIconPath" :"static/image/icon-gcgn.png" , "text" :"工程功能\n各类数量" }, { "pagePath" :"static/image/icon-" , "iconPath" :"static/image/icon-ssdt.png" , "selectedIconPath" :"static/image/icon-ssdt.png" , "text" :"实时动态" } ] }, selectedIndex :0 , }) const switchTab =(index,item )=>{ console .log (index,item); dataState.selectedIndex =index; } </script > <style lang ="less" scoped > .main { width : 100% ; height : 100% ; position : absolute; display : flex; flex-direction : column; .navigator { display : flex; border-bottom : 5px solid #eee ; .navigator-item { flex : 1 ; display : flex; flex-direction : column; text-align : center; padding :15px 5px ; img { width : 80 rpx; left : 50% ; position : relative; transform : translateX (-50% ); margin-bottom : 10px ; } .text-active { color : rgba (62 , 132 , 243 , 1 ); } } } .content { background :url ('../../static/image/page-bg.png' ); flex : 1 ; overflow-x : hidden; } } </style >
5.配置环境变量 主要有三种方式:
vue.config.js 或者是 vite.config.js 配置文件,在 Cli工程 和 HBuilderX创建的项目 中都可以使用。
.env 文件,只有在Cli工程中可以使用。
package.json 文件,在 Cli工程 和 HBuilderX创建的项目 中都可以使用。
这里我才用的是自定义的方式 (1) 项目根目录下新建 .env.development.js 文件
1 2 3 4 export default { env : 'development' , request_baseurl : 'http://development' , };
(2) 项目根目录下新建 .env.production.js 文件
1 2 3 4 export default { env : 'production' , request_baseurl : 'http://production' , };
(3) 项目根目录下新建 .env 文件
1 2 3 4 5 6 7 import development from './.env.development' ;import production from './.env.production' ;export default { development, production }
(4) 修改vite.config.js文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import { defineConfig } from 'vite' ;import uni from '@dcloudio/vite-plugin-uni' ;import env from './.env' ;function getConfig ( ){ let envConfig=env[process.env .NODE_ENV ]; let temp={}; for (let name in envConfig){ temp['process.env.' +name]=JSON .stringify (envConfig[name]); } return temp; } export default defineConfig ({ plugins : [uni ()], define : getConfig (), });
(5) 直接在项目中使用
1 console .log (process.env .request_baseurl );
问题 (1)vite.config.js不生效 如果编写了 vite.config.js 不生效,需要点击控制台,然后选择重新编译项目,才能有用。
(2)define定义的是一个变量 在正常的思维中,下面的 process.env.VUE_APP_CONFIG 配置为d,这个d会被认为是一个字符串,但是实际上不是的,它会被识别为一个变量。
1 2 3 define : { 'process.env.VUE_APP_CONFIG' : "d" , },
【解决方案】 解决方法就是 JSON.stringify 进行序列化。这个在uni-app的说明中,也是这么用的。
1 2 3 define : { 'process.env.VUE_APP_CONFIG' : JSON .stringify ("d" ), },
6.uni.request封装 (1)封装request
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 export default function http (param ) { let url = param.url , method = param.method , header = param.header ||{}, data = param.data || {}, token = param.token || "" , hideLoading = param.hideLoading || false ; let baseUrl=process.env .VITE_GLOB_DOMAIN_URL ; var requestUrl = baseUrl + url; if (method) { method = method.toUpperCase (); } if (!header['content-type' ]){ header['content-type' ] = "application/json" ; } if (!hideLoading) { uni.showLoading ({ title : '加载中...' }); } return new Promise ((resolve, reject ) => { uni.request ({ url : requestUrl, data : data, method : method, header : header, success : (res ) => { if (res.statusCode && res.statusCode != 200 ) { uni.showToast ({ title : "api错误" + res.errMsg , icon : 'none' }); return ; } resolve (res.data ) }, fail : (e ) => { uni.showToast ({ title : "" + e.data .msg , icon : 'none' }); resolve (e.data ); }, complete ( ) { if (!hideLoading) { uni.hideLoading (); } resolve (); return ; } }) }) }
(2)创建api接口 创建一个独立的 api 文件,定义需要请求的url。
1 2 3 4 5 6 import http from '../utils/request.js' export const getCodeInfo = (params ) => { return http ({ url :"/sys/randomImage" +`/${params} ` , }) }
(3)引用api接口
1 2 3 4 5 6 7 import { getCodeInfo } from '../../api/index.js' ;randCodeData.checkKey = 1629428467008 ; getCodeInfo (randCodeData.checkKey ).then ((res ) => { randCodeData.randCodeImage = res; randCodeData.requestCodeSuccess = true ; });
7.路径别名 在使用 HBuilderX 创建的项目中,不需要单独的配置 vite.config.js 文件,默认的 @ 就是项目的根目录。
如果使用的是 Cli 进行创建的,@ 符合表示的就是 src 目录。
8.Pinas (1) main.js中增加如下代码
1 2 3 4 5 6 7 8 9 10 11 import { createSSRApp } from 'vue' ;import * as Pinia from 'pinia' ;export function createApp ( ) { const app = createSSRApp (App ); app.use (Pinia .createPinia ()); return { app, Pinia , }; }
(2) 创建store
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import { defineStore } from 'pinia' ;export const useCounterStore = defineStore ('counter' , { state : () => { return { count : 0 }; }, actions : { increment ( ) { this .count ++; }, }, });
(3) 在组件中使用
1 2 3 import { useCounterStore } from '@/stores/counter' const counter = useCounterStore ()counter.count ++
参考文章:
1.
状态管理 Pinia uni-app 内置了 Pinia, 使用 HBuilder X 不需要手动安装,直接使用即可。
9.二级目录 发行的h5网页端,要想配置成二级目录,需要单独的进行设置。
(1)打开项目根目录下的 “manifest.json 文件”,找到 “web 配置”,然后 找到运行基础路径,编写需要发布的路径。
(2)配置nginx,进行二级目录的编写。
这样配置带来的副作用,就是page.json中写的那个 tabbar 的路径就有问题了。
1 2 3 4 5 6 7 8 9 10 11 12 "tabBar" : { "color" : "rgba(166, 166, 166, 1)" , "selectedColor" : "rgba(62, 132, 243, 1)" , "borderStyle" : "black" , "backgroundColor" : "#ffffff" , "list" : [ { "pagePath" : "pages/index/index" , "iconPath" : "static/image/icon-index.png" , "selectedIconPath" : "static/image/icon-index-select.png" , "text" : "index" } ] }
解决方法就是,对基础路径增加一个 斜杠,由 “h5”,变为 “/h5/” 。
10.图表 10.1.安装图表 安装图表的方法还是挺麻烦的,要用微信扫码看广告,然后才能下载。打开插件市场,秋云 ucharts echarts 高性能跨全端图表组件 选择 “下载插件并倒入HBuilderX”,然后观看广告之后,打开并导入到 HBuilderX 之后,就会出现一个 UniApp .
10.2.直接使用 qiuyun 这个插件进行开发 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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 <template> <view class="charts-box"> <qiun-data-charts type="column" :chartData="stateData.chartData" :opts="opts" /> </view> </template> <script setup> import { onMounted, reactive } from "vue"; import { getRfdwd } from "@/api/index.js"; /** * 配置内容 */ const opts=reactive({ padding: [20,40,0,10], background:"rgba(0,0,0,0)", tile:{ name:"面积年增长" }, }) /** * 统计数据 */ const stateData = reactive({ yearData: ['2016', '2017', '2018', '2019', '2020'], // 年份数据 mjData: [1000, 3000, 800, 2600, 4700], // 面积数据 zzlData: [100, 300, 80, 260, 500], // 增长率数据 mjYAxis: { min: 0, max: 4700, }, // 面积的轴配置 zzlYAxis: { min: 0, max: 500, }, // 增长率的轴配置 chartData:{} // 图表数据 }); /** * 获取数据 */ function initData(){ getRfdwd().then(res => { let features=res.features; // 执行统计 statisticsFunc(features); }) } /** * 获取统计数据 */ function statisticsFunc(features) { let count = features.length; let mjData = {}; // 面积数据 let jc = 1; // 基准值 for (let i = count - 1; i >= 0; i--) { let feature = features[i]; let properties = feature.properties; let jgrq = properties.jgrq; let year = jgrq ? jgrq.substring(0, 4) : ''; year = parseInt(year); let mj = parseFloat(properties.rfmj); if (year && year >= 2018 && year <= 2022) { mjData[year] = mj; } if (year == 2017) { jc = mj; } } stateData.yearData = Object.keys(mjData); let mjArray = Object.values(mjData); stateData.mjData = mjArray; // 配置y轴 let sortMj = mjArray.concat([]).sort(function (a, b) { return a - b; }); stateData.mjYAxis = { min: sortMj[0], max: sortMj[sortMj.length - 1], }; // 统计增长率 let mjDataCount = stateData.mjData.length; let zzl = []; for (let i = 0; i < mjDataCount; i++) { let mj = stateData.mjData[i]; let temp = Math.floor(((mj - jc) / jc) * 10000) / 100; zzl.push(temp); } stateData.zzlData = zzl; // 配置y轴 let sortZzl = zzl.concat([]).sort(function (a, b) { return a - b; }); stateData.zzlYAxis = { min: sortZzl[0], max: sortZzl[sortZzl.length - 1], }; // 更新图表 stateData.chartData={ categories: stateData.yearData, series: [ { name: "面积", data: stateData.mjData } ] } } /** * 挂载 */ onMounted(()=>{ initData(); }) </script> <style lang="less" scoped> .charts-box{ margin-top: 20rpx; height: 900rpx; } </style>
问题 (1) ctx.draw is not a function 更新数据的时候,结果就是报这个错误。
【解决方案】 原先的引入为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <qiun-data-charts type="column" :chartData="chartData" :opts="opts" /> const chartData = reactive ({ categories : stateData.yearData , series : [ { name : "面积" , data : stateData.mjData } ] }) chartData.categories =stateData.yearData ;
修改为二级引用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <qiun-data-charts type="column" :chartData="chartData" :opts="opts" /> const stateData = reactive ({ chartData :{} }) stateData.chartData ={ categories : stateData.yearData , series : [ { name : "面积" , data : stateData.mjData } ] }
10.3.原生使用 脱离了HbuildX,如何使用 uCharts 呢? (1)变细 easycom配置,在page.json中编写 easycom 配置
1 2 3 4 5 6 "easycom" : { "autoscan" : true , "custom" : { "qiun-data-charts" : "@qiun/uni-ucharts/components/qiun-data-charts/qiun-data-charts.vue" } }
(2) 从代码仓库 拷贝文件 到 components 文件夹。将相关的代码,从代码仓库 下载下来,然后复制到 src/components 文件夹下
(3)拷贝static文件夹,将仓库中的static文件夹全部的内容拷贝到自己项目的static文件夹下
(4)文件目录,最后形成的文件目录如下:
11.Cesium 在uniapp中只支持高德和腾讯地图,要想使用自定义的地图还是挺麻烦的,我用了一种尝试方式,就是使用web-view的方式嵌入了。 (1)创建 web-view
1 <web-view src="pages/map/index" class ="map-wrap" ></web-view>
(2)引入js脚本 我尝试了使用vite进行配置,但是问题还是很多,最后直接在 index.html 文件中,使用 script 标签的方式引入了 mars3d 和 mars3d-cesium.
1 2 3 4 5 6 <link href ="https://unpkg.com/mars3d-cesium@latest/Build/Cesium/Widgets/widgets.css" rel ="stylesheet" type ="text/css" /> <script src ="https://unpkg.com/mars3d-cesium@latest/Build/Cesium/Cesium.js" type ="text/javascript" > </script > <link href ="https://unpkg.com/mars3d@latest/dist/mars3d.css" rel ="stylesheet" type ="text/css" /> <script src ="https://unpkg.com/mars3d@latest/dist/mars3d.js" type ="text/javascript" > </script >
(3)创建地图
(4)问题 这种方式带来的问题就是,无法在小程序和app等项目中使用了,因为小程序不支持引入外部 script 的链接。
问题 (1) Unbalanced delimiter found in string 我在使用 Mars3d 这个 npm 包的时候遇到了这个问题。
【解决方案】 我查看了这个报错的文件,然后查找了 “// #ifdef” 这个字段,发现真的有这个东西。把这个 #ifdef 删除就好了。
(2) 静态资源404
【解决方案】 就是将 mars3d-cesium 复制到 static/mars3d-cesium 目录,然后修改vite.config.js,通过 cesiumRunPath 定义 Cesium 的路径。
1 2 3 mars3dPlugin ({ cesiumRunPath :"static/mars3d-cesium" })
(3) define is not defined
【解决方案】 这个问题暂时没有解决,应该就是在vite中使用require语法导致的。
12.defineAsyncComponent 在使用微信小程序调试的时候,出现了 defineAsyncComponent 不支持的问题。
13.路由守卫 当某些页面需要登录,进入之前需要判断是否登录,如果没有登录则跳转到登录页。可以封装公共方法或混入实现,但是不太优雅,这时使用路由守卫实在是太方便了!幸好,插件uni-simple-router给我们提供了
14.地图组件 15.npm安装
16.设置相对路径 项目打包之后,配置相对目录,特别是在命令行的情况下。 (1)配置mainfast.json
1 2 3 4 5 6 "h5" : { "publicPath" : "./" , "router" : { "base" : "./" } }
(2) package.json package.json 打包时配置输出的目录 outDir
1 "build": "uni build --mode production --outDir build",