uni-app uni-app背景介绍 当前跨平台开发存在的3个问题 1、多端泛滥 2、体验不好 3、生态不丰富
uni-app 产品特征 1、跨平台更多 —— 条件编译:优雅的在一个项目里调用不同平台的特色功能! 2、运行体验更好 —— 组件、api与微信小程序一致,兼容 weex 原生渲染 3、通用技术栈,学习成本更低 —— vue 的语法、微信小程序的api、内嵌 mpvue 4、开放生态,组件更丰富 —— 支持通过 npm 安装第三方包、支持微信小程序自定义组件及 SDK、兼容 mpvue 组件及项目、App 端支持和原生混合编码、DCloud 将发布插件市场
功能框架
uni-app 规范 页面文件遵循 Vue 单文件组件(SFC)规范 组件标签靠近小程序规范 接口能力(JS API)靠近微信小程序规范 数据绑定及事件处理同 Vue.js 规范 为兼容多端运行,建议使用 flex 布局进行开发
条件编译 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <template> <view class="content"> <!-- #ifdef MP-WEIXIN --> <view class=""> 只会编译到小程序 </view> <!-- #endif --> <!-- #ifdef APP-PLUS --> <view class=""> 只会编译到 APP </view> <!-- #endif --> </view> </template>
生命周期 应用生命周期 页面生命周期 组件生命周期 组件 name
配置 pages.json globalStyle
pages
API 快速创建项目 通过 HBuilderX 创建项目 通过vue-cli命令行 创建项目 1 2 3 npm install -g @vue/cli vue create -p dcloudio/uni-preset-vue my-project
native.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 function call ( ) { var Intent = plus.android.importClass("android.content.Intent" ); var Uri = plus.android.importClass("android.net.Uri" ); var main = plus.android.runtimeMainActivity(); var uri = Uri.parse("tel:10010" ); var call = new Intent("android.intent.action.CALL" ,uri); main.startActivity( call ); }
uni-app 项目 目录结构 单文件 vue.js 文件导入 尺寸单位 rpx
代码块提示 HBuilderX 快捷键 项目发行 项目配置 页面配置 pages style app-plus
微信小程序 配置 condition:{ }
navigator 跳转
组件、组件生命周期
组件传值 props\emit、uni.$on、uni.$emit
uni-ui 组件库的引入
uni-app 规范
条件编译
App 端的 nvue 开发
HTML5+
组件、自定义组件、基础组件、生命周期、路由、API、语法、布局样式
Hbuiderx
vuecli方式
微信开放平台 unionid
分享
交互反馈
redis 根据用户信息生成 随机 key 登录根基这个生成的随机键来判断
(根据用户信息+上次登录的时间)-临时想法
uniapp 一键登录
e.currentTarget.id
e.target.id
获取系统信息
设置导航条
下拉刷新 onpullDownRefresh
上拉加载 onReachBottom
登录 openid unionid多端一致 微信开发平台
全局变量
节点信息
socket 的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import io from './common/weapp.socket.io.js' Vue.prototype.socket = io('http://192.168.1.3:8082') methods:{ // 发送讯息 send: function(){ if(this.cont.length>0){ this.arr.push(this.cont); let aa = this.cont this.socket.emit('message','aa') } } // 接受广播讯息 getmsg: function(){ this.socket.on('gbmsg',data=>{ this.arr.push(data); }) } }
uni-app 去掉 App、h5 端的导航栏 pages.json
1 2 3 4 5 6 7 8 9 "globalStyle": { "navigationBarTextStyle": "white", "navigationBarTitleText": "uni-app", "navigationBarBackgroundColor": "#007AFF", "backgroundColor": "#FFFFFF", "h5": { "titleNView": false } }
全局样式引入
vue
1 2 3 4 // App.vue <style> @import url('/common/free.css') </style>
引入图标库
1 2 3 4 5 @font-face { font-family : "iconfont" ; src : url ('data:base64' ) format ('woff2' ); }
1 2 3 4 5 6 // App.vue <style> /* #ifndef APP-PLUS-NVUE */ @import url('/common/icon.css') /* endif */ </style>
nvue
1 2 3 4 5 6 7 8 9 10 11 // 只支持 unicode // App.vue <script> onLaunch: function(){ const domModule = weex.requireModule('dom') domModule.addRule('fontFace', { 'fontFamily': "iconfont", 'src': "url('http://at.alicdn.com/t/font_1469606063_76593.ttf')" }); } </script>
midButton 中间凸起按钮设置
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 { "pages" : [{ "path" : "pages/component/index" , "style" : { "navigationBarTitleText" : "组件" } }, { "path" : "pages/API/index" , "style" : { "navigationBarTitleText" : "接口" } }, { "path" : "pages/component/view/index" , "style" : { "navigationBarTitleText" : "view" } }], "condition" : { "current" : 0 , "list" : [{ "name" : "test" , "path" : "pages/component/view/index" }] }, "globalStyle" : { "navigationBarTextStyle" : "black" , "navigationBarTitleText" : "演示" , "navigationBarBackgroundColor" : "#F8F8F8" , "backgroundColor" : "#F8F8F8" , "usingComponents" :{ "collapse-tree-item" :"/components/collapse-tree-item" }, "renderingMode" : "seperated" , "pageOrientation" : "portrait" , "rpxCalcMaxDeviceWidth" : 960 , "rpxCalcBaseDeviceWidth" : 375 , "rpxCalcIncludeWidth" : 750 }, "tabBar" : { "color" : "#7A7E83" , "selectedColor" : "#3cc51f" , "borderStyle" : "black" , "backgroundColor" : "#ffffff" , "height" : "50px" , "fontSize" : "10px" , "iconWidth" : "24px" , "spacing" : "3px" , "list" : [{ "pagePath" : "pages/component/index" , "iconPath" : "static/image/icon_component.png" , "selectedIconPath" : "static/image/icon_component_HL.png" , "text" : "组件" }, { "pagePath" : "pages/API/index" , "iconPath" : "static/image/icon_API.png" , "selectedIconPath" : "static/image/icon_API_HL.png" , "text" : "接口" }], "midButton" : { "width" : "80px" , "height" : "50px" , "text" : "文字" , "iconPath" : "static/image/midButton_iconPath.png" , "iconWidth" : "24px" , "backgroundImage" : "static/image/midButton_backgroundImage.png" } }, "easycom" : { "autoscan" : true , "custom" : { "^uni-(.*)" : "@/components/uni-$1.vue" } }, "topWindow" : { "path" : "responsive/top-window.vue" , "style" : { "height" : "44px" } }, "leftWindow" : { "path" : "responsive/left-window.vue" , "style" : { "width" : "300px" } }, "rightWindow" : { "path" : "responsive/right-window.vue" , "style" : { "width" : "300px" }, "matchMedia" : { "minWidth" : 768 } } }
1 2 3 4 5 6 7 8 // 只支持 unicode // App.vue <script> onLaunch: function(){ uni.onTabBarMidButtonTap(()=>{ }) } </script>
业务 刷礼物 list App nvue 专用组件 app端nvue专用组件。在app-nvue下,如果是长列表,使用list组件的性能高于使用view或scroll-view的滚动。原因在于list在不可见部分的渲染资源回收有特殊的优化处理。
如果需要跨端,建议使用 uni-ui 的 uni-list组件,它会自动处理webview渲染和原生渲染的情况,在app-nvue下使用list组件,而在其他平台则使用页面滚动。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 // live.nvue <template> <f-gift ref="gift"></f-gift> </template> <script> mounted(){ setInterval(()=>{ this.$refs.gift.send({ username: '发送人', avatar: "", gift_name: '蛋糕', gift_image: '/static/gift/3.png', num: 1 }) }) } </script>
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 // f-gift.vue 礼物组件 <template> <list style="width:520rpx;height:500rpx;" :show-scrollbar="false" :bounce="false"> <!-- 注意事项: 不能使用 index 作为 key 的唯一标识 --> <cell class="flex align-center px-3" v-for="(item, index) in dataList" :key="item.id" insert-animation="default" delete-animation="default"> <view style="width: 325rpx;"> </view> </cell> </list> </template> <script> const domModule = weex.requireModule('dom') export default { data () { return { gifts: [{}] } }, method:{ // 送礼物 send(gift){ this.gifts.push(gift) this.toBottom(); this.autoHide(); } // 置于底部 toBottom(){ this.$nextTick(() => { let index = this.gifts.length -1 let ref = 'item' + index if(this.$refs[ref]){ dom.scrollToElement(this.$refs[ref][0],{}) } }) }, // 自动消失 autoHide(){ if(this.gifts.length){ let timer = setTimeout(()=>{ this.gifts.splice(0,1); },5000) } } } } </script>
弹幕 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <template> <view> <scroll-view scroll-y="true" scroll-with-animation :scroll-inio-view="scrollInToView"> <view :id="'danmu'+item.id" > </view> </scrioll-view> </view> </template> <script> methods: { toBottom(){ let len = this.list.length; if(len > 0 && this.list[len-1]){ this.scrollInToView = 'danmu' + this.list[len - 1].id } } } </script>
UI 框架 uView :uView是uni-app生态专用的UI框架,uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码, 可发布到iOS、Android、H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉)等多个平台(引言自uni-app网)ThorUI :简约而不简单一直是ThorUI的追求。ThorUI目前有微信小程序原生版本 和uni-app版本 ,后续会扩展到其他原生版本,扩大生态。 除了组件库ThorUI还会陆续发布一些常用模板,使开发更加高效。
目前组件与模板默认支持App端(IOS和Android)、H5、微信小程序、QQ小程序。
colorui :鲜亮的高饱和色彩,专注视觉的小程序组件库
报错 微信小程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 SystemError (appServiceSDKScriptError) Cannot read property 'forceUpdate' of undefined TypeError: Cannot read property 'forceUpdate' of undefined at http://127.0.0.1:28307/appservice/__dev__/WAService.js:2:1415111 at http://127.0.0.1:28307/appservice/__dev__/WAService.js:2:633507 at o (http://127.0.0.1:28307/appservice/__dev__/asdebug.js:1:3197) at e.exports.<anonymous> (http://127.0.0.1:28307/appservice/__dev__/asdebug.js:1:3577) at http://127.0.0.1:28307/appservice/__dev__/asdebug.js:1:1844 at Array.forEach (<anonymous>) at WebSocket._ws.onmessage (http://127.0.0.1:28307/appservice/__dev__/asdebug.js:1:1826) console.error @ VM38:1 errorReport @ VM45 WAService.js:2 (anonymous) @ VM45 WAService.js:2 (anonymous) @ VM45 WAService.js:2 o @ VM42 asdebug.js:1 (anonymous) @ VM42 asdebug.js:1 (anonymous) @ VM42 asdebug.js:1 _ws.onmessage @ VM42 asdebug.js:1
配置微信小程序 AppID
sitemap.json Error: 未找到入口 sitemap49.json 文件,或者文件读取失败,请检查后重新编译。
根目录下创建 sitemap.json 并配置
uni-app 图表
H5端流行的echart报表因为涉及大量dom操作,无法跨端使用,而wx-chart在跨端和更新方面都不足,如果要做小程序,推荐使用全端可用的uChart 。
如只考虑H5端,也可以继续使用 echart、f2等常规web图表。
如不考虑小程序,那么App端和H5,还可以通过renderjs 技术来使用 echart、f2等web图表,功能性能比uchart更好。什么是renderjs 、基于renderjs使用echart的示例
不开发APP,可以不使用nvue
插件 插件大赛2020评奖结果揭晓,这些优秀的插件你都用起来了吗?
极光认证官方SDK
uCharts高性能跨全端图表
uParse修复版-html富文本加载
APP-引导页+官方示例
封装的request网络请求
开源项目 Uni-App
awesome-uni-app
来客推电商 / 小程序商城+APP+SaaS+前后代码开源
相关资料 [视频]uni-app跨平台框架官方教程 √ [视频]uni-app实战直播app全栈开发,uni-app实战视频教程 √
[视频]uni-App从入门到实战 [视频]uni-app实战商城类app和小程序
[视频]uni-app 快速入门 从零开始实现新闻资讯类跨端应用 [视频]uni-app基础+进阶+案例 [视频]uni-app零基础入门到项目实战
uni-app 零基础到实战课程
2020uniApp视频全套资料配源码【千锋Web前端】 uniapp 打造美团外卖微信小程序,uni-app,vue 中高级实战课程 ThinkPHP6+uniapp实战开发【简书app】 uni-app 跨平台 App 终极解决方案 uni-app视频教程合集|UniApp实战教程
小程序开发:用原生还是选框架(wepy/mpvue/taro/uni-app)– 第1季 创建、运行、发布uni-app uni-app 全局变量的几种实现方式 uni-app 中保持用户登录状态 uni-app去掉h5端的导航栏 uni-app中过滤器的使用 uniapp获取微信手机号码 uni-app H5跨域问题解决方案(CORS、Cross-Origin) 直播业务指南 历时六个月月完全由UNI做推流APP的经历分享
跨平台前端框架uni-app学习 Native.js示例汇总 dcloud 社区问答
SystemError (appServiceSDKScriptError) 高效开发技巧 开发规范
uni-app官方教程学习手记 √ uni-app—从安装到卸载 √ wepy踩坑 sitemap.json Error: 未找到入口 sitemap49.json 文件,或者文件读取失败,请检查后重新编译。 √ 解决uni-app开发环境中H5端跨域问题 √
uni-app 全局变量的几种实现方式 √
uni-app 启动界面(splash)参数配置说明 | 启动慢的原因 (https://ask.dcloud.net.cn/article/35021 )√
HBuilder X运行小程序时,打开了微信开发者工具,但微信开发者工具未运行项目但又没有错误提示 √
uni-app 小程序系列教程
uni-app官网
uni-app 资源在线升级/热更新
uni-app 整包升级/更新方案
关于 uni-app 白话uni-app vue vue和微信小程序的区别、比较 uni-ui H5 端路由配置 网络请求封装拦截等可参考插件市场 从App端跳转到微信小程序方式 uni-app导航栏文档和注意事项 导航栏开发指南 导航栏演示示例 uni-app大法好 ,nvue 从入坑到放弃 uni-app小程序手把手项目实战
uni-app网络请求封装 uni-app 请求封装
http://www.hcoder.net/tutorials/info/id/1335
Native.js示例汇总