第一个uni-app项目 ================= [TOC] 这部分的项目文件为:“01-UniAPP Hello World”和“02-UniAPP Tabs” # 目录结构 一个uni-app工程,默认包含如下目录及文件: ![](media/2019-03-03-23-45-10.png) 图 uni-app工程文件目录及说明 * components目录:组件文件存放目录 * pages目录:业务页面文件存放目录 * static目录:存放应用引用静态资源(如图片、视频等)的地方,注意:静态资源只能存放于此 * unpackage:编译的临时文件目录 * App.vue:应用配置,用来配置App全局样式以及监听应用的生命周期 * main.js:Vue初始化入口文件 * manifest.json:配置应用名称、appid、logo、版本等打包信息 * pages.json:配置页面路由、导航条、选项卡等页面类信息 # 页面文件规范 为了实现微信小程序、原生App的跨端兼容,综合考虑编译速度、运行性能等因素,uni-app 约定了如下开发规范: > 页面规范 - Vue 单文件组件 (SFC) 规范 .vue 文件是一个自定义的文件类型,用类 HTML 语法描述一个 Vue 组件。每个 .vue 文件包含三种类型的顶级语言块`<template>`、`<script>` 和` <style>`。 ``` <template> </template> <script> </script> <style> </style> ``` > template语言块用于编写页面的定义代码,script语言块编写页面的模块Javascript代码,style语言块用于编写样式定义脚本。 > vue-loader 会解析文件,提取每个语言块,如有必要会通过其它 loader 处理,最后将他们组装成一个 ES Module,它的默认导出是一个 Vue.js 组件选项的对象。 # UniAPP Hello World项目 我们先从一段简单的脚本开始,感受一下uni-app最核心的功能,uni-app是基于Vue.js的前端框架,支持大部分的 Vue.js特性。 > 这个示例展示了uni-app的核心功能:数据的双向绑定。属性title自动显示在屏幕正中间。 * [ ] 项目:01-UniAPP Hello World * [ ] 文件:pages/home/index.vue ## 第一个页面 ``` // pages/home/index.vue <template> <view class="content"> <text class="title">{{title}}</text> </view> </template> <script> export default { data() { return { title: 'Hello world' } } } </script> <style> .content { flex: 1; justify-content: center; align-items: center; } .title { font-size: 36upx; color: #8f8f94; } </style> ``` ## 添加新的页面 添加新的页面“pages/home/hello.vue”,这个示例展示了uni-app的核心功能:数据的双向绑定。通过计算属性message对属性name处理封装,在输入框内输入的内容会同步展示在页面的text标签内,如图所示。与传统的HTML不一样的是uni-app自定义了一系列的标签,最基本的view标签可以理解为HTML的div标签。 > 添加新的页面需要修改pages.json文件,参考下一节如何修改pages.json文件 首先定义data域的成员属性name ``` <script> export default { data() { return { name: 'Jack', } }, computed: { message() { return `Hello, ${this.name}`; } }, } </script> ``` 然后template节中添加一个输入框,将输入的内容通过v-model绑定到变量name。 ~~~ <input type="text" v-model="name" placeholder="你的名字" /> ~~~ 增加一个计算属性message,定义读取message返回一条消息 ~~~ computed: { message() { return `Hello, ${this.name}`; } }, ~~~ 这里的this指针指向vue实例本身。使用模版字符串构造复杂的字符串。 ~~~ `Hello,${this.name}` ~~~ 计算属性message与name属性密切相关,当name值改变的时候message自动更新。 ~~~ <template> <view class="content"> <view> <input type="text" v-model="name" placeholder="你的名字" /> </view> <view> <text>{{ message }}</text> </view> </view> </template> ~~~ * [ ] 项目:01-UniAPP Hello World * [ ] 文件:pages/home/hello.vue 图表 4‑2 第一个uni-app项目代码清单 ~~~ <template> <view class="content"> <view> <input type="text" v-model="name" placeholder="你的名字" /> </view> <view> <text>{{ message }}</text> </view> </view> </template> <script> export default { data() { return { name: 'Jack', } }, computed: { message() { return `Hello, ${this.name}`; } }, } </script> <style> .content { display: flex; flex: 1; flex-direction: column; justify-content: center; align-items: center; } input { border-bottom: 1px solid; } .name { font-size: 60px; font-weight: 600; } </style> ~~~ > uni-app修改了 Vue.js 的 runtime 和 compiler 实现,鉴于跨平台及App特殊需求,相比Web平台, Vue.js 在 uni-app 中使用时会存在一些差异。 ![](media/fa8ab49bad405328a7078f22b3a4498f.png) 图表 4‑3 微信开发者工具调试界面 ## 配置文件 ### 配置文件概述 pages.json 文件用来对 uni-app 进行全局配置(globalStyle)、决定页面文件的路径和窗口表现(pages)、设置底部 tab 的表现(tabBar)和条件启动(condition)。 图表 4‑4 配置文件pages.json 的配置项列表 | 选项 | 说明 | |-------------|----------------------------------------------------------------------------------------------| | globalStyle | 设置默认页面的窗口表现 | | pages | 设置页面路径及窗口表现,pages数组中第一项表示应用启动页,项目中出现的所有的页面必须在pages中列出 | | tabBar | 设置底部 tab 的表现 | | condition | 启动模式配置,仅开发阶段有效,方便给页面传递参数测试功能 | - 完整的配置说明,参考配置文件一章。 ### 全局配置 配置文件的globalStyle节用于设置整个APP的全局设置,如顶部当航栏的文字颜色、标背景色以及整个页面的背景色。 ~~~ "globalStyle": { "navigationBarTextStyle": "black", "navigationBarTitleText": "uni-app", "navigationBarBackgroundColor": "#FF0000", "backgroundColor": "#F8F8F8" }, ~~~ 这些配置如果某个页面想改变默认值,需要在特定页面的配置中重载,例如将pages/index/index页面的导航栏的背景色(navigationBarBackgroundColor)改成绿色(\#00FF00),需要修改style属性的值。 ~~~ { "pages": [ //pages数组中第一项表示应用启动页 { "path": "pages/index/index", "style": { "navigationBarTitleText": "首页", "navigationBarBackgroundColor": "#00FF00" } }, … ~~~ ### 模式配置 假设已经增加了3个页面 * pages/home/index * pages/home/hello * pages/home/about 根据约定pages数组中第一项表示应用启动页 ~~~ "pages": [{ "path": "pages/home/index", "style": { "navigationBarTitleText": "首页", "navigationBarBackgroundColor": "#00FF00" } }, { "path": "pages/home/hello", "style": { "navigationBarTitleText": "Hello!" } }, { "path": "pages/home/about", //重载全局设置 "style": { "navigationBarTextStyle": "black", "navigationBarTitleText": "About", "navigationBarBackgroundColor": "#F00", "backgroundColor": "#F8F8F8" } } ], ~~~ 那么,在开发阶段,如果要直接启动about页面,就必须将about设置为第一项,这样改动起来非常麻烦,因此可以通过配置编译模式赖解决,condition节的list数组存放多个配置的列表,索引从0开始,current属性用于设置当前启用的模式。 ~~~ "condition": { //模式配置,仅开发期间生效 "current": 2, //当前激活的模式(list 的索引项,从0开始) "list": [{ "name": "首页", //模式名称 "path": "pages/home/index", //启动页面,必选 "query": "" //启动参数,在页面的onLoad函数里面得到。 }, { "name": "Hello", //模式名称 "path": "pages/home/hello", //启动页面,必选 "query": "" //启动参数,在页面的onLoad函数里面得到。 }, { "name": "关于", //模式名称 "path": "pages/home/about", //启动页面,必选 "query": "uid=100&t=1535987051" //启动参数,在页面的onLoad函数里面得到。 } ] } ~~~ 如果页面有参数,可以在onLoad事件中解析。 ~~~ onLoad: function (e) { console.log(JSON.stringify(e)); } ~~~ 打印的结果如下: ~~~ {"uid":"100","t":"1535987051"} ~~~ > 查询字符串:问号后面所跟的参数“uid=100&t=1535987051”就是查询字符串,字符串以键值对的形式出现,如果有多个参数,用"&"隔开就行了。 > 例如:"about?uid=100&t=1535987051"表示带两个参数uid和t,他们的值分别为100和1535987051。参数的名称和值含有特殊字符必须进行url转义。 **注意:** 在5+app里真机运行可直接打开配置的页面,微信开发者工具里需要手动改变编译模式,如下图: ![](media/3bb0237feddec9da38de5325190bf807.png) ### 单页程序配置示例 图表 4‑5 pages.json示例文件 ~~~ { //pages数组中第一项表示应用启动页 //参考:https://uniapp.dcloud.io/collocation/pages "pages": [{ "path": "pages/home/index", "style": { "navigationBarTitleText": "首页", "navigationBarBackgroundColor": "#00FF00" } }, { "path": "pages/home/hello", "style": { "navigationBarTitleText": "Hello!" } }, { "path": "pages/home/about", //重载全局设置 "style": { "navigationBarTextStyle": "black", "navigationBarTitleText": "About", "navigationBarBackgroundColor": "#F00", "backgroundColor": "#F8F8F8" } } ], "globalStyle": { //全局设置 "navigationBarTextStyle": "black", //导航栏文本颜色 "navigationBarTitleText": "uni-app", //导航栏文本默认文字 "navigationBarBackgroundColor": "#F8F8F8", //导航栏背景颜色 "backgroundColor": "#F8F8F8" //页面的背景色 }, "condition": { //模式配置,仅开发期间生效 "current": 2, //当前激活的模式(list 的索引项,从0开始) "list": [{ "name": "首页", //模式名称 "path": "pages/home/index", //启动页面,必选 "query": "" //启动参数,在页面的onLoad函数里面得到。 }, { "name": "Hello", //模式名称 "path": "pages/home/hello", //启动页面,必选 "query": "" //启动参数,在页面的onLoad函数里面得到。 }, { "name": "关于", //模式名称 "path": "pages/home/about", //启动页面,必选 "query": "uid=100&t=1535987051" //启动参数,在页面的onLoad函数里面得到。 } ] } } ~~~ ### 多页应用配置 一般一个应用不止一个页面,我们习惯如图所示,在主程序页面按照多页的方式来组织, ![](media/aad199da214359257c11105175cf4101.png) 假设已经增加了两个页面 * [ ] pages/home/index * [ ] pages/home/about 我们希望底部通过Tab的形式切换这两个页面。 文件pages/home/index.vue页面水平和垂直居中显示一行文字'Hello'。 pages/home/about页面类似,在页面上简单的显示一行文字。 要增加多页功能,需要在pages.json文件中增加对tabs的配置,例如 ~~~ "tabBar": { "color": "#cdcdcd", "selectedColor": "#1296db", "borderStyle": "black", "backgroundColor": "#ffffff", "list": [{ "pagePath": "pages/home/index", "iconPath": "static/tabbar/home.png", "selectedIconPath": "static/tabbar/homeHL.png", "text": "首页" }, { "pagePath": "pages/home/about", "iconPath": "static/tabbar/my.png", "selectedIconPath": "static/tabbar/myHL.png", "text": "关于" }] }, ~~~ uni-app每个页面支持使用原生title,首页支持使用原生底部tab,这些是要在pages.json里配置,这些并不是vue页面的一部分。根据微信小程序的规范,底部的Tab最多有5个,最少2个。 ### 多页程序配置的示例 项目:02-UniAPP Tabs ~~~ { //pages数组中第一项表示应用启动页 //参考:https://uniapp.dcloud.io/collocation/pages "pages": [{ "path": "pages/home/index", "style": { "navigationBarTitleText": "Hello world" } }, { "path": "pages/home/about", //重载全局设置 "style": { "navigationBarTextStyle": "black", "navigationBarTitleText": "About", "navigationBarBackgroundColor": "#F00", "backgroundColor": "#F8F8F8" } } ], "globalStyle": { //全局设置 "navigationBarTextStyle": "black", //导航栏文本颜色 "navigationBarTitleText": "uni-app", //导航栏文本默认文字 "navigationBarBackgroundColor": "#F8F8F8", //导航栏背景颜色 "backgroundColor": "#F8F8F8" //页面的背景色 }, "tabBar": { "color": "#cdcdcd", "selectedColor": "#1296db", "borderStyle": "black", "backgroundColor": "#ffffff", "list": [{ "pagePath": "pages/home/index", "iconPath": "static/tabbar/home.png", "selectedIconPath": "static/tabbar/homeHL.png", "text": "首页" }, { "pagePath": "pages/home/about", "iconPath": "static/tabbar/my.png", "selectedIconPath": "static/tabbar/myHL.png", "text": "关于" }] }, "condition": { //模式配置,仅开发期间生效 "current": 0, //当前激活的模式(list 的索引项,从0开始) "list": [{ "name": "首页", //模式名称 "path": "pages/home/index", //启动页面,必选 "query": "" //启动参数,在页面的onLoad函数里面得到。 }, { "name": "关于", //模式名称 "path": "pages/home/about", //启动页面,必选 "query": "" //启动参数,在页面的onLoad函数里面得到。 } ] } } ~~~ > 以后的项目都是基于Tabs多页导航模式,以本案例为基础增加功能页面。