sssong123

 

uniapp详解

一、介绍

友情提示,样式引用最后加分号(;)

1、什么是uni-app?

进入官网

uni-app 是一个使用 Vue.js (opens new window)开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。

二、uniapp 初始化相关配置

1、工程目录结构

 注意: 

  • static 下目录的 js 文件不会被 webpack 编译,里面如果存在 es6 的代码不经过转化直接运行,在手机设备上会出现报错
  • 所有的 less,scss 等资源同样不要放在 static 目录下,建议这些公共的资料放在 common 目录下

2、应用配置 manifest.json

应用的配置文件,用于指定应用的名称,图标,权限等,我们可以在这里为 Vue 为 H5 设置跨域拦截处理器

3、编译配置 vue.config.js

是一个可选的配置文件,如果项目的根目录中存在这个文件,那么它会被自动加载,一般用于配置 webpack 等编译选项

 4、全局配置 pages.json 

官方文档

注意:结束的那个对象,不能加逗号(,)结束,会出现报错

对 uni-app 进行全局配置,决定页面文件的路径,窗口样式,原生的导航栏,底部的原生 tabbar 等,它类似微信小程序中的 app.json 的页面管理部分

 5、全局样式 uni.scss

  • 为了方便整体控制应用的风格。比如按键,边框风格,里面预置了一批scss变量预置。
  • uni-app官方扩展插件(uni ui)及插件市场上很多三方插件均使用了这些样式变量,如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import这个文件),方便用户通过搭积木的方式开发整体风格一致的App。

  • 是一个特殊的文件,在代码中无需 import 这个文件即可在scss代码中使用这里的样式变量。uniapp的编译器在 webpack配置中特殊处理了这个 uni.scss ,达到全局可用的效果,如果开发者想要less,stylus的全局使用,需要在 Vue.config.js 中自行配置 webpack 策略

 6、condition 启动模式配置

详情

7、uniapp 开发规范及资源路径

1.开发规范约定

  • 页面文件向导Vue单文件组件(SFC)规范

  • 组件标签靠近小程序规范,详见uni-app 组件规范

  • 互连能力(J5 API)靠近微信小程序规范,但需要将替换替换wx为uni详见uni-app接口规范

  • 数据绑定及事件处理同Vue.js规范,同时补充了App 和页面的生命周期

  • 为兼容多端运行,建议使用 flex 布局进行开发

三、uniapp 生命周期

uniapp 完全支持 Vue 实例的生命周期,同时还新增 应用生命周期页面生命周期

1、应用生命周期

主要在 app.vue运行

函数名 说明
onLaunch 当 uni-app 初始化完成时触发   (全局只触发一次)
onShow 当 uni-app 启动,或从后台进入前台显示
onHide 当 uni-app 从前台进入后台
onError 当 uni-app 报错时触发
onUniNViewMessage 当 nvue 页面发送的数据进行监听,可参考 nvue 向 Vue通讯
onUnhandledRejection 对未处理的 Promise 拒绝事件监听函数
onPageNotFound 页面不存在监听函数(常用)
onThemeChange 监听系统主体变化

 

 

 

 

 

 

 

 

 

 

2、页面生命周期

函数名 说明
onLoad

监听页面加载,其参数为上个页面传递的数据,参数类型为0bject〔用于页面传参),参考示例

onShow

监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面

onReady

监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发

onHide 监听页面隐藏
onUnload 监听页面卸载
onResize 监听窗口尺寸变化
onPullDownRefresh 监听用户下拉动作,一般用于下拉刷新,
onReachBottom 页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据
onTabItemTap

点击底部导航栏切换页面(tab) 时触发,参数为0bject,具体见下方注意事项

onShareAppMessage

用户点击右上角分享,在右上角3个点里面

onPageScroll

监听页面滚动,参数为0bject

onNavigationBarButtonTap

监听原生标题栏按钮点击事件,参数为Object

onBackPress 监听页面返回
onNavigationBarSearchInputChanged 监听原生标题栏搜索输入框输入内容变化事件
onNavigationBarSearchInputConfirmed

监听原生标题栏搜索输入框搜索事件,用户点击软键盘上的“搜索"按钮时触发。

onNavigationBarSearchInputClicked

监听原生标题栏搜索输入框点击事件

onShareTimeIine

监听用户点击右上角转发到朋友圈

onAddToFavorites

监听用户点击右上角收藏

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

四、uniapp 路由配置及页面跳转

1、路由的配置

"pages": [
        {
            "path": "pages/index",
            "style": {
                "navigationBarTitleText": "路由配置", //导航栏标签文字
                "navigationBarBackgroundColor": "#FFFFFF", //导航栏背景颜色
                "navigationBarTextStyle": "black", //导航栏标题颜色
                "backgroundColor": "#FFFFFF", //窗口的背景色
                "enablePullDownRefresh": true //是否开启下拉刷新
            }
        },
        {
            "path": "pages/user",
            "style": {
                "navigationBarTitleText": "路由配置",
                "navigationBarBackgroundColor": "#FFFFFF",
                "navigationBarTextStyle": "black",
                "backgroundColor": "#FFFFFF",
                "enablePullDownRefresh": true
            }
        }
]

2、路由的跳转

uni-app 有两种页面路由跳转方式:使用navigator组件跳转(标签式导航)、调用API跳转(编程式导航)

(1)、navigator标签组件跳转传参方式


普通跳转:
// 路径:/pages/search/search <navigator url="/pages/search/search"> </navigator> 二级跳转:带参数 // 路径:pages/search/wz/wz <navigator :url="'wz/wz?ids='+e.id"> </navigator>

 

框架以栈的形式管理当前所有页面, 当发生路由切换的时候,页面栈的表现如下:

路由方式页面栈表现触发时机
初始化 新页面入栈 uni-app 打开的第一个页面
打开新页面 新页面入栈 调用 API uni.navigateTo 使用组件 <navigator open-type="navigate" />
页面重定向 当前页面出栈,新页面入栈 调用 API uni.redirectTo 使用组件
页面返回 页面不断出栈,直到目标返回页 调用 API uni.navigateBack 使用组件 、 用户按左上角返回按钮、安卓用户点击物理back按键
Tab 切换 页面全部出栈,只留下新的 Tab 页面 调用 API uni.switchTab 使用组件 、 用户切换 Tab
重加载 页面全部出栈,只留下新的页面 调用 API uni.reLaunch 使用组件

3、获取当前页面栈

getCurrentPages() 函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面。

注意: getCurrentPages() 仅用于展示页面栈的情况,请勿修改页面栈,以免造成页面状态错误。

4、路由传参与接收

说明:页面生命周期的 onLoad()监听页面加载,其参数为上个页面传递的数据,如:

//页面 1 跳转并传递参数
uni.navigateTo({
    url: 'page2?name=liy&message=Hello'
});

下一个页面的onLoad函数可得到传递的参数。

// 页面 2 接收参数
onLoad: function (option) { //option为object类型,会序列化上个页面传递的参数
    console.log(option.name); //打印出上个页面传递的参数。
    console.log(option.message); //打印出上个页面传递的参数。
}

注意url 有长度限制,太长的字符串会传递失败,并且不规范的字符格式也可能导致传递失败,所以对于复杂参数建议使用 encodeURI、decodeURI 进行处理后传递

5、小程序路由分包配置

因小程序有体积和资源加载限制,各家小程序平台提供了分包方式,优化小程序的下载和启动速度。

所谓的主包,即放置默认启动页面及 TabBar 页面,而分包则是根据 pages.json 的配置进行划分。

在小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,会把对应分包自动下载下来,下载完成后再进行展示,此时终端界面会有等待提示。

// pages:主包
"pages": [{
     "path": "pages/index/index",
      "style": {
           "navigationBarTitleText": "uni-app",
            "enablePullDownRefresh": true  //允许顶部下拉刷新
     }
}],
// subPackages:分包
根目录新建 subpages 目录存放分包
"subPackages": [ { "root": "news", // 根目录下的文件夹名 "pages": [{ "path": "index", "style": { "navigationBarTitleText": "新闻中心", "navigationBarBackgroundColor": "#FFFFFF", "navigationBarTextStyle": "black", "backgroundColor": "#FFFFFF" } } ] } ... ], // 预下载分包设置 "preloadRule": { "pages/index": { "network": "all", "packages": ["activities"] } }

 五、uniapp 常用组件简介

进入官网

uni-app 为开发者提供了一系列基础组件,类似 HTML 里的基础标签元素,但 uni-app 的组件与 HTML 不同,而是与小程序相同,更适合手机端使用。

虽然不推荐使用 HTML 标签,但实际上如果开发者写了div等标签,在编译到非H5平台时也会被编译器转换为 view 标签,类似的还有 spantextanavigator等,包括 css 里的元素选择器也会转,但为了管理方便、策略统一,新写代码时仍然建议使用view等组件。

开发者可以通过组合这些基础组件进行快速开发, 基于内置的基础组件,可以开发各种扩展组件,组件规范与vue组件相同。

六、uniapp 常用 API 简介

进入官网

uni-app的 js 代码,h5 端运行于浏览器中,非 h5 端 Android 平台运行在 v8 引擎中,iOS 平台运行在 iOS 自带的 jscore 引擎中。所以,uni-app的 jsAPI 由标准 ECMAScript 的 js API 和 uni 扩展 API 这两部分组成。

ECMAScript 由 Ecma 国际管理,是基础 js 语法。浏览器基于标准 js 扩充了window、document 等 js API;Node.js 基于标准 js 扩充了 fs 等模块;小程序也基于标准 js 扩展了各种 wx.xx、my.xx、swan.xx 的 API。

标准 ecmascript 的 API 非常多,比如:console、settimeout等等。

非 H5 端,虽然不支持 window、document、navigator 等浏览器的 js API,但也支持标准 ECMAScript。

开发者不要把浏览器里的 js 等价于标准 js。

所以 uni-app 的非 H5 端,一样支持标准 js,支持 if、for 等语法,支持字符串、数组、时间等变量及各种处理方法,仅仅是不支持浏览器专用对象。

1、图片的上传,

了解详情

uni.chooseImage(): 从本地相册选择图片或使用相机拍照上传。

                 uni.chooseImage({
                    count: 1,
                    sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
                    sourceType: ['album', 'camera'], //从相册选择还是相机
                    success: res => {   //返回图片的本地文件路径列表
                        console.log(res.tempFilePaths[0]);
//在这里不套定时器不生效 setTimeout(()=>{ uni.pageScrollTo({ // 将页面滚动到目标位置 scrollTop:999999, duration:0, // 间隔时间 success() { // console.log('成功'); }, }) }) } })

七、uniapp 自定义组件与通信

1、自定义组件的概念

组件是 vue 技术中非常重要的部分,组件使得与ui相关的轮子可以方便的制造和共享,进而使得vue使用者的开发效率大幅提升,在项目的component目录下存放组件,uni-app 只支持 vue 单文件组件(.vue 组件)

组件可以使用「全局注册」和「页面引入」两种方式进行使用,使用分为三步:

导入 import xxx from 'xxx'

注册 Vue.use('xx',xx) 或 components:{ xxx }

使用 <xx /> 或 <xx></xx>

2、父子组件通信

  • 父传子。父组件通过自定义属性向子组件传递数据,子组件通过 props 接收父组件传递的数据
    // 父组件
    <template>
        <view class="content">
            <chil :msg='title'></chil>
        </view>
    </template>
    <script>
         export default {
            data() {
            return {
                 title: '我是父组件定义的数据信息'
                    }
            }
          },
    </script>
    
    // 子组件
    <template>
        <view class="content">
            <view>{{msg}}</view>
        </view>
    </template>
    <script>
         export default {
            props:['msg'],
            data() {
               return {
                   title: '我是父组件定义的数据信息'
               }
            }
         },
    </script>
  • 子传父。 父组件通过自定义事件标签向子组件传递事件,子组件通过触发父组件定义事件方式修改父组件数据
    // 父组件
    <template>
        <view class="content">
            <chil :msg='title' @childEvent="sayHello"></chil>
        </view>
    </template>
    <script>
         export default {
            data() {
                 return {
                      title: '我是父组件定义的数据信息'
                 }
            },
            methods: {
            sayHello(txt){
                // 触发事件,把文案,通过自定义事件又传递给子组件
                this.title = '子组件跟我通讯了'
                console.log('获取子组件传递过来的信息',txt);    
            }
        }
          },
    </script>
    
    // 子组件
    <template>
        <view class="content">
            <view>{{msg}}</view>
    <view>
    <button @click="sayHelloToFather">按钮</button>
    </view>
        </view>
    </template>
    <script>
         export default {
            props:['msg'],
            data() {
               return {
                   title: '我是父组件定义的数据信息'
               }
            },
            methods:{
            sayHelloToFather(){
    // 触发自定义事件
    this.$emit('childEvent','我是子组件的数据') } } }, </script>

3、全局事件的定义及通讯 。【uni.$on  $  uni.$emit  $  uni.$once  &  uni.$off】

进入官网

在整个应用的任何地方均可以使用uni.$on创建一个全局事件

在整个应用的任何地方也均可以使用 uni.$emit 来触发全局事件,实现多组件见的数据通信

注意:在应用中必须要先用 uni.$on创建事件后,才能用 uni.$emit 调用

                               // 【任意组件间通讯】
// 绑定的组件
onLoad() {
    uni.$on('getInfo',(data)=>{
        console.log('任意组件传参',data);
    })
},


// 触发的组件
methods:{
    sayHelloToFather(){    
        uni.$emit('getInfo','宋')
    }
}

八、Vuex 状态管理

跟 vue 一样

  • State:存储状态数据

  • Getter:从状态数据派生数据,相当于 State 的计算属性

  • Mutation:存储用于同步更改状态数据的方法,默认传入的参数为 state

  • Action:存储用于异步更改状态数据,但不是直接更改,而是通过触发 Mutation 方法实现,默认参数为context

  • Module:Vuex 模块化

1、交互关系图

 

2、模拟用户登入逻辑案例

状态管理(仓库vuex)代码:

// 引入 Vue
import Vue from 'vue'
// 引入 Vuex
import Vuex from 'vuex'
Vue.use(Vuex)

export default new Vuex.Store({
    actions:{
        login(context,userName){
            uni.setStorageSync('userName',userName)
            context.commit('MLOGIN',userName)
        },
        logout(context){
            // 清空所有存储的数据
            uni.clearStorageSync()
            context.commit('MLOGOUT')
        }
    },
    mutations:{
        MLOGIN(state, userName){
            state.userName = userName
        },
        MLOGOUT(state){
            state.userName = '退出状态用户'
        }
    },
    state:{
        //实现固化存储
        userName: uni.getStorageSync('userName') ? uni.getStorageSync('userName'):'未登录用户'
    }
})

//在main.js 中注册

// 调用 store vuex 状态管理
import store from '@/store/index.js'


const app = new Vue({
...App,
store
})

 

组件中代码:

<template>
    <view>
        <text>通讯录</text>
        <view class="">{{userName}}</view>
        <view class="">
            <button @click="login('宋')">登陆</button>
            <button @click="logout">退出</button>
        </view>
    </view>
</template>

<script>
    import {mapState,mapActions} from 'vuex'
    export default {
        data() {
            return {
                
            }
        },
        computed:{
            ...mapState(['userName'])
        },
        methods: {
            // ...mapActions(['login']),
            ...mapActions(['login','logout'])
        }
    }
</script>

九、运行环境判断与跨端兼容

1、判断是开发环境还是生成环境

uni-app 可通过 process.env.NODE_ENV 判断当前环境是开发环境还是生产环境,一般用于连接测试服务器或生产服务器的动态切换。

在HBuilderX 中,点击「运行」编译出来的代码是开发环境,点击「发行」编译出来的代码是生产环境

// 可以写在任何地方
if(process.env.NODE_ENV === 'development'){
    console.log('开发环境')
}else{
    console.log('生产环境')
}

2、判断平台:编译期判断 & 运行期判断两种

  • 编译期判断,即条件判断,不同平台在编译出包后已经是不同的代码。了解详情
    // #ifdef H5
    alert('只有h5平台才有alert方法') 
    // #endif
    console.log('条件判断');
  • 运行期判断是指代码已经打入包中,仍然需要在运行期判断平台,此时可使用 uni.getSystemInfoSync().platform 判断客户端环境是 Android、iOS 还是小程序开发工具
    switch(uni.getSystemInfoSync().platform){
    case 'android':
       console.log('运行Android上')
       break;
    case 'ios':
       console.log('运行iOS上')
       break;
    default:
       console.log('运行在开发者工具上')
       break;
    }

3、跨端兼容

uni-app 已将常用的组件、JS API 封装到框架中,开发者按照 uni-app 规范开发即可保证多平台兼容,大部分业务均可直接满足,但每个平台有自己的一些特性,因此会存在一些无法跨平台的情况。

  • 大量写 if else,会造成代码执行性能低下和管理混乱。

  • 编译到不同的工程后二次修改,会让后续升级变的很麻烦。

在 C 语言中,通过 #ifdef、#ifndef 的方式,为 windows、mac 等不同 os 编译不同的代码。 uni-app 参考这个思路,为 uni-app 提供了条件编译手段,在一个工程里优雅的完成了平台个性化实现。

 

条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。

// 写法:以 #ifdef 或 #ifndef 加%PLATFORM%开头,以#endif 结尾。

// #ifdef H5
alert('你好')
// #endif
console.log('条件判断');
写法:以 #ifdef 或 #ifndef 加%PLATFORM%开头,以#endif 结尾。
  • // #ifdef %PLATFORM%
  • // #endif
  • %PLATFORM%:平台名称 可选取值,参考下表
%PLATFORM% 可取值参考表
平台
APP-PLUS App
APP-PLUS-NVUE App nvue
H5 H5
MP-WEIXIN 微信小程序
MP-ALIPAY 支付宝小程序
MP-BAIDU 百度小程序
MP-TOUTIAO 字节跳动小程序
MP-QQ QQ小程序
MP-360 360小程序
MP 微信小程序/支付宝小程序/百度小程序/字节跳动小程序/QQ小程序/360小程序
QUICKAPP-WEBVIEW 快应用通用(包含联盟、华为)
QUICKAPP-WEBVIEW-UNION 快应用联盟
QUICKAPP-WEBVIEW-HUAWEI 快应用华为

案例:

组件的条件注释:

        <!-- #ifdef H5 -->
        <view>
          h5页面会显示
        </view>
        <!-- #endif -->

        <!-- #ifdef MP-WEIXIN -->
        <view>
          微信小程序会显示
        </view>
        <!-- #endif -->

        <!-- #ifdef APP-PLUS -->
        <view>
          app会显示
        </view>
        <!-- #endif -->

api 的条件注释:

onLoad () {
  //#ifdef MP-WEIXIN
  console.log('微信小程序')
  //#endif
  
  //#ifdef H5
  console.log('h5页面')
  //#endif
}

样式的条件注释:

/* #ifdef H5 */
view{
  height: 100px;
  line-height: 100px;
  background: red;
}
/* #endif */

/* #ifdef MP-WEIXIN */
view{
  height: 100px;
  line-height: 100px;
  background: green;
}
/* #endif */

 

posted on 2022-08-28 13:38  叫兽~  阅读(2312)  评论(0)    收藏  举报

导航