uni-app快速入门开发

10,534 阅读10分钟

初衷

近期公司要开发一个电商小程序,之前的mpvue已经停更别再选了,原生嘛 也没啥意思,因为是vue党所所以团队就选择了 uni-app来试试水,一周多使用下来使用感受 还是可以的。 会vue的 话简直就是无脑开发,看完这篇文章 直接上手撸。

小程序 分包加载:链接

底层实现原理:链接

uni-app runtime :

逻辑层和视图层分离,且非H5端通信有折损

uni-app 在非H5端运行时,从架构上分为逻辑层和视图层两个部分。逻辑层负责执行业务逻辑,也就是运行js代码,视图层负责页面渲染。

虽然开发者在一个vue页面里写js和css,但其实,编译时就已经将它们拆分了。

逻辑层详解

逻辑层是运行在一个独立的jscore里的,它不依赖于本机的webview,所以一方面它没有浏览器兼容问题,可以在Android4.4上跑es6代码,另一方面,它无法运行window、document、navigator、localstorage等浏览器专用的js API。

uni-app的App端和小程序端的js引擎,其实是在jscore上补充了一批手机端常用的JS API,比如扫码。

视图层详解

通常:h5和小程序平台,以及app-vue,视图层是webview。而app-nvue的视图层是基于weex改造的原生视图。

uni-app的js基本没有不同手机的兼容问题(因为js引擎自带了),而视图层的css,在app-vue上会有手机浏览器的css兼容问题。所以在app-vue的场景中尽量不要使用太新的css语法,除非你不打算支持低端机。

当然这样做也是有 利弊的 详情查看

项目创建

两种方式

1. 通过 HBuilderX 可视化界面

这个超级简单 开箱即用,无需配置nodejs。

下载好 IDE在点击工具栏里的文件 -> 新建 -> 项目 ,喜欢哪个模板选一个就完事儿了(推荐 hello uni-app)。

2. 通过vue-cli命令行 ( vue玩家推荐)

通过vuecli3.0+ 做为支持,所以 需要先安装  npm install -g @vue/cli  然后=》创建项目:  vue create -p dcloudio/uni-preset-vue my-project

自带各种脚本,秀的不行啊! 通过这个方式,可以安装各种 你想要的 css预处理器、第三方插件等等,玩vue项目的都懂的。 image.png

关于NPM支持

cli项目默认已经有package.json了。 HBuilderX创建的项目默认没有,需要通过初始化命令来创建。

关于页面配置

跟小程序一样放在 : pages.json

{
    "pages": [{
        "path": "pages/component/index",
        "style": {
            "navigationBarTitleText": "组件"
        }
  }]
}

开发规范

为了实现多端兼容,综合考虑编译速度、运行性能等因素,uni-app 约定了如下开发规范:

  • 组件标签靠近小程序规范,(比如基本的 view、text、image)详见uni-app 组件规范
  • 接口能力(JS API)靠近微信小程序规范,但需将前缀 wx 替换为 uni,详见uni-app接口规范
  • 数据绑定及事件处理同 Vue.js 规范,同时补充了App及页面的生命周期
  • 为兼容多端运行,建议使用flex布局进行开发

资源路径说明

  • @开头的绝对路径以及相对路径会经过base64转换规则校验

模板内引入静态资源

<!-- 绝对路径,/static指根目录下的static目录,在cli项目中/static指src目录下的static目录 -->
<image class="logo" src="/static/logo.png"></image>
<image class="logo" src="@/static/logo.png"></image>
<!-- 相对路径 -->
<image class="logo" src="../../static/logo.png"></image>

js文件引入

/ 绝对路径,@指向项目根目录,在cli项目中@指向src目录
import add from '@/common/add.js'
// 相对路径
import add from '../../common/add.js'

css引入静态资源

/* 绝对路径 */
@import url('/common/uni.css');
@import url('@/common/uni.css');
/* 相对路径 */
@import url('../../common/uni.css');

页面

getCurrentPages() 函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面。 **最好 自己打印出来 看下 所需信息    const pages = **getCurrentPages()

尺寸单位

uni-app 支持的通用 css 单位包括 px、rpx

  • px 即屏幕像素
  • rpx 即响应式px,一种根据屏幕宽度自适应的动态单位。以750宽的屏幕为基准,750rpx恰好为屏幕宽度。屏幕变宽,rpx 实际显示效果会等比放大。

生命周期

详情 链接

onLoad 监听页面加载,主要通过这个获取页面参数 onLoad(option)}{},参考示例
onShow 监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面
onReady 监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发
onHide 监听页面隐藏
onUnload 监听页面卸载

全局页面通讯

链接

触发全局的自定事件

uni.$emit(eventName,OBJECT) 附加参数都会传给监听器回调。栗子: uni.$emit('update',{msg:'页面更新'})

监听全局的自定义事件

uni.$on(eventName,callback)事件可以由 uni.$emit 触发,回调函数会接收所有传入事件触发函数的额外参数。

uni.$on('update',function(data){
  console.log('监听到事件来自 update ,携带参数 msg 为:' + data.msg);
})

注意事项

  • uni.$emit、 uni.$on 、 uni.$once 、uni.$off 触发的事件都是 App 全局级别的,跨任意组件,页面,nvue,vue 等
  • 使用时,注意及时销毁事件监听,比如,页面 onLoad 里边 uni.$on 注册监听,onUnload 里边 uni.$off 移除,或者一次性的事件,直接使用 uni.$once 监听

样式

使用 uni-app 组件的时候 有时候修改内部组件样式 无效,需要使用 /deep/ .xxx { } 才可以生效。

页面通用模式

<template>
  <view class="container">  
  
 <view class="user-section">
  <image class="bg" src="/static/user-bg.jpg"></image>
 </view>

 <view class="info-box">
  <text class="username">{{userInfo.nickname || '游客'}}</text>
 </view>
    
  </view>
</template>

// 基本上和vue一摸一样
<script>
import { getMyInfo } from '@/api/my.js'
import { mapState } from 'vuex';
import mixins_share from '@/mixins/share.js'
export default {
  mixins: [mixins_share],
  data() {
    return {
      userInfo: {},
      vipTheme: {
   
      },
    };
  },
  computed: {
    ...mapState(['accessToken'])
  },
  onLoad(option) {
    this.nickName = option.nickName
  },
  onShow() {

  },
  methods: {
    scroll: function(e) {
      console.log(e);
    },
    goOrderList() {
      uni.navigateTo({
        url: '/pages/orderList/list'
      })
    }
  }
};
</script>

// 使用 css插件需要安装
<style lang="scss" scoped>
.mine {
  min-height: 100vh;
  background-color: #f5f5f5;
  .mine-header {
   }
 }
 </style>

注意事项:

  • 页面生命周期 优先使用 小程序那一套, onLoad(option) {}  获取参数, onShow() {}  页面显示.

页面跳转方式

保留当前页面,跳转到某个页面

使用uni.navigateBack可以返回到原页面。

/在起始页面跳转到test.vue页面并传递参数
uni.navigateTo({
    url: 'test?id=1&name=uniapp'
});

注意: 跳转到 tabBar 页面只能使用 switchTab 跳转

关闭当前页面,跳转到应用内的某个页面。

uni.redirectTo(OBJECT)

跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。

uni.switchTab(OBJECT)

关闭当前页面,返回上一页面或多级页面

uni.navigateBack(OBJECT)可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层。

// 在C页面内 navigateBack,将返回A页面
uni.navigateBack({
    delta: 2
});

想了解更多?那点我官方走起

数据缓存

同步的话 在后面+Sync 例如:uni.setStorageSync

数据存储在本地缓存(异步接口)

uni.setStorage(OBJECT)指定的 key 中,会覆盖掉原来该 key 对应的内容

uni.setStorage({
    key: 'storage_key',
    data: JSON.stringify(data), // 需要存储的内容,只支持原生类型、及能够通过 JSON.stringify 序列化的对象
    success: function () {
        console.log('success');
    }
});

从本地缓存中异步获取指定 key 对应的内容

uni.getStorage({
    key: 'storage_key',
    success: function (res) {
        console.log(res.data);
    }
});

异步移除指定 key

uni.removeStorage({
    key: 'storage_key',
    success: function (res) {
        console.log('success');
    }
});

清理本地数据缓存。

uni.clearStorage()

注意:

uni-app的Storage在不同端的实现不同:

  • H5端为localStorage,浏览器限制5M大小,是缓存概念,可能会被清理
  • App端为原生的plus.storage,无大小限制,不是缓存,是持久化的
  • 各个小程序端为其自带的storage api,数据存储生命周期跟小程序本身一致,即除用户主动删除或超过一定时间被自动清理,否则数据都一直可用。
  • 微信小程序单个 key 允许存储的最大数据长度为 1MB,所有数据存储上限为 10MB。
  • 支付宝小程序单条数据转换成字符串后,字符串长度最大200*1024。同一个支付宝用户,同一个小程序缓存总上限为10MB。
  • 百度、字节跳动小程序文档未说明大小限制

想了解更多?那点我官方走起

网络请求

发起网络请求: 官网介绍

uni.request({
    url: 'https://www.example.com/request', //仅为示例,并非真实接口地址。
    data: {
        text: 'uni.request'
    },
    header: {
        'custom-header': 'hello' //自定义请求头信息
    },
    success: (res) => {
        console.log(res.data);
        this.text = 'request success';
    }
});
  • 单次网络请求数据量建议控制在50K以下(仅指json数据,不含图片),过多数据应分页获取,以提升应用体验。

上传文件(图片)

uni.uploadFile(OBJECT)

如页面通过 uni.chooseImage 等接口获取到一个本地资源的临时文件路径后,可通过此接口将本地资源上传到指定服务器。另外选择和上传非图像、视频文件参考:ask.dcloud.net.cn/article/355…

uni.chooseImage({
    success: (chooseImageRes) => {
        const tempFilePaths = chooseImageRes.tempFilePaths;
        uni.uploadFile({
            url: 'https://www.example.com/upload', //仅为示例,非真实的接口地址
            filePath: tempFilePaths[0],
            name: 'file',
            formData: {
                'user': 'test'
            },
            success: (uploadFileRes) => {
                console.log(uploadFileRes.data);
            }
        });
    }
});

媒体文件操作 官网介绍

常用界面操作 官网介绍

其他辅助功能 官网介绍

使用cli创建项目和使用HBuilderX可视化界面创建项目有什么区别

编译器的区别

  • cli创建的项目,编译器安装在项目下。并且不会跟随HBuilderX升级。如需升级编译器,执行npm update
  • HBuilderX可视化界面创建的项目,编译器在HBuilderX的安装目录下的plugin目录,随着HBuilderX的升级会自动升级编译器。
  • 已经使用cli创建的项目,如果想继续在HBuilderX里使用,可以把工程拖到HBuilderX中。注意如果是把整个项目拖入HBuilderX,则编译时走的是项目下的编译器。如果是把src目录拖入到HBuilderX中,则走的是HBuilderX安装目录下plugin目录下的编译器
  • cli版如果想安装less、scss、ts等编译器,需自己手动npm安装。在HBuilderX的插件管理界面安装无效,那个只作用于HBuilderX创建的项目。

结语

所有的评测都只是提供决策依据,最后的结果还是要依赖开发者的团队技术栈、业务诉求、未来规划等。 不过作为一篇评测文章的结语,我们还是要给出自己的建议:

  • 如果你熟悉React,不懂Vue.js,推荐Taro;
  • 如果你熟悉Vue.js,则推荐 uni-app;
  • 如果你已经有H5代码,只想增加微信小程序平台,并且对性能要求不高,可以考虑kbone;
  • 如果你的业务涉及多端,更推荐 uni-app;
  • 如果你希望通过 serverless 方案快速上线业务,推荐 uni-app。

此结语摘自隔壁大佬:作者:CHB   链接:juejin.cn/post/684490…

先到这里了,关注 后期慢慢更新更多~

问题记录

1、需求描述:小程序页面分享带参数 u=userid,别人打开的时候 第一次会走 onLaunch 来获取参数并存储。如果 再打开 另一个人分享的 userid是不同的,此时 onLaunch不在走了,怎么获取参数?

解决方案: 在main.js 里 混入 onLoad

Vue.mixin({
  onLoad(options){
  // 获取到参数 操作 
  }
}

2、全局 添加 分享功能,实现每个页面都可以 进行特性模式 分享。 解决方案:

Vue.mixin({
  onShareAppMessage(e) {
    const merchant = this.$store.getters.merchant
    return {
      title: merchant.subName,
      path: `/pages/tabBar/vhome${'?refId='+this.$store.getters.userInfo.uid}`,
      imageUrl: merchant.posterImg
    }
  }
})

本文使用 mdnice 排版