uni-app解析及配置(小程序对应的转换)

485 阅读14分钟

在这里插入图片描述

变化

文件变化:

以前是.html文件,现在是.vue文件

网络模型变化:

以前网页大多是b/s,服务端代码混合在页面里;
现在是c/s,前后端分离,通过js api(类似ajax的uni.request)获取json数据,把数据绑定在界面上渲染。

文件内代码架构变化:

以前一个html大节点,里面有script和style节点;
现在template是一级节点,用于写tag组件,script和style是并列的一级节点,也就是有3个一级节点。vue单文件组件规范

<template>  
    <view>  
    必须有一个view,且只能有一个根view。写所有内容。  
    </view>  
</template>  
<script>  
    export default {  
    data(){
    
    }
 }  
</script>  

<style>  
</style>

外部文件引用方式变化:

以前通过script src、link href引入外部的js和css;
现是es6的写法,import引入外部的js模块(注意不是文件)或css js要require进来,变成了对象。
在hello uni-app的common目录有一个工具类util.js,可以在hello uni-app中搜索这个例子查看。

<script>  
var util = require('../../../common/util.js');  //require这个js模块  
var formatedPlayTime = util.formatTime(playTime); //调用js模块的方法  
</script>

而在这个util.js里,要把之前的function封装为对象的方法

function formatTime(time) {  
    return time;//这里没写逻辑  
}  

module.exports = {  
    formatTime: formatTime  
}

还有一些高级的用法

var dateUtils = require('../../../common/util.js').dateUtils; //直接使用js模块的属性。在hello uni-app有示例  
import * as echarts from '/components/echarts/echarts.simple.min.js'; //将js导入并重命名为echarts,然后使用echarts.来继续执行方法。在hello uni-app有示例

css外部文件导入

<style>  
    @import "./common/uni.css";  
</style>

全局样式,在根目录下的app.vue里写入,每个页面都会加载app.vue里的样式。

另外,vue支持组件导入,可以更方便的封装一个包括界面、js、样式的库。
如下是导入一个角标的组件库,在页面上显示一个abc并且右上角有个数字角标1

<template>  
    <view>  
        <uni-badge text="abc" :inverted="true"></uni-badge><!--3.使用组件-->  
    </view>  
</template>  
<script>  
    import uniBadge from "../../../components/uni-badge.vue";//1.导入组件  
    export default {  
        data() {  
            return {  

            }  
        },  
        components: {  
            uniBadge //2.注册组件  
        }  
    }  
</script>

如需要全局导入vue组件,每个页面都可以直接使用而不用引用和注册,在项目根目录下的main.js里处理。如下是hello uni-app里的例子。

//main.js  
import pageHead from './components/page-head.vue' //导入  
Vue.component('page-head', pageHead) //注册。注册后在每个vue的page页面里可以直接使用<page-head></page-head>组件。

组件/标签的变化:

除了改动外,新增了一批移动端常用的新组件

cover-view需要多强调几句,uni-app的非h5端的video、map、canvas、textarea是原生组件,层级高于其他组件。如需覆盖原生组件,比如在map上加个遮罩,则需要使用cover-view组件

除了内置组件,还有很多开源的扩展组件,把常用操作都进行封装,DCloud建立了插件市场收录这些扩展组件,详见插件市场

js的变化:
js的变化,分为运行环境变化、数据绑定模式变化、api变化3部分。

标准js语法和api都支持,比如if、for、settimeout、indexOf等。

但浏览器专用的window、document、navigator、location对象,包括cookie等存储,只有在浏览器中才有,app和小程序都不支持。

可能有些人以为js等于浏览器里的js。其实js是ECMAScript组织管理的,浏览器中的js是w3c组织基于js规范补充了window、document、navigator、location等专用对象。

在uni-app的各个端中,除了h5端,其他端的js都运行在一个独立的v8引擎下,不是在浏览器中,所以浏览器的对象无法使用。如果你做过小程序开发,对此应当很了解。

这意味着依赖document的很多HTML的库,比如jqurey无法使用。

当然app和小程序支持web-view组件,里面可以加载标准HTML,这种页面仍然支持浏览器专用对象window、document、navigator、location。

  • 以前的dom操作,改成vue的MVVM模式

现在前端趋势是去dom化,改用mvvm模式,更简洁的写法,大幅减少代码行数,同时差量渲染性能更好。
uni-app使用vue的数据绑定方式解决js和dom界面交互的问题。

如果你想改变某个dom元素的显示内容,比如一个view的显示文字:

以前是给view设id,然后js里通过选择器获取dom元素,进一步通过js进行赋值操作,修改dom元素的属性或值。 如下演示了一段代码,页面中有个显示的文字区和一个按钮,点击按钮后会修改文字区的值

<template>  
    <view>  
        <text>{{textvalue}}</text><!-- 这里演示了组件值的绑定 -->  
        <button :type="buttontype" @click="changetextvalue()">修改为789</button><!-- 这里演示了属性和事件的绑定 -->  
    </view>  
</template>  

<script>  
    export default {  
        data() {  
            return {  
                textvalue:"123",  
                buttontype:"primary"  
            };  
        },  
        onLoad() {  
            this.textvalue="456"//这里修改textvalue的值,其实123都来不及显示就变成了456  
        },  
        methods: {  
            changetextvalue() {  
                this.textvalue="789"//这里修改textvalue的值,页面自动刷新为789  
            }  
        }  
    }  
</script>

如果你学过小程序的数据绑定,但不了解vue,要注意:

  • 小程序的数据绑定参考了vue,但自己修改了一些。在uni-app中只支持标准的vue,不支持小程序的数据绑定语法
  • 小程序里的setData在uni-app里并不存在,因为vue是自动双向数据绑定的。直接通过赋值方式修改数据,如果数据绑定到界面上,界面会自动更新渲染
  • js api的变化

因为uni-app的api是参考小程序的,所以和浏览器的js api有很多不同,如

  • alert,confirm 改成 uni.showmodel
  • ajax 改成 uni.request
  • cookie、session 没有了,local.storage 改成 uni.storage

uni-app的js api还有很多,但基本就是小程序的api,把wx.xxx改为uni.xxx即可。详见
uni-app在不同的端,支持条件编译,无限制的使用各端独有的api,条件编译

css的变化:
标准的css基本都是支持的。

选择器有2个变化:*选择器不支持;元素选择器里没有body,改为了page。微信小程序即是如此。

单位方面,px无法动态适应不同宽度的屏幕,rem无法用于nvue/weex。如果想使用根据屏幕宽度自适应的单位,推荐使用rpx,全端支持。

uni-app推荐使用flex布局,并默认就是flex布局,这个布局思路和传统流式布局有点区别。但flex的有趣在于,不管是什么技术都支持这种排版,web、小程序/快应用、weex/rn、原生的iOS、Android开发,全都支持flex。它是通吃所有端的新一代布局方案。相关教程请自行百度学习。

uni-app的vue文件里支持所有web排版方式,不管是流式还是flex。但nvue里,只支持flex,因为它在app端是使用原生排版引擎渲染的。

注意背景图和字体文件尽量不要大于40k。会影响性能。如果非要大于40k,需放到服务器侧远程引用或base64后引入,不能放到本地作为独立文件引用。在小程序里,其实小于40k的文件在css里也无法引用,uni-app编译器在编译时自动做了处理,把小于40k的文件编译为base64方式了。

工程结构和页面管理

uni-app的工程结构有单独的要求,详见

每个可显示的页面,都必须在 pages.json中注册。如果你开发过小程序,那么pages.json类似app.json。如果你熟悉vue,这里没有vue的路由,都是在pages.json里管理。

vue工程的首页一般是index.html或default.html,是在web server里配的。而uni-app的首页,是在pages.json里配的,page节点下第一个页面就是首页。一般在/pages/xx的目录下。

app和小程序中,为了提升体验,页面提供了原生的导航栏和底部tabbar,注意这些配置是在pages.json中做,而不是在vue页面里创建,但点击事件的监听在显示的vue页面中做。

在vue中,以前的js事件监听概念改为了生命周期概念。uni-app生命周期

如果你熟悉小程序开发的话,对比变化如下

  • 原来app.json被一拆为二。页面管理,被挪入了uni-app的pages.json;非页面管理,挪入manifest.json
  • 原来的app.js和app.wxss被合并到了app.vue中

开发规范

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

目录结构

一个uni-app工程,默认包含如下目录及文件:

┌─components uni-app组件目录

│ └─comp-a.vue 可复用的a组件

├─hybrid 存放本地网页的目录,

├─platforms 存放各平台专用页面的目录,

├─pages 业务页面文件存放的目录

│ ├─index

│ │ └─index.vue index页面

│ └─list

│ └─list.vue list页面

├─static 存放应用引用静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此

├─wxcomponents 存放小程序组件的目录,

├─main.js Vue初始化入口文件

├─App.vue 应用配置,用来配置App全局样式以及监听

├─manifest.json 配置应用名称、appid、logo、版本等打包信息

└─pages.json 配置页面路由、导航条、选项卡等页面类信息

Tips:

  • static 下的 js 文件不会被编译,如果里有 es6 的代码,不经过转换直接运行,手机设备上会报错。
  • css、less/scss 等资源同样不要放在 static 目录下,建议这些公用的资源放在 common 目录下。 HbuilderX1.9.0+ 支持在根目录创建 ext.json sitemap.json 文件。

资源路径:
++模板内引入静态资源:
template内引入静态资源,如image、video等标签的src属性时,可以使用相对路径或者绝对路径
++js文件引入:
js文件或script标签内(包括renderjs等)引入js文件时,可以使用相对路径和绝对路径
++css引入静态资源:
css文件或style标签内引入css文件时(scss、less文件同理),只能使用相对路径
注意:自HBuilderX 2.6.6-alpha起支持绝对路径引入静态资源,旧版本不支持此方式

路由:
uni-app页面路由为框架统一管理,开发者需要在pages.json里配置每个路由页面的路径及页面样式。类似小程序在app.json中配置页面路由一样。所以 uni-app 的路由用法与 Vue Router 不同,如仍希望采用 Vue Router 方式管理路由,可在插件市场搜索 Vue-Router。

路由跳转:
uni-app 有两种页面路由跳转方式:使用navigator组件跳转、调用API跳转。

配置

pages.json
pages.json 文件用来对 uni-app 进行全局配置,决定页面文件的路径、窗口样式、原生的导航栏、底部的原生tabbar 等。

condition
启动模式配置,仅开发期间生效,用于模拟直达页面场景,如小程序转发后,用户点击所打开的页面。

属性说明:
在这里插入图片描述
list说明:
在这里插入图片描述
注意: 在 App 里真机运行可直接打开配置的页面,微信开发者工具里需要手动改变编译模式.
在这里插入图片描述

"condition": { //模式配置,仅开发期间生效
        "current": 0, //当前激活的模式(list 的索引项)
        "list": [
                {
                    "name": "index", //模式名称
                    "path" : "pages/index/index",
                    "query": "interval=4000&autoplay=false" //启动参数,在页面的onLoad函数里面得到。
                },
                {
                    "name": "about", //模式名称
                    "path" : "pages/about/about",
                    "query": "" //启动参数,在页面的onLoad函数里面得到。
                }
        ]
    }

manifest.json
manifest.json 文件是应用的配置文件,用于指定应用的名称、图标、权限等。

package.json
通过在package.json文件中增加uni-app扩展节点,可实现自定义条件编译平台(如钉钉小程序、微信服务号等平台)。

vue.config.js
vue.config.js 是一个可选的配置文件,如果项目的根目录中存在这个文件,那么它会被自动加载,一般用于配置 webpack 等编译选项,具体规范参考:vue.config.js

uni.scss
uni.scss文件的用途是为了方便整体控制应用的风格。比如按钮颜色、边框风格,uni.scss文件里预置了一批scss变量预置。
uni.scss是一个特殊文件,在代码中无需 import 这个文件即可在scss代码中使用这里的样式变量。uni-app的编译器在webpack配置中特殊处理了这个uni.scss,使得每个scss文件都被注入这个uni.scss,达到全局可用的效果。如果开发者想要less、stylus的全局使用,需要在vue.config.js中自行配置webpack策略。

App.vue
App.vue是uni-app的主组件,所有页面都是在App.vue下进行切换的,是页面入口文件。但App.vue本身不是页面,这里不能编写视图元素。

这个文件的作用包括:调用应用生命周期函数、配置全局样式、配置全局的存储globalData

main.js
main.js是uni-app的入口文件,主要作用是初始化vue实例、定义全局组件、使用需要的插件如vuex。

使用代码块直接创建组件模板

为提升开发效率,HBuilderX将 uni-app 常用代码封装成了以 u 开头的代码块,如在 template 标签内输入 ulist 回车,会自动生成如下代码:

<view class="uni-list">
    <view class="uni-list-cell">
        <view class="uni-list-cell-navigate uni-navigate-right" v-for="(item,index) in list" :key="index">
            {{item.value}}
        </view>
    </view>
</view>

代码块分为Tag代码块、JS代码块,如在 script 标签内输入 uShowToast 回车,会自动生成如下代码:

uni.showToast({
    title: '',
    mask: false
    duration: 1500
});

uni-app已支持代码块见下方列表:
Tag代码块:

  • uButton
  • uCheckbox
  • uGrid:宫格,需引用uni ui
  • uList:列表,需引用uni ui
  • uListMedia
  • uRadio
  • uSwiper
    几乎各种组件不管是内置组件还是uni ui的组件,均已封装为代码块,在HBuilderX的vue代码template区域中敲u,代码助手会提示所有可见列表。也可在HBuilderX菜单工具-代码块设置-vue代码块的左侧列表查阅所有。

除组件外,其他常用代码块包括:

  • viewfor:生成一段带有v-for循环结构的视图代码块
  • vbase:生成一段基本的vue代码结构

JS代码块:
uni api代码块:

  • uRequest
  • uGetLocation
  • uShowToast
  • uShowLoading
  • uHideLoading
  • uShowModal
  • uShowActionSheet
  • uNavigateTo
  • uNavigateBack
  • uRedirectTo
  • uStartPullDownRefresh
  • uStopPullDownRefresh
  • uLogin
  • uShare
  • uPay

vue js代码块:

  • vImport:导入文件
  • ed:export default
  • vData:输出 data( ) { return { } }
  • vMethod:输出 methods:{}
  • vComponents:输出 components: {}

其他常用js代码块:

  • iff:简单if
  • forr:for循环结构体
  • fori:for循环结构体并包含i
  • funn:函数
  • funa:匿名函数
  • rt:return true
  • clog:输出:“console.log()”
  • clogvar:增强的日志输出,可同时把变量的名字打印出来
  • varcw:输出:“var currentWebview = this.mp.page.mp.page.getAppWebview()”
  • ifios:iOS的平台判断
  • ifAndroid:Android的平台判断
    预置代码块不满足需求的话,可以自定义代码块,教程参考ask.dcloud.net.cn/article/359…

混合开发问题总结

uni-app和原生App混合开发问题:
首先务必确认uni-app和原生代码,谁是主谁是从的问题。

  • 如你的应用是uni-app开发,需要扩展一些原生能力,请参考插件市场右上角的原生插件开发教程。
  • 如你的App是原生开发的,部分功能栏目想通过uni-app实现,有2种方式
  • 在原生App里集成uni小程序sdk,参考文档
  • 如不想集成原生sdk,那就把uni-app代码发布成H5方式,在原生App里通过webview打开。
  • 如果应用是uni-app开发为主,只是想离线打包,那么不应该使用uni小程序sdk,请在HBuilderX的发行菜单里点击离线打包。
  • 另注意离线打包无法享受插件市场的付费原生插件,如有相关需求需自己进行原生插件开发,参考插件市场右上角的原生插件开发教程。

uni-app和原生小程序混合开发问题:
uni-app编译后的wxml代码没有可维护性,不便于整合到原生小程序里。如果想复用原生小程序的代码:

方式1:把原生小程序的代码变成组件,uni-app支持使用小程序wxml组件,参考
方式2:把原生小程序转换为uni-app源码,有各种转换工具,详见