本文目录
  1. p1 uniapp简介
  2. p2 uniapp环境搭建
    1. 创建uniapp项目
    2. 运行到浏览器
    3. 运行到微信小程序
    4. 运行到安卓手机
  3. p3 uniapp项目结构和开发规范
    1. 项目结构
    2. 开发规范
  4. P4 globalStyle全局配置
  5. P5 创建和配置页面
  6. p6-p7 tabBar 配置
  7. p8 condition
  8. p9 text组件
  9. p10 view组件
  10. p11 button组件
  11. p12 image组件
  12. p13 uniapp样式-字体图片-sass
    1. css单位
    2. 样式导入
    3. 选择器
    4. 全局样式与局部样式
    5. 使用scss
    6. 字体图标
  13. p14 -16数据绑定和事件绑定
  14. p17 应用和页面的生命周期函数
  15. p18 下拉刷新
  16. p19 上拉(触底)加载
  17. p20 发送get请求
  18. p21 数据缓存
    1. uni.setStorage
    2. uni.setStorageSync
    3. uni.getStorage
    4. uni.getStorageSync
    5. uni.removeStorage
    6. uni.removeStorageSync
  19. p22 图片的上传和预览
  20. p23 条件编译跨端兼容
  21. p24 导航
    1. navigator组件导航
    2. 编程式导航
  22. p25 组件的创建和组件生命周期函数
    1. 组件的创建和使用
    2. 组件的生命周期函数
  23. p26 组件之间的通信
    1. 父组件—子组件
    2. 子组件—父组件
    3. 全局组件通信
      1. uni.$emit(eventName,OBJECT)
      2. uni.$on(eventName,callback)
  24. p27 uni-ui扩展组件

分类: 公众号和小程序 | 标签: uniapp

uniapp学习笔记

发表于: 2022-06-12 16:05:28 | 字数统计: 8.1k | 阅读时长预计: 40分钟

笔记根据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项目

image-20220605214331953

运行到浏览器

image-20220605214413231

运行到微信小程序

image-20220605214452424

注意:需要先在微信小程序中 设置-安全设置 开启端口 否则启动不了。

image-20220605214536999

运行到安卓手机

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的语法结合

P4 globalStyle全局配置

对应page.json文件中globalStyle节点

属性类型默认值描述平台差异说明
navigationBarBackgroundColorHexColor#F7F7F7导航栏背景颜色(同状态栏背景色)APP与H5为#F7F7F7,小程序平台请参考相应小程序文档
navigationBarTextStyleStringwhite导航栏标题颜色及状态栏前景颜色,仅支持 black/white
navigationBarTitleTextString导航栏标题文字内容
navigationStyleStringdefault导航栏样式,仅支持 default/custom。custom即取消默认的原生导航栏,需看使用注意微信小程序 7.0+、百度小程序、H5、App(2.0.3+)
backgroundColorHexColor#ffffff下拉显示出来的窗口的背景色微信小程序
backgroundTextStyleStringdark下拉 loading 的样式,仅支持 dark / light微信小程序
enablePullDownRefreshBooleanfalse是否开启下拉刷新,详见页面生命周期
onReachBottomDistanceNumber50页面上拉触底事件触发时距页面底部距离,单位只支持px,详见页面生命周期

更多属性配置可以参考文档:全局配置文档

P5 创建和配置页面

第一步:新建文件夹以及创建vue文件

image-20220605221538951

message.vue的内容如下:

<template>
    <view>message页面</view>
</template>

<script>
</script>

<style>
</style>

第二步:在page.json文件中进行配置

注意:pages数组中第一项表示应用启动页

image-20220605221816965

测试就可以看到页面了

image-20220605221952416

参考:页面样式配置文档

p6-p7 tabBar 配置

属性说明:

属性类型必填默认值描述平台差异说明
colorHexColortab 上的文字默认颜色
selectedColorHexColortab 上的文字选中时的颜色
backgroundColorHexColortab 的背景色
borderStyleStringblacktabbar 上边框的颜色,可选值 black/whiteApp 2.3.4+ 支持其他颜色值、H5 3.0.0+
blurEffectStringnoneiOS 高斯模糊效果,可选值 dark/extralight/light/none(参考:使用说明 (opens new window)App 2.4.0+ 支持、H5 3.0.0+(只有最新版浏览器才支持)
listArraytab 的列表,详见 list 属性说明,最少2个、最多5个 tab
positionStringbottom可选值 bottom、toptop 值仅微信小程序支持

tabbar文档

第一步:新增contact页面,参考p5。建完之后别忘了在pages.json中的pages节点下配置路径

image-20220610110727253

第二步:将图片拷贝的静态文件夹,有选中的图片和不选中的图片。可以用阿里图标库生成

image-20220610105106625

第三步: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": "我们"
            }
        ]
    }

然后在界面就可以看到效果了,点击之后可以切换到对应的界面

image-20220610111119764

p8 condition

condition文档

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

属性说明:

属性类型是否必填描述
currentNumber当前激活的模式,list节点的索引值
listArray启动模式列表

list说明:

属性类型是否必填描述
nameString启动模式名称
pathString启动页面路径
queryString启动参数,可在页面的 onLoad 函数里获得

注意: 在 App 里真机运行可直接打开配置的页面,微信开发者工具里需要手动改变编译模式,如下图:

image-20220610113003166

第一步:新增details页面

第二步:在pages.json中添加condition节点,配置如下

"condition" : { //模式配置,仅开发期间生效
        "current": 0, //当前激活的模式(list 的索引项)
        "list": [
            {
                "name": "详情页", //模式名称
                "path": "pages/details/details", //启动页面,必选
                "query": "id=10" //启动参数,在页面的onLoad函数里面得到
            }
        ]
    }

p9 text组件

text组件文档

文本组件。

用于包裹文本内容。

属性说明

属性名类型默认值说明平台差异说明
selectableBooleanfalse文本是否可选App、H5、快手小程序
user-selectBooleanfalse文本是否可选微信小程序
spaceString显示连续空格App、H5、微信小程序
decodeBooleanfalse是否解码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组件

view组件文档

视图容器。

它类似于传统html中的div,用于包裹各种元素内容。

如果使用nvue (opens new window),则需注意,包裹文字应该使用<text>组件。

属性说明

属性名类型默认值说明
hover-classStringnone指定按下去的样式类。当 hover-class=”none” 时,没有点击态效果
hover-stop-propagationBooleanfalse指定是否阻止本节点的祖先节点出现点击态,App、H5、支付宝小程序、百度小程序不支持(支付宝小程序、百度小程序文档中都有此属性,实测未支持)
hover-start-timeNumber50按住后多久出现点击态,单位毫秒
hover-stay-timeNumber400手指松开后点击态保留时间,单位毫秒

在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组件

按钮组件

属性说明

属性名类型默认值说明平台差异说明
sizeStringdefault按钮的大小
typeStringdefault按钮的样式类型
plainBooleanfalse按钮是否镂空,背景色透明
disabledBooleanfalse是否禁用
loadingBooleanfalse名称前是否带 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组件

图片组件

属性名类型默认值说明平台差异说明
srcString图片资源地址
modeString‘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单位

css单位文档

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

  • px 即屏幕像素
  • rpx 即响应式 px,一种根据屏幕宽度自适应的动态单位。以 750 宽的屏幕为基准,750rpx 恰好为屏幕宽度。屏幕变宽,rpx 实际显示效果会等比放大,但在 App(vue2 不含 nvue) 端和 H5(vue2) 端屏幕宽度达到 960px 时,默认将按照 375px 的屏幕宽度进行计算,具体配置参考:rpx 计算配置

举例说明:

  1. 若设计稿宽度为 750px,元素 A 在设计稿上的宽度为 100px,那么元素 A 在 uni-app 里面的宽度应该设为:750 * 100 / 750,结果为:100rpx。
  2. 若设计稿宽度为 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” 的组件
elementview选择所有 view 组件
element, elementview, checkbox选择所有文档的 view 组件和所有的 checkbox 组件
::afterview::after在 view 组件后边插入内容,仅 vue 页面生效
::beforeview::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 内使用时需要注意,此字体名重复可能会显示不正常,可以使用工具修改。
  • 使用本地路径图标字体需注意:
    1. 为方便开发者,在字体文件小于 40kb 时,uni-app 会自动将其转化为 base64 格式;
    2. 字体文件大于等于 40kb,仍转换为 base64 方式使用的话可能有性能问题,如开发者必须使用,则需自己将其转换为 base64 格式使用,或将其挪到服务器上,从网络地址引用;
    3. 字体文件的引用路径推荐使用以 ~@ 开头的绝对路径。
@font-face {
    font-family: test1-icon;
    src: url('~@/static/iconfont.ttf');
}

第一步:将字体图标文件拷贝到static文件夹下

image-20220610222656159

第二步:修改iconfont.css路径,都加上~@路径

image-20220610222737395

第三步:使用

<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

image-20220611131049139

  • 当处理完数据刷新后,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

image-20220611144307276

页面生命周期中有个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 来访问接口 出现下面这样表示成功

image-20220611150847478

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文档

该组件类似HTML中的<a>组件,但只能跳转本地页面。目标页面必须在pages.json中注册。

该组件的功能有API方式,另见:https://uniapp.dcloud.io/api/router?id=navigateto(opens new window)

属性说明

属性名类型默认值说明平台差异说明
urlString应用内的跳转链接,值为相对路径或绝对路径,如:”../first/first”,”/pages/first/first”,注意不能加 .vue 后缀
open-typeStringnavigate跳转方式

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组件

image-20220611221930789

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)

触发全局的自定义事件,附加参数都会传给监听器回调函数。

属性类型描述
eventNameString事件名
OBJECTObject触发事件携带的附加参数

uni.$on(eventName,callback)

监听全局的自定义事件,事件由 uni.$emit 触发,回调函数会接收事件触发函数的传入参数。

属性类型描述
eventNameString事件名
callbackFunction事件的回调函数

【案例: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不包括基础组件,它是基础组件的补充

uni-ui扩展组件文档

使用方法,登录后下载进入到Hbuilderx即可,默认已经全局注册,无需导入。

后端项目跟着老师的视频敲就好

------ 本文结束,感谢您的阅读 ------
本文作者: 程序员青阳
版权声明: 本文采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。