华清远见重庆中心-移动互联网应用

css动画

动画原理

       /* 同时设置多个变换属性,用空格隔开 */
            transform: rotate(180deg) translateX(100px) scale(0.5);

            /* transform 的实现原理类似于矩阵,先旋转后平移和先平移后旋转结果是不同的 */
            transform: translateX(100px) rotate(180deg) scale(0.5);
  • rotate(180deg)旋转角度

  • translateX(100px)沿着X轴平移100像素

  • scale(0.5)等比例缩放

  • skew(30deg)倾斜角度

  • transform-origin: 50px 100px;

/* 设置transform的原点 */

/* 原点的位置会影响旋转的圆心,缩放的位置 */

/* 值的带选项:center, top, bottom, left, right, 还可以写具体的长度值 */

/* transform-origin: center;

/ / 原点若x值和y值都为0,代表的是元素左上角的位置 */

/* 第一参数值代表横向移动的距离,正数代表向右移动,负数代表向左移动 */

/* 第二参数值代表纵向移动的距离,正数代表向下移动,负数代表向上移动 */

过渡动画

   transition: all 2s linear;

            /* transition复合属性可以拆解成以下属性 */

            /* 过渡属性:声明一个需要产生过渡动画的属性 */
            /* 可以同时声明多个属性,属性之间用逗号隔开 */
            /* 待选项:
                all: 代表所有属性
                none: 没有任何属性
             */
            transition-property: opacity, transform;
            transition-property: all;

            /* 补间动画的时长 */
            transition-duration: 1s;
            transition-duration: 1000ms;

            /* 补间动画的速度曲线 */
            /* 带选项:
                linear: 匀速播放动画
                ease-in: 慢进匀速出
                ease-out: 匀速进慢出
                ease-in-out: 慢进慢出
                steps(n): 声明有n个过渡阶段
             */
            transition-timing-function: linear;

            /* 除了使用预制带选项,也可以手动赋值如下: */
            transition-timing-function: cubic-bezier(0.76, 0.19, 0.19, 0.8);

            /* steps 函数 */
            transition-timing-function: steps(5);

            /* 延迟播放动画的时间 */
            transition-delay: 1s;

            /* 使用transition属性设置所有的过渡动画属性 */
            /* 属性顺序如下:过渡属性名 过渡时长 速度曲线 延迟时间 */

            transition: all 3s ease-in-out 2s;
  • transition -property:过度属性

  • transition -duration:过度动画时长

  • transition-timeing-function:过度动画的运动曲线

  • transition-delay:过度动画的延迟时间

过渡动画事件

  // 过渡动画事件
    // 过渡动画播放完成事件
    box.addEventListener('transitionend', ev => {
        console.log(ev);
        console.log('播放结束');
    })

    box.addEventListener('transitionstart', ev => {
        console.log(ev);
        console.log('开始播放');
    })

    box.addEventListener('transitionrun', ev => {
        console.log('run');
    })
  • transitionend:过度动画播完触发

  • transitionstart:过度动画开始播完触发

  • transitionrun:过度动画运行时播完触发

animation动画

  /* 动画名称 */
            /* 作用:用于告诉浏览器,该动画应用哪一个动画关键帧序列 */
            animation-name: move;

            /* 动画播放时长 */
            animation-duration: 2s;

            /* 动画播放的速度曲线 */
            animation-timing-function: linear;

            /* 延迟播放的时间 */
            /* animation-delay: 1s; */

            /* 动画播放次数 */
            /* 带选项:
                infinite: 无限循环播放
             */
            /* animation-iteration-count: infinite; */
            /* animation-iteration-count: 2; */

            /* 动画播放方向 */
            /* 带选项:
                normal:正向播放
                reverse: 反向播放
                alternate: 正向播放一次然后反向再播放一次
                alternate-reverse: 反向播放一次然后正向再播放一次
             */
            /* animation-direction: alternate-reverse; */

            /* 播放结束后,元素的最终状态模式 */
            /* 
                带选项:
                forwards:动画播放完后,保留最后一帧的状态
                backwards:动画播放完后,保留第一帧的状态
                both:动画播放完后,保留第一帧和最后一帧的状态和
             */
            animation-fill-mode: forwards;


            /* 可以定义复合属性,取代上面的所有属性 */
            /* 赋值顺序,可以参考如下顺序 */
            /* duration | timing-function | delay | iteration-count | direction | fill-mode | play-state | name */
            /* duration | timing-function | delay | name */
            /* duration | name */
            animation: move 2s linear 0s forwards;

        }

        /* 关键帧:动画播放时的几个关键状态 */
        /* 序列:有序的队列 */

        /* 定义一个关键帧序列 如下: */
        /* 使用@keyframes定义关键帧序列,后面参数为:动画名 */

        @keyframes move {

            /* 起始状态 */
            /* from { */
            0% {
                transform: translateX(0);
                color: #000;
                font-size: 16px;
            }

            /* 用百分比定义中间状态 */
            50% {
                transform: translateX(1000px);
                color: pink;
                font-size: 32px;
            }

            /* 结束状态 */
            /* to { */
            100% {
                transform: translateX(500px);
                color: green;
                font-size: 64px;
            }
        }
 btn.addEventListener('click', () => {
        if (!box.classList.contains('active')) {
            box.classList.add('active')
        }
    })

    box.addEventListener('animationend', () => {
        console.log('动画播放完成');
    })

    box.addEventListener('animationstart', () => {
        console.log('动画开始播放');
    })

    box.addEventListener('animationiteration', () => {
        console.log('动画重复播放');
    })

动画事件一般用的最多的是animationend

渐变色和响应式布局

  /* 线性渐变色 */
            /* 注意:渐变色的值,适用于 background-image 属性,而不是 background-color */
            /* linear-gradient
                第一个参数: 渐变的方向,也可以是个角度值
                默认方向为: to bottom
                后续颜色参数可以追加一个距离值
            */
            /* background-image: linear-gradient(to right, red, yellow 100px, green 200px); */
            background-image: linear-gradient(30deg, red, red 100px, blue 100px, blue 200px, black 200px);

            /* 径向渐变 */
            background-image: radial-gradient(red, yellow);
            background-image: radial-gradient(red, red 100px, yellow 100px, yellow 200px, black 200px);

            /* 重复线性渐变 */
            background-image: repeating-linear-gradient(to right, black, black 50px, white 50px, white 100px);

            /* 重复径向渐变 */
            background-image: repeating-

响应式布局

 /* 什么是页面的响应式?
            页面的元素样式会根据页面的宽度做出变化
        */

        /* 如何实现响应式? */
        /* 使用媒体查询,来实现响应式布局 */
        /* 媒体查询的作用:当媒体查询条件成立时,将应用花括号中代码块的样式 */

        /* 语法:@media media-type and (condition1) and (condition2) */

        /* 媒体类型 media-type:
            备选项
            all: 所有设备
            print:打印机的预览模式
            screen:显示屏
            speech:语音合成器
         */
        /* min-width: 屏幕最小宽度 */
        @media screen and (min-width: 700px) {
            .box {
                background-color: #f00 !important;
            }
        }

        /* max-width: 屏幕最大宽度 */
        @media screen and (max-width: 1000px) {
            .box {
                background-color: #00f !important;
            }
        }

jquery

jquery是jquery是一个js的工具库

针对页面元素,jquery提供了很多操纵页面元素的函数

还有一些工具函数,方便一些运算

jquery可以充当发起网络请求的客户端工具

  // jquery 使用的方法:

    // 1. 查询并存储元素
    // 2. 操作元素,包括修改元素样式,绑定事件等

    let box = document.querySelector('.box')

    // 查询并构造一个jquery对象
    let $box = $('.box')

    console.log($box);
    // 修改样式
    $box.css('background-color', '#f00')

jquery绑定事件

    // 给jquery对象绑定事件时,直接调用该事件名称对应的函数
    // $box.click(function (ev) {
    //     console.log(ev);
    //     console.log('click');
    // })

    // $box.mousemove(function (ev) {
    //     console.log(ev);
    //     console.log('move');
    // })

    // $box.mouseenter(function (ev) {
    //     console.log('enter');
    // })

    // 手动触发事件
    // $box.click()
    // $box.mouseenter()

    // 使用 on 函数绑定事件
    const click1 = function (ev) {
        console.log('click1');
        console.log(ev);
    }
    $box.on('click', click1)

    $box.on('click', function (ev) {
        console.log('click2');
        console.log(ev);
    })

    // 使用 off 解绑事件
    // 如果只写一个参数,会解绑所有的对应事件
    // $box.off('click')
    $box.off('click', click1)


    // 使用 one 函数,可以让绑定的事件只触发一次
    // $box.one('click', (ev) => {
    //     console.log('one click');
    //     console.log(ev);
    // })

    $box[0].addEventListener('click', function () {
        console.log('one click');
        $box[0].removeEventListener('click', arguments.callee)
    })

    // 页面加载完成事件
    $(function () {
        console.log('load');
    })

canvas画布

canvas 绘制几何图形原理是,先获取绘画的点,这个点在canvas中称为路径(path),会根据用户使用的工具不同(工具要么是笔刷要么是油漆桶),进行镂空绘制或者填充绘制

canvas最重要的是

 // 获取画布
    let c = document.querySelector('canvas')
    let ctx = c.getContext('2d')

画线

  // 获取画布
    let c = document.querySelector('canvas')
    let ctx = c.getContext('2d')

    // 修改笔头宽度
    ctx.lineWidth = 20

    // 画线之前要开启路径
    ctx.beginPath()

    // 移动笔头
    ctx.moveTo(100, 50)
    // 绘制直线路径
    ctx.lineTo(200, 50)
    ctx.lineTo(200, 300)
    // ctx.lineTo(100, 50)

    // 闭合路径
    ctx.closePath()

    // 根据路径绘图
    // 绘制镂空线
    ctx.stroke()
    // 绘制填充图形
    // ctx.fill()


    ctx.beginPath()
    ctx.moveTo(250, 250)

    // 绘制弧形
    // 第一个和第二个参数: 圆心坐标
    // 第三个参数: 圆半径
    // 第四个和第五个参数: 起始弧度和结束弧度
    // 0 度代表水平向右
    // 正方向为顺时针
    ctx.arc(250, 250, 250, Math.PI / 180 * 30, Math.PI)

    ctx.closePath()

    ctx.stroke()
    // ctx.fill()

画图片

  // 获取画布
    let c = document.querySelector('canvas')
    let ctx = c.getContext('2d')

    // 绘制图片,只能绘制html页面中的图片<img>标签,且必须是加载完成的图片

    // 获取图片源
    const img = document.querySelector('img')
    img.addEventListener('load', () => {
        // 图片加载完成后才能绘制图片
        // 语法:
        // void ctx.drawImage(image, dx, dy);
        // void ctx.drawImage(image, dx, dy, dWidth, dHeight);
        // void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
        // 解释:
        // image:img标签
        // dx,dy: 绘制图片的坐标位置
        // dWidth, dHeight: 绘制图片的宽度和高度
        // sx, sy: 图片内部的坐标,用于截取图片
        // sWidth, sHeight: 截取图片的宽高

        // 绘制完整图片
        // ctx.drawImage(img, 100, 50)
        // ctx.drawImage(img, 100, 50, 200, 100)

        // 绘制部分图片
        ctx.drawImage(img, 70, 130, 250, 100, 100, 50, 250, 100)
    })

函数

   const canvas = document.querySelector('canvas')
    const ctx = canvas.getContext('2d')

    // 动画目标: 将一个 50 x 50 的方块,以每秒 100px 的速度 向右移动

    // requestAnimationFrame 请求动画的下一帧
    // 参数是一帧之后的回调函数
    requestAnimationFrame(render)

    // 上一次动画时长
    let lastTime = 0
    // 上一帧到下一帧的间隔时间
    let deltaTime = 0

    let box = {
        position: { x: 0, y: 0 },
        width: 50,
        height: 50,
        // 速度: 每秒移动 100px
        v: 100
    }

    // time 动画的播放总时长
    function render(time) {

        // 执行每一帧的逻辑

        // 计算上一帧到这一帧的时间间隔
        deltaTime = time - lastTime
        lastTime = time
        console.log(deltaTime);

        // 速度 * deltaTime = 每帧的速度
        box.position.x += deltaTime * 0.001 * box.v


        // 画图
        // 清空画布
        ctx.clearRect(0, 0, 500, 500)
        ctx.fillRect(box.position.x, box.position.y, box.width, box.height)

        // 循环递归请求下一帧
        requestAnimationFrame(render)
    }

多媒体标签

视频

 <!-- 属性
        width 标签宽度
        height 标签高度
        controls 控制面板
        muted 静音
        autoplay 自动播放
        src 媒体源
        preload 预载模式
        loop 循环
        poster 海报
    -->
    <!-- 使用自动播放+静音,能实现自动播放的效果 -->
    <!-- <video width="200" height="200" src="./video/oceans.mp4" controls autoplay muted></video> -->

    <video controls preload="auto" loop poster="./img/1.png">
        <!-- source 代表视频源 -->
        <source src="./video/oceans.mp4">
        </source>
    </video>

音频

 <!-- 由于audio和video都属于HTMLMediaElement的实例
        所以audio的所有使用方法和video一样
        可以通过 instanceof 来判断一个对象是否是某个类型的实例
        video instanceof HTMLMediaElement
    -->

    <!-- <audio src="./audio/a4.mp3" controls loop></audio> -->

    <!-- source 标签若有多个,那么浏览器会从上至下加载直到某一个被加载成功为止 -->
    <audio controls>
        <source src="./audio/a4.mp3">
        <source src="./audio/b4.mp3">
        <source src="./audio/c4.mp3">
    </audio>

事件

   // 可以通过音频类型 Audio 来播放音效
    let aud = new Audio('./audio/a4.mp3')

    // 关于自动播放
    // 若直接播放媒体资源,将获得一个异常,告诉你浏览器不允许在用户未经允许的请款下自动播放
    // video.play()

    // setTimeout(() => {
    //     video.play()
    // }, 5000)

    // document.addEventListener('click', () => {
    //     // 由于不能直接自动播放,所以需要一个事件触发播放
    //     video.play()
    // })


    playBtn.addEventListener('click', () => {
        // 播放
        video.play()
        // 获取媒体的总时间
        totalTime.innerHTML = video.duration
    })
    pauseBtn.addEventListener('click', () => {
        // 暂停
        video.pause()
    })

    setInterval(() => {
        // video.currentTime 当前媒体播放的进度时间
        currentTime.innerHTML = video.currentTime
    }, 1000)

    goTo.addEventListener('click', () => {
        // 跳转播放时间
        video.currentTime = Number(inp.value)
    })

    // 音量加减
    // 取值范围是0~1
    vUp.addEventListener('click', () => {
        video.volume = Math.min(1, video.volume + 0.1)
    })
    vDown.addEventListener('click', () => {
        video.volume = Math.max(0, video.volume - 0.1)
    })

    // 静音与恢复
    muted.addEventListener('click', () => {
        video.muted = !video.muted
    })

微信小程序

小程序项目结构

项目下的文件和文件夹的作用如下:

components: 小程序的自定义组件
images: 图片文件夹
pages: 存放页面文件的文件夹
    index: 页面文件夹
        index.js: 页面的js代码
        index.json: 页面的配置
        index.wxml: html模板文件
        index.wxss: 页面的样式文件
utiles: 辅助用的js代码放的文件夹
app.js: 微信小程序的程序入口(程序入口:开始执行代码的地方)
app.json: 小程序应用程序的全局配置文件
app.wxss: 小程序的全局样式(.wxss文件是小程序的样式文件)
project.config.json: 小程序项目的配置
sitemap.json: 用于微信搜索小程序的配置文件

常用标签

<!-- page 标签相当于 html 中的 body -->
<page></page>

<!-- view 标签相当于 html 中的 div -->
<view></view>

<!-- text 相当于 html 中的 span -->
<text></text>

<!-- image 相当于 html 中的 img -->
<image></image>

<!-- block 是一个自身不会显示的标签 -->
<block></block>

认识页面对象模型page

使用Page函数包裹的整个对象是一个 page 对应的对象模型,例如:

Page({
    data: {
        // 数据
    },
    onLoad: {
        // 加载完成事件
    }
})

模板语法

模板语法是微信规定的一套书写wxml的语法

插值

作用:用于将变量值插入页面

语法:

<!-- name 变量,定义在 js 文件的 data 中 -->
{{name}}
注意:插值运算的花括号中{{}},填写的内容其实是js表达式

循环渲染

作用:可以将数组数据循环显示到页面中

语法:

<!-- wx: 开头的写在标签头部的东西 称为指令 -->
<!-- array: 来自js data中的数组 -->
<!-- 使用 wx:for 一定要加上 wx:key,wx:key的值是array对象中的不可重复的属性 -->
<view wx:for="{{array}}" wx:key="id">
    <!-- index: 是 wx:for 中隐式声明的变量,代表循环遍历array时的当前索引 -->
    <!-- item: 是 wx:for 中隐式声明的变量,代表循环遍历array时的当前数组成员 -->
    {{index}}: {{item}}
</view>

条件渲染

可以根据条件判断,选择性的渲染页面

语法:

<view wx:for="{{table}}" wx:key="name">
    <text>{{index}}: 姓名 = {{item.name}}; 年龄 = {{item.age}}; 性别 = </text>
    <!-- wx:if 指令的值为布尔表达式,为true是渲染该节点,否则不渲染 -->
    <text wx:if="{{item.sex==='male'}}">男</text>
    <!-- wx:if 可以和 wx:elif、wx:else 连用 -->
    <text wx:elif="{{item.sex==='female'}}">女</text>
    <text wx:else>其他</text>
</view>

全局配置

app.json 文件中的配置是全局配置 影响所有页面

  • entryPagePath 小程序启动页的路径

  • pages 页面的路径列表

  • window 全局窗口的配置

  • tabBar 底部选项卡

  • debug 开启调试模式

页面配置

全局配置下,window中的所有内容,每个页面自身也可以配置

  • disableScroll 禁止用户上下滚动页面

  • usingComponents 使用组件

授权

用户需要使用本地设备上的一些设备功能时,需要向系统获取设备权限,例如:摄像头,定位信息,联系人,陀螺仪等

此时就需要进行授权操作

什么时候使用授权

在用户即将使用一些需要授权才能使用的本地设备功能时(微信小程序已经把这些功能制作成了接口,当需要调用这些接口的时候就可以进行授权)

流程

  • 读取当前权限

  • 判断是否存在权限

  • 不存在权限就进行授权

// 可以通过 wx.getSetting 先查询一下用户是否授权了 "scope.record" 这个 scope
wx.getSetting({
    success(res) {
        if (!res.authSetting['scope.record']) {
            // 调用 wx.authorize 进行授权
            wx.authorize({
                scope: 'scope.record',
                success() {
                    // 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问
                    wx.startRecord();
                },
            });
        }
    },
});

权限列表

文档: 授权 | 微信开放文档

授权期限

授权后,权限将一直存在,直到小程序被删除为止

关于二次授权

用户在进行授权时是可以拒绝的,若拒绝授权,我们可以使用 wx.openSetting 打开设置引导用户开启权限

例如以下代码

wx.getSetting({
    success: (res) => {
        console.log(res);
        if (!res.authSetting['scope.camera']) {
            if (typeof res.authSetting['scope.camera'] === 'undefined') {
                // 用户没有进行过授权

                wx.authorize({
                    scope: 'scope.camera',
                    success: () => {
                        console.log('开启摄像头');
                    },
                });
            } else {
                // 用户拒绝过授权

                // openSetting 打开权限设置
                // 设置中包含的是已经授权或被拒绝过的权限
                wx.openSetting({
                    success(res) {
                        console.log(res);
                    },
                });
            }
        } else {
            console.log('开启摄像头');
        }
    },
});

什么是组件

具备独立的 js,json,wxml,wxss的一段代码是一个组件

组件主要的作用是复用页面代码

创建组件

注册组件

组件结构

组件生命周期

组件生命周期 | 微信开放文档

组件属性

// 在组件的配置中添加 properties 配置
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    // 声明属性 value
    // 具体声明方式可参考 https://developers.weixin.qq.com/miniprogram/dev/reference/api/Component.html#properties-%E5%AE%9A%E4%B9%89
    value: {
      type: String, // 属性类型 可以通过设置 optionalTypes 来接收多种类型的数据
      value: 'o,k', // 属性默认值
      // 属性变化监听器
      observer: function (newVal, oldVal) {
        console.log(newVal);
        console.log(oldVal);
        console.log(this)
      }
    }
  },
})

组件内设置属性的方法和 Page 设置 data 是一样的

// 使用 setData 设置属性
this.setData({value: 'hello'})

在 Page 中注册组件后就可以将组件作为标签使用了

// 注册组件
{
    "useingComponent": {
        "my-component": "path/to/component"
    }
}
<!-- 使用组件 -->
<!-- _value 是当前页面 data 中的值 -->
<my-component value="{{_value}}"></my-component>
注意: 除了在组件内修改 value 值以外,还可以通过修改 Page 的 _value 来修改组件的 value 值

组件方法

获取组件并调用组件方法

Page({
    getComponent() {
        // 给组件添加 class="my-component"
        // 通过 selectComponent 获取组件
        let com = this.selectComponent('.my-component')
        // 假设组件 methods 中有个方法叫 myFn
        // 调用组件方法
        com.myFn()
    }
})

组件事件

<!-- 假设组件的模板如下 -->
<button bindtap="onClick">发送点击事件</button>
// 组件声明如下
Component({
    methods: {
        onClick() {
            // triggerEvent 可以发出事件
            // 文档: https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/events.html#%E7%9B%91%E5%90%AC%E4%BA%8B%E4%BB%B6
            // 第一个参数: 发出的事件名称
            // 第二个参数: 事件传递出去的参数
            // 第三个参数: 事件选项
            this.triggerEvent('my-click', 'my detail')
        }
    }
})
<!-- Page 的 wxml 如下 -->
<!-- 通过 bind:<event-name> 的方式绑定事件 -->
<my-component bind:my-click="myClickHandler"></my-component>
Page({
    // myClickHandler 将接收组件的 my-click 事件
    myClickHandler(event) {
        // event.detail 的值就是 triggerEvent 的第二个参数值
        console.log(event.detail)
    }
})

将数据保存到小程序的全局对象中

// 获取小程序实例对象
const app = getApp()

app.globalData.x = 1 // 给小程序的全局对象赋值

// 只要不关闭小程序就能通过小程序全局对象保存参数

为什么要使用全局对象来存储数据

为了让每个页面共享相同的数据

持久化数据

什么叫持久化?持久化就是长期存储数据到磁盘中,关闭应用程序后,存储的数据还在

异步是什么?异步就是程序执行的时候不会等待或卡顿

同步是什么?同步的程序在调用的时候会等待或卡顿

导航与页面间传参

导航:引导页面跳转到指定位置

导航方法有两种:1. 页面标签进行导航,类似 html 中的 a 标签;2. 使用js进行导航,类似于 location.href

使用 navigator 标签

文档:navigator | 微信开放文档

语法:

<!-- url:要跳转到的页面路径 -->
<!-- 若要传递参数,可以在url后面增加 ?key=value 的参数 -->
<navigator url="path"></navigator>

使用 wx.navigateTo

语法:

function(){
    wx.navigateTo({
        // path: 要跳转的路径
        // key=value: 要传递的参数
        url: 'path?key=value'
    })
}

// wx.navigateTo 跳转到某页 会新增堆栈
// wx.redirectTo 重定向到某页 不会新增堆栈
// wx.navigateBack 返回
参数的获取可以在另一个页面的 onLoad 声明周期函数中 options 变量中存放着参数

js代码中的赋值与读值

在js代码的函数中读取属性的方法:

Page({
    read() {
        console.log('read')
        // 函数中的 this 代表当前页面对象模型
        console.log(this)
        // 谁用this.data读取页面属性
        console.log(this.data.table)
    }
})

给页面属性赋值的方法:

Page({
    write() {
        // 使用this.setData函数进行赋值,参数是个json对象,需要修改哪个属性,就给该对象添加哪个属性
        this.setData({title: '天龙八部'})
    }
})

页面底部选项卡

在 app.json 中 增加 tabBar 配置就能添加选项卡

{
    "tabBar": {
        "selectedColor": "#444", // 选中的按钮的文本颜色
        "list": [ // 按钮列表
            {
                "pagePath": "pages/read/read", // 跳转的页面路径
                "text": "领读", // 按钮的文字描述
                "iconPath": "image/tab_icon1.png", // 未选中时的图标路径
                "selectedIconPath": "image/tab_icon1_active.png" // 选中时的图标路径
            }
        ]
    },
}
注意:要显示选项卡,按钮列表中,必须要有一个配置的 pagePath 属性值,是小程序的入口页面
注意:底部选项卡指定的页面不能是分包里的页面

自定义底部选项卡图标

可以在阿里适量图库下载需要的图标(一般来说是一个镂空图标和一个填充图标)

将下载后的图片复制到小程序项目目录下,然后再tabBar配置选项中配置即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值