笔记根据B站Uni-App从入门到实战-黑马程序员杭州校区出品视频教程整理
相关素材:https://pan.baidu.com/s/1Dkj5iuGRG6j2HzK_8MDxFA 提取码:7vm2,搬运来的链接,大家自取
案例的接口文档:https://www.showdoc.com.cn/128719739414963?page_id=2513235043485226
颜色对照表:https://destiny001.gitee.io/color/
p1 uniapp简介
uni-app上手简单,可快速开发小程序、h5、安卓、ios应用
。学习本课程需有vue基础方可继续,当然了有想学习小程序的,也建议学习本课程,学会uni-app之后,原生小程序也可快速上手。
p2 uniapp环境搭建
下载HBuilderX即可:https://www.dcloud.io/hbuilderx.html
创建uniapp项目
运行到浏览器
运行到微信小程序
注意:需要先在微信小程序中 设置-安全设置 开启端口
否则启动不了。
运行到安卓手机
略
p3 uniapp项目结构和开发规范
项目结构
├─pages 业务页面文件存放的目录
│ ├─index
│ │ └─index.vue index页面
│ └─list
│ └─list.vue list页面
├─static 存放应用引用的本地静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此
├─unpackage 非工程代码,一般存放运行或发行的编译结果
├─main.js Vue初始化入口文件
├─App.vue 应用配置,用来配置App全局样式以及监听 应用生命周期
├─manifest.json 配置应用名称、appid、logo、版本等打包信息,详见
├─pages.json 配置页面路由、导航条、选项卡等页面类信息,详见
└─uni.scss 这里是uni-app内置的常用样式变量
开发规范
为了实现多端兼容,综合考虑编译速度、运行性能等因素,uni-app
约定了如下开发规范:
- 页面文件遵循 Vue 单文件组件 (SFC) 规范(opens new window)
- 组件标签靠近小程序规范,详见uni-app 组件规范
- 接口能力(JS API)靠近微信小程序规范,但需将前缀
wx
替换为uni
,详见uni-app接口规范 - 数据绑定及事件处理同
Vue.js
规范,同时补充了App及页面的生命周期 - 为兼容多端运行,建议使用
flex布局
进行开发
总结:就是小程序的语法和vue的语法结合
P4 globalStyle全局配置
对应page.json
文件中globalStyle
节点
属性 | 类型 | 默认值 | 描述 | 平台差异说明 |
---|---|---|---|---|
navigationBarBackgroundColor | HexColor | #F7F7F7 | 导航栏背景颜色(同状态栏背景色) | APP与H5为#F7F7F7,小程序平台请参考相应小程序文档 |
navigationBarTextStyle | String | white | 导航栏标题颜色及状态栏前景颜色,仅支持 black/white | |
navigationBarTitleText | String | 导航栏标题文字内容 | ||
navigationStyle | String | default | 导航栏样式,仅支持 default/custom。custom即取消默认的原生导航栏,需看使用注意 | 微信小程序 7.0+、百度小程序、H5、App(2.0.3+) |
backgroundColor | HexColor | #ffffff | 下拉显示出来的窗口的背景色 | 微信小程序 |
backgroundTextStyle | String | dark | 下拉 loading 的样式,仅支持 dark / light | 微信小程序 |
enablePullDownRefresh | Boolean | false | 是否开启下拉刷新,详见页面生命周期。 | |
onReachBottomDistance | Number | 50 | 页面上拉触底事件触发时距页面底部距离,单位只支持px,详见页面生命周期 |
更多属性配置可以参考文档:全局配置文档
P5 创建和配置页面
第一步:新建文件夹以及创建vue文件
message.vue的内容如下:
<template>
<view>message页面</view>
</template>
<script>
</script>
<style>
</style>
第二步:在page.json文件中进行配置
注意:pages数组中第一项表示应用启动页
测试就可以看到页面了
参考:页面样式配置文档
p6-p7 tabBar 配置
属性说明:
属性 | 类型 | 必填 | 默认值 | 描述 | 平台差异说明 |
---|---|---|---|---|---|
color | HexColor | 是 | tab 上的文字默认颜色 | ||
selectedColor | HexColor | 是 | tab 上的文字选中时的颜色 | ||
backgroundColor | HexColor | 是 | tab 的背景色 | ||
borderStyle | String | 否 | black | tabbar 上边框的颜色,可选值 black/white | App 2.3.4+ 支持其他颜色值、H5 3.0.0+ |
blurEffect | String | 否 | none | iOS 高斯模糊效果,可选值 dark/extralight/light/none(参考:使用说明 (opens new window)) | App 2.4.0+ 支持、H5 3.0.0+(只有最新版浏览器才支持) |
list | Array | 是 | tab 的列表,详见 list 属性说明,最少2个、最多5个 tab | ||
position | String | 否 | bottom | 可选值 bottom、top | top 值仅微信小程序支持 |
第一步:新增contact页面,参考p5。建完之后别忘了在pages.json中的pages节点下配置路径
第二步:将图片拷贝的静态文件夹,有选中的图片和不选中的图片。可以用阿里图标库生成
第三步:page.json中配置一下tabbar
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#3cc51f",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "static/image/home.png",
"selectedIconPath": "static/image/home-active.png",
"text": "主页"
},
{
"pagePath": "pages/message/message",
"iconPath": "static/image/message.png",
"selectedIconPath": "static/image/message-active.png",
"text": "信息"
},
{
"pagePath": "pages/contact/contact",
"iconPath": "static/image/contact.png",
"selectedIconPath": "static/image/contact-active.png",
"text": "我们"
}
]
}
然后在界面就可以看到效果了,点击之后可以切换到对应的界面
p8 condition
启动模式配置,仅开发期间生效,用于模拟直达页面的场景,如:小程序转发后,用户点击所打开的页面。
属性说明:
属性 | 类型 | 是否必填 | 描述 |
---|---|---|---|
current | Number | 是 | 当前激活的模式,list节点的索引值 |
list | Array | 是 | 启动模式列表 |
list说明:
属性 | 类型 | 是否必填 | 描述 |
---|---|---|---|
name | String | 是 | 启动模式名称 |
path | String | 是 | 启动页面路径 |
query | String | 否 | 启动参数,可在页面的 onLoad 函数里获得 |
注意: 在 App 里真机运行可直接打开配置的页面,微信开发者工具里需要手动改变编译模式,如下图:
第一步:新增details页面
第二步:在pages.json中添加condition节点,配置如下
"condition" : { //模式配置,仅开发期间生效
"current": 0, //当前激活的模式(list 的索引项)
"list": [
{
"name": "详情页", //模式名称
"path": "pages/details/details", //启动页面,必选
"query": "id=10" //启动参数,在页面的onLoad函数里面得到
}
]
}
p9 text组件
文本组件。
用于包裹文本内容。
属性说明
属性名 | 类型 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|
selectable | Boolean | false | 文本是否可选 | App、H5、快手小程序 |
user-select | Boolean | false | 文本是否可选 | 微信小程序 |
space | String | 显示连续空格 | App、H5、微信小程序 | |
decode | Boolean | false | 是否解码 | App、H5、微信小程序 |
space 值说明
值 | 说明 |
---|---|
ensp | 中文字符空格一半大小 |
emsp | 中文字符空格大小 |
nbsp | 根据字体设置的空格大小 |
修改detail.vue
<template>
<view>
<view><text>不可选文字(默认)</text></view>
<view><text selectable>可选文字</text></view>
<view><text>空格隔空 你搞个1</text></view>
<view><text space="ensp">中文字符 空格一半大小</text></view>
<view><text space="emsp">中文字符 空格大小</text></view>
<view><text space="nbsp" style="font-size: 16px;">根据字体 设置的空格大小</text></view>
<view><text>解码 & > </text></view>
</view>
</template>
<script>
</script>
<style>
</style>
测试就可以看到对应的效果
p10 view组件
视图容器。
它类似于传统html中的div,用于包裹各种元素内容。
如果使用nvue (opens new window),则需注意,包裹文字应该使用<text>
组件。
属性说明
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
hover-class | String | none | 指定按下去的样式类。当 hover-class=”none” 时,没有点击态效果 |
hover-stop-propagation | Boolean | false | 指定是否阻止本节点的祖先节点出现点击态,App、H5、支付宝小程序、百度小程序不支持(支付宝小程序、百度小程序文档中都有此属性,实测未支持) |
hover-start-time | Number | 50 | 按住后多久出现点击态,单位毫秒 |
hover-stay-time | Number | 400 | 手指松开后点击态保留时间,单位毫秒 |
在details.vue文件中加入下面的测试代码
<template>
<view>
<view class="box" hover-class="box-active" :hover-start-time="2000" :hover-stay-time="2000">
<view class="childbox" hover-class="childbox-active" hover-stop-propagation></view>
</view>
</view>
</template>
<style>
.box{
width: 150px;
height: 150px;
background: green;
}
.box-active{
background: deeppink;
}
.childbox{
width: 50px;
height: 50px;
background: greenyellow;
}
.childbox-active{
background: deepskyblue;
}
</style>
p11 button组件
按钮组件
属性说明
属性名 | 类型 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|
size | String | default | 按钮的大小 | |
type | String | default | 按钮的样式类型 | |
plain | Boolean | false | 按钮是否镂空,背景色透明 | |
disabled | Boolean | false | 是否禁用 | |
loading | Boolean | false | 名称前是否带 loading 图标 | H5、App(App-nvue 平台,在 ios 上为雪花,Android上为圆圈) |
更多属性可以看button组件文档
在details.vue文件中加入下面的测试代码即可看到效果
<button>默认按钮</button>
<button size="mini">mini按钮</button>
<button type="primary">type=primary按钮</button>
<button type="primary" plain>type=primary的镂空按钮</button>
<button type="primary" disabled>type=primary的禁用按钮</button>
<button type="primary" loading>type=primary的loading按钮</button>
p12 image组件
图片组件
属性名 | 类型 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|
src | String | 图片资源地址 | ||
mode | String | ‘scaleToFill’ | 图片裁剪、缩放的模式 |
Tips
<image>
组件默认宽度 300px、高度 225px;app-nvue平台,暂时默认为屏幕宽度
src
仅支持相对路径、绝对路径,支持 base64 码;- 页面结构复杂,css样式太多的情况,使用 image 可能导致样式生效较慢,出现 “闪一下” 的情况,此时设置
image{will-change: transform}
,可优化此问题。 - 自定义组件里面使用
<image>
时,若src
使用相对路径可能出现路径查找失败的情况,故建议使用绝对路径。
mode 有效值:
mode 有 14 种模式,其中 5 种是缩放模式,9 种是裁剪模式。
模式 | 值 | 说明 |
---|---|---|
缩放 | scaleToFill | 不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素 |
缩放 | aspectFit | 保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。 |
缩放 | aspectFill | 保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。 |
更多参考图片组件文档
在details.vue中加入下面的代码
<image src="https://heliufang.gitee.io/2022/03/27/1513842928408203264/images/image-20220319113815361.png"></image>
<image src="https://heliufang.gitee.io/2022/03/27/1513842928408203264/images/image-20220319113815361.png" mode="aspectFit"></image>
<image src="https://heliufang.gitee.io/2022/03/27/1513842928408203264/images/image-20220319113815361.png" mode="aspectFill"></image>
p13 uniapp样式-字体图片-sass
css单位
uni-app
支持的通用 css 单位包括 px、rpx
- px 即屏幕像素
- rpx 即响应式 px,一种根据屏幕宽度自适应的动态单位。以 750 宽的屏幕为基准,750rpx 恰好为屏幕宽度。屏幕变宽,rpx 实际显示效果会等比放大,但在 App(vue2 不含 nvue) 端和 H5(vue2) 端屏幕宽度达到 960px 时,默认将按照 375px 的屏幕宽度进行计算,具体配置参考:rpx 计算配置 。
举例说明:
- 若设计稿宽度为 750px,元素 A 在设计稿上的宽度为 100px,那么元素 A 在
uni-app
里面的宽度应该设为:750 * 100 / 750
,结果为:100rpx。- 若设计稿宽度为 640px,元素 A 在设计稿上的宽度为 100px,那么元素 A 在
uni-app
里面的宽度应该设为:750 * 100 / 640
,结果为:117rpx。
vue 页面支持下面这些普通 H5 单位,但在 nvue 里不支持:
- rem 根字体大小可以通过 page-meta 配置
- vh viewpoint height,视窗高度,1vh 等于视窗高度的 1%
- vw viewpoint width,视窗宽度,1vw 等于视窗宽度的 1%
新建uniapp-style.vue页面
假设设计稿的宽度为375px ,盒子的宽度为100px。那么根据公式 750*100/375=200rpx
<template>
<view>
<view class="box">
<text>uniapp</text>
</view>
</view>
</template>
<script>
</script>
<style>
.box{
width: 200rpx;
height: 200rpx;
background: red;
font-size: 32rpx;
}
</style>
打开页面调试工具发现切换到宽度为375px的设备,发现盒子的像素确实是100px
样式导入
使用@import
语句可以导入外联样式表,@import
后跟需要导入的外联样式表的相对路径,用;
表示语句结束。
在uniapp-style.vue页面的同级目录下新建a.css文件,文件内容如下
.box{
border: 1rpx solid;
}
然后再uniapp-style.vue页面引入
<style>
@import url(./a.css);
.box{
width: 200rpx;
height: 200rpx;
background: red;
font-size: 32rpx;
}
</style>
测试发现给盒子加上边框了。
选择器
目前支持的选择器有:
选择器 | 样例 | 样例描述 |
---|---|---|
.class | .intro | 选择所有拥有 class=”intro” 的组件 |
#id | #firstname | 选择拥有 id=”firstname” 的组件 |
element | view | 选择所有 view 组件 |
element, element | view, checkbox | 选择所有文档的 view 组件和所有的 checkbox 组件 |
::after | view::after | 在 view 组件后边插入内容,仅 vue 页面生效 |
::before | view::before | 在 view 组件前边插入内容,仅 vue 页面生效 |
注意:
- 在
uni-app
中不能使用*
选择器。 - 微信小程序自定义组件中仅支持 class 选择器
page
相当于body
节点,例如:
<!-- 设置页面背景颜色,使用 scoped 会导致失效 -- >
page {
background-color: #ccc;
}
全局样式与局部样式
定义在 App.vue 中的样式为全局样式,作用于每一个页面。在 pages 目录下 的 vue 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 App.vue 中相同的选择器。
注意:
- App.vue 中通过
@import
语句可以导入外联样式,一样作用于每一个页面。 - nvue 页面暂不支持全局样式
使用scss
在页面加上 lang=”scss” 会自动安装scss插件
<style lang="scss">
@import url(./a.css);
.box{
width: 200rpx;
height: 200rpx;
background: red;
text{
font-size: 16rpx;
color: aqua;
}
}
</style>
字体图标
uni-app
支持使用字体图标,使用方式与普通 web
项目相同,需要注意以下几点:
- 支持 base64 格式字体图标。
- 支持网络路径字体图标。
- 小程序不支持在 css 中使用本地文件,包括本地的背景图和字体文件。需以 base64 方式方可使用。
- 网络路径必须加协议头
https
。 - 从 http://www.iconfont.cn (opens new window)上拷贝的代码,默认是没加协议头的。
- 从 http://www.iconfont.cn (opens new window)上下载的字体文件,都是同名字体(字体名都叫 iconfont,安装字体文件时可以看到),在 nvue 内使用时需要注意,此字体名重复可能会显示不正常,可以使用工具修改。
- 使用本地路径图标字体需注意:
- 为方便开发者,在字体文件小于 40kb 时,
uni-app
会自动将其转化为 base64 格式; - 字体文件大于等于 40kb,仍转换为 base64 方式使用的话可能有性能问题,如开发者必须使用,则需自己将其转换为 base64 格式使用,或将其挪到服务器上,从网络地址引用;
- 字体文件的引用路径推荐使用以 ~@ 开头的绝对路径。
- 为方便开发者,在字体文件小于 40kb 时,
@font-face {
font-family: test1-icon;
src: url('~@/static/iconfont.ttf');
}
第一步:将字体图标文件拷贝到static文件夹下
第二步:修改iconfont.css路径,都加上~@路径
第三步:使用
<text class="iconfont icon-shipin"></text>
p14 -16数据绑定和事件绑定
和vue一模一样 uniapp官网上的vue文档
新建一个home.vue文件用来测试
<template>
<view>
<view>数据绑定学习(和vue一样)</view>
<!-- 插值表达式和三目运算符 -->
<view>{{msg}}</view>
<view>{{"1"+"uniapp"}}</view>
<view>{{1+1}}</view>
<view>{{flag?'真的':'假的'}}</view>
<!-- v-bind绑定数据 -->
<image :src="imgurl"></image>
<!-- v-for循环 -->
<view v-for="(item,index) in arr" :key="item.id">
序号:{{index}},ID:{{item.id}},姓名:{{item.name}},年龄:{{item.age}}
</view>
<button @click="clickHandle1">注册1</button>
<button type="primary" @click="clickHandle2(10,$event)">注册2</button>
</view>
</template>
<script>
export default{
data(){
return {
msg: '你好',
flag: false,
imgurl: 'https://heliufang.gitee.io/2022/03/27/1513842928408203264/images/image-20220319113815361.png',
arr: [
{id: 1,name: '赵云',age: 18},
{id: 2,name: '马超',age: 28},
{id: 3,name: '关羽',age: 38},
]
}
},
methods: {
clickHandle1(e){//不传参数获取事件对象
console.log(e)
},
clickHandle2(num,e){//传参
console.log(num,e)
}
}
}
</script>
<style>
</style>
p17 应用和页面的生命周期函数
应用的生命周期函数–App.vue文件中
<script>
export default {
onLaunch: function() {
console.log('应用加载完毕-只执行一次')
},
onShow: function() {
console.log('应用显示')
},
onHide: function() {
console.log('应用隐藏')
}
}
</script>
<style>
@import url(./static/fonts/iconfont.css);
/*每个页面公共css */
</style>
页面的生命周期函数–每个页面中 页面生命周期文档
函数名 | 说明 |
---|---|
onLoad | 监听页面加载,其参数为上个页面传递的数据,参数类型为 Object(用于页面传参),参考示例 |
onShow | 监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面 |
onReady | 监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发 |
onHide | 监听页面隐藏 |
例如在message.vue页面中加上页面的生命周期函数
<template>
<view>message页面</view>
</template>
<script>
export default{
onLoad(obj){
//页面加载完毕,obj是上个页面传递的数据
console.log('页面加载完毕',obj)
},
onShow(){
console.log('页面显示')
},
onReady(){
console.log('页面初次渲染完毕')
},
onHide(){
console.log('页面隐藏,通过切换tabbar可以看到我')
}
}
</script>
p18 下拉刷新
在 js 中定义 onPullDownRefresh 处理函数(和onLoad等生命周期函数同级),监听该页面用户下拉刷新事件。
- 需要在
pages.json
里,找到的当前页面的pages节点,并在style
选项中开启enablePullDownRefresh
。
- 当处理完数据刷新后,
uni.stopPullDownRefresh
可以停止当前页面的下拉刷新。
message.vue代码
<template>
<view>
message页面
<view v-for="(item) in arr" :key="item.id">{{item}}</view>
<button type="primary" @click="refreshArr">按钮触发下拉刷新</button>
</view>
</template>
<script>
export default{
data(){
return {
arr: ['java','前端','UI','测试']
}
},
methods: {
refreshArr(){
uni.startPullDownRefresh()
}
},
onPullDownRefresh(){
setTimeout(() => {
this.arr = ['UI','测试','java','前端']
uni.stopPullDownRefresh() //关闭下拉刷新
},2000)
},
}
</script>
p19 上拉(触底)加载
页面的可以配置触底的距离,也就是距离底部多少距离触发,默认是50
页面生命周期中有个onReachBottom方法,用来监听触底。
<template>
<view>
message页面
<view class="item-class" v-for="(item) in arr" :key="item.id">{{item}}</view>
<button type="primary" @click="refreshArr">按钮触发下拉刷新</button>
</view>
</template>
<script>
export default{
data(){
return {
arr: ['java','前端','UI','测试']
}
},
methods: {
refreshArr(){
uni.startPullDownRefresh()
}
},
onPullDownRefresh(){
setTimeout(() => {
this.arr = ['UI','测试','java','前端']
uni.stopPullDownRefresh() //关闭下拉刷新
},2000)
},
onReachBottom(){//触底的方法
//es6的语法扩展数组
this.arr = [...this.arr,...['UI','测试','java','前端']]
console.log('触底',this.arr)
}
}
</script>
<style>
.item-class{
height: 200px;
}
</style>
p20 发送get请求
搭建本地的node服务
第一步,根据dtcmsdb4.sql文件来恢复数据库
第二步, npm i 安装依赖
第三步,node ./src/app.js 来启动服务,注意:默认数据库账号密码都是root,如果本地不是请修改好
第四步,浏览器输入 http://localhost:8082/api/getlunbo 来访问接口 出现下面这样表示成功
uniapp中通过uni.request(OBJECT) 发起网络请求。uni.request文档
<template>
<view>
<button type="primary" @click="getlunbo">发起请求</button>
</view>
</template>
<script>
export default{
methods: {
getlunbo(){
uni.request({
url: 'http://localhost:8082/api/getlunbo',
success(resp){
console.log(resp)
}
})
}
}
}
</script>
p21 数据缓存
uni.setStorage
将数据存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容,这是一个异步接口。
uni.setStorageSync
将 data 存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容,这是一个同步接口。
uni.getStorage
从本地缓存中异步获取指定 key 对应的内容。
uni.getStorageSync
从本地缓存中同步获取指定 key 对应的内容。
uni.removeStorage
从本地缓存中异步移除指定 key。
uni.removeStorageSync
从本地缓存中同步移除指定 key。
测试代码如下
<template>
<view>
<button type="primary" @click="saveData">保存数据</button>
<button type="primary" @click="getData">获取数据</button>
<button type="primary" @click="removeData">删除数据</button>
</view>
</template>
<script>
export default{
methods: {
saveData(){
// uni.setStorage({
// key: 'id',
// data: 80,
// success(){
// console.log('保存成功')
// }
// })
uni.setStorageSync('id',100)
},
getData(){
// uni.getStorage({
// key: 'id',
// success(resp){
// console.log('获取成功:',resp.data)
// }
// })
let resp = uni.getStorageSync('id')
console.log('获取成功:',resp)
},
removeData(){
// uni.removeStorage({
// key: 'id',
// success() {
// console.log('删除成功')
// }
// })
uni.removeStorageSync('id')
}
}
}
</script>
p22 图片的上传和预览
- uni.chooseImage(OBJECT)
从本地相册选择图片或使用相机拍照。
App端如需要更丰富的相机拍照API(如直接调用前置摄像头),参考plus.camera
- uni.previewImage(OBJECT)
预览图片。
代码如下
<template>
<view>
<button type="warn" @click="uploadImg">上传图片</button>
<image v-for="item in imgList" :src="item" @click="previewImg(item)"></image>
</view>
</template>
<script>
export default{
data(){
return{
imgList: []
}
},
methods: {
uploadImg(){
uni.chooseImage({
success: res => {
this.imgList = res.tempFilePaths
//console.log(res)
}
})
},
previewImg(current){
console.log('预览图片')
uni.previewImage({
current,//current 为当前显示图片的链接/索引值
urls: this.imgList //需要预览的图片链接列表
})
}
}
}
</script>
p23 条件编译跨端兼容
条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。
条件编译写法 | 说明 |
---|---|
#ifdef APP-PLUS 需条件编译的代码 #endif | 仅出现在 App 平台下的代码 |
#ifndef H5 需条件编译的代码 #endif | 除了 H5 平台,其它平台均存在的代码 |
#ifdef H5 || MP-WEIXIN 需条件编译的代码 #endif | 在 H5 平台或微信小程序平台存在的代码(这里只有||,不可能出现&&,因为没有交集) |
HbuilderX中输入if关键字会有代码提示
<template>
<view>
<!-- #ifdef H5 -->
<view>h5显示</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view>微信小程序中显示</view>
<!-- #endif -->
</view>
</template>
<script>
export default{
onLoad() {
// #ifdef H5
console.log('h5打印')
// #endif
// #ifdef MP-WEIXIN
console.log('wx打印')
// #endif
}
}
</script>
<style>
view{
/* #ifdef H5 */
color: red;
/* #endif */
/* #ifdef MP-WEIXIN */
color: deepskyblue;
/* #endif */
}
</style>
p24 导航
navigator组件导航
页面跳转。 navigator文档
该组件类似HTML中的<a>
组件,但只能跳转本地页面。目标页面必须在pages.json中注册。
该组件的功能有API方式,另见:https://uniapp.dcloud.io/api/router?id=navigateto(opens new window)
属性说明
属性名 | 类型 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|
url | String | 应用内的跳转链接,值为相对路径或绝对路径,如:”../first/first”,”/pages/first/first”,注意不能加 .vue 后缀 | ||
open-type | String | navigate | 跳转方式 |
open-type 有效值
值 | 说明 | 备注 |
---|---|---|
navigate | 对应 uni.navigateTo | 保留当前页面,跳转到应用内的某个页面。带返回按钮 |
redirect | 对应 uni.redirectTo | 关闭当前页面,跳转到应用内的某个页面。不带返回按钮 |
switchTab | 对应 uni.switchTab | 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。 |
编程式导航
uni.navigateTo
uni.redirectTo
uni.switchTab
代码如下:
<template>
<view>
<navigator url="/pages/details/details">跳转到详情页(带返回按钮)</navigator>
<navigator url="/pages/details/details" open-type="redirect">跳转到详情页redirect(不带返回按钮)</navigator>
<navigator url="/pages/message/message" open-type="switchTab">到tabbar的消息页</navigator>
<!-- 编程式导航 和上面三个是对应的 -->
<button type="primary" @click="routerNavigate">跳转到详情页(带返回按钮)</button>
<button type="primary" @click="routerRedirect">跳转到详情页(不带返回按钮)</button>
<button type="primary" @click="routerSwichtab">到tabbar的消息页</button>
</view>
</template>
<script>
export default{
onUnload() {
console.log('页面卸载')
},
methods: {
routerNavigate(){
uni.navigateTo({
url: '/pages/details/details'
})
},
routerRedirect(){
uni.redirectTo({
url: '/pages/details/details'
})
},
routerSwichtab(){
uni.switchTab({
url: '/pages/message/message'
})
}
}
}
</script>
p25 组件的创建和组件生命周期函数
和vue的组件创建以及生命周期是一样的。
组件的创建和使用
新建components目录,并在目录下新建test组件
test组件的内容如下
<template>
<view>
test组件
</view>
</template>
<script>
export default {
name:"test"
}
</script>
然后在index.vue中应用test组件
<template>
<view class="content">
<test></test>
</view>
</template>
<script>
import test from '../../components/test.vue' //导入test组件
export default {
components:{
test//注册test组件
}
}
</script>
组件的生命周期函数
index.vue
<template>
<view class="content">
<test v-if="flag"></test>
<button type="primary" @click="toggleTest">切换test组件</button>
</view>
</template>
<script>
import test from '../../components/test.vue'
export default {
components:{
test
},
data(){
return{
flag: true
}
},
methods: {
toggleTest(){
this.flag = !this.flag
}
}
}
</script>
test.vue组件
<template>
<view id="mout">
test组件
</view>
</template>
<script>
export default {
name:"test",
data() {
return {
num: 10
};
},
beforeCreate() {
console.log('beforeCreate...',this.num)
},
created() {
console.log('created',this.num) //页面渲染完毕
},
beforeMount() {
console.log('beforeMount',document.getElementById('mout'))
},
mounted() {
console.log('mounted',document.getElementById('mout')) //dom挂载完毕
},
destroyed() {
console.log('destroyed') //页面销毁
}
}
</script>
p26 组件之间的通信
父组件—子组件
父组件传递数据
<template>
<view class="content">
<!-- 通过v-bind给子组件传数据 -->
<test v-if="flag" :msg='fmsg'></test>
</view>
</template>
<script>
import test from '../../components/test.vue'
export default {
components:{
test
},
data(){
return{
flag: true,
fmsg: '儿子你好!'
}
}
}
</script>
子组件接收数据
<template>
<view id="mout">
test组件,父组件传来的数据为:--- {{msg}}
</view>
</template>
<script>
export default {
name:"test"
props: ['msg'],//接受父组件传来的数据
}
</script>
子组件—父组件
父组件提供一个方法用来接收子组件的数据
<template>
<view class="content">
<!-- 将func方法传给子组件,子组件通过func方法给父组件传值 -->
<test v-if="flag" @func="receivedSon"></test>
</view>
</template>
<script>
import test from '../../components/test.vue'
export default {
components:{
test
}
methods: {
receivedSon(msg){
//接收到子组件传来的数据
console.log(msg)
}
}
}
</script>
子组件通过this.$emit调用,来给父组件传值
<template>
<view id="mout">
test组件
<button type="primary" @click="sendFather">给父组件传数据</button>
</view>
</template>
<script>
export default {
name:"test",
data() {
return {
num: 10
};
},
methods: {
sendFather(){
//通过this.$emit调用,来给父组件传值
this.$emit('func','爸爸你好,我是儿子')
}
}
}
</script>
全局组件通信
uni.$emit(eventName,OBJECT)
触发全局的自定义事件,附加参数都会传给监听器回调函数。
属性 | 类型 | 描述 |
---|---|---|
eventName | String | 事件名 |
OBJECT | Object | 触发事件携带的附加参数 |
uni.$on(eventName,callback)
监听全局的自定义事件,事件由 uni.$emit
触发,回调函数会接收事件触发函数的传入参数。
属性 | 类型 | 描述 |
---|---|---|
eventName | String | 事件名 |
callback | Function | 事件的回调函数 |
【案例:a组件更新b组件的数据】
新建a组件
<template>
<view>
a组件<button type="primary" @click="updateB">修改b组件的数据</button>
</view>
</template>
<script>
export default {
name:"a",
methods: {
updateB(){
uni.$emit('updateNum',10) //触发全局的updateNum事件
}
}
}
</script>
新建b组件
<template>
<view>
b组件的num={{num}}
</view>
</template>
<script>
export default {
name:"b",
data() {
return {
num: 0
};
},
created() {
uni.$on('updateNum',num =>{ //添加全局的事件
this.num += num
})
}
}
</script>
p27 uni-ui扩展组件
uni-ui是DCloud提供的一个跨端ui库,它是基于vue组件的、flex布局的、无dom的跨全端ui框架。
uni-ui不包括基础组件,它是基础组件的补充。
使用方法,登录后下载进入到Hbuilderx即可,默认已经全局注册,无需导入。
后端项目跟着老师的视频敲就好