• 微信小程序开发之路④


    14、微信小程序数据绑定与数组的运用

    01 微信小程序数据绑定

    WXML数据绑定
    
    • 1

    运用 JS 的 data 对象完成的 WXML 数据的动态显示

    绑定分类:

    1、基础绑定

    data: {
        studentName: 'tom'
    }
    ;<text>{{ studentName }}</text>
    
    • 1
    • 2
    • 3
    • 4

    data 的作用

    1、初始始数据

    2、我们的所有数据和面页中的内容绑定时的对接程序。

    2、组件绑定

    属性设定(需要在双引号内)

    <view class="{{flag ? 'color-red' : 'color-green'}}">
        <text>name: {{studentName}}text>
    
        <view id="item{{id}}"> item-view view>view
    >
    
    • 1
    • 2
    • 3
    • 4
    • 5

    运算符的操作

    02、微信小程序数组

    小程序数组的写法

    studentScroes:[90, 70, 85],

    和绑定表达式的组合使用

    {{studentScroes[0]}}

    和绑定表达式的对象组合使用

    {{studentClassScroes[0].className}}

    扩展运算符(模板时后期讲解)

    Js 里的 data 页面的初始数据,让我们所有的数据与页面的内容进行数据绑定时的对接程序

      data: {
        studentName: "tom"
      },
    
    • 1
    • 2
    • 3

    15、微信小程序条件渲染与列表渲染

    在微信里所有的字符串都是真

    01、微信小程序条件渲染与列表渲染

    wx:if 用来做判断是否需要渲染该代码块
    
    • 1

    也可以用 wx:elif 和 wx:else 来写 if-else 语句

    Block wx:if
    
    wx:if --> if(){}
    wx:elif -> if else(){}
    wx:else --> else(){}
    block --> template
    
    特别区分:
    
    wx:if 和 hiiden 相当 display:none(css 隐藏 )
    
    wx:if 是遇 true 显示,hidden 是遇 false 显示。
    
    wx:if 在隐藏的时候不渲染,而 hidden 在隐藏时仍然渲染,只是不呈现。
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    所以如果频繁切换的话,用 hidden 将会消耗更多资源,因为每次呈现的时候他都会渲染,每次隐藏的时候,他都会销毁。

    如果切换并不频繁的话,用 wx:if 相对来说较好些,因为它会避免初始就一下渲染那么多。

    02、微信小程序条件渲染与列表渲染

    wx:for 的通用写法

    修改特定属性:

    wx:for-item 修改循环变量

    <view class="inner-view margin20" wx:for="{{navigatorScroll}}">
        <navigator url="{{item.url}}">
            <image src="/icon/{{item.img}}">image>
            <view class="inner-fnt">{{item.title}}view>
        navigator>
    view>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    wx:for-index 可以指定数组的下标

    view wx:for=“{{array}}” wx:for-index=“idx” wx:for-item=“itemName”

    指定义: wx:for-index=“scoredID”

    指定义: wx:for-item=“studentScore”

    <view
        wx:for="{{studentScores}}"
        wx:for-index="scoredID"
        wx:for-item="studentScore"
    >
        {{scoredID}}:{{studentScore}}
    view>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    数组的嵌套

    block wx:for

    block 与 view 区别

    用在 block 中可以渲染一个包含多节点的结构块。(相当一个 vue 中的 template 标签)

    用在 view 中只能应用单个节点。

    16、微信小程序模板操作与引用

    template 定义模板后可以在不同的位置使用模板

    模板的定义 name 起名字

    
    
    • 1
    <template name="studentInfo">
        <view>学号:{{ studentName }}</view>
        <view>姓名: {{ studengXingMing }}</view>
        <view>年龄:{{ age }}</view>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    使用模板 is

    
    
    • 1
    <template is="studentInfo" data="{{studentName, age}}" />
    
    • 1

    模板的作用域

    模板的引用的两种方式import和include
    
    • 1

    include 引入的模板里面不能包含 template 元素

    <include src="/templates/footer.wxml" />
    
    • 1

    Improt(引入模板)

    模板文件 templates 下目录:

    studentInfo.wxml
    text_student.wxml

    引入到 templateDemo.wxml

    可以把外部的一个文件导入指定的文件。然后再调用

    Import 的作用域:没有继承性
    就是 A 引入 B,B 引入 C, 在 A 里面不能展示 C

    Include(导入代码)

    可以将目标文件整个代码引入,相当于拷贝

    17、微信小程序的事件调用

    微信小程序事件

    事件是用户与微信小程序的交互的通讯接口
    
    事件是视图层到逻辑层的通讯方式。
    
    事件可以将用户的行为反馈到逻辑层进行处理。
    
    事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    事件对象可以携带额外信息,如 id, dataset, touches。

    在 JS 中就有事件操作的概念,微信小程序的更加简便

    事件的使用方式

    在组件中绑定一个事件处理函数。

    <view bindtap="tapName">Click me</view>
    
    • 1

    在相应的 Page 定义中写上相应的事件处理函数,参数是 event。

    tapName(event) {
        console.log(event);
    },
    
    • 1
    • 2
    • 3

    返回对象

    {type: “tap”, timeStamp: 2774, target: {…}, currentTarget: {…}, mark: {…}, …}

    以“bind+事件类型”或“catch+事件类型” 作为用户的事件绑定监听器,连接事件源和事件处理程序

    事件绑定函数可以是一个数据绑定

    <view bindtap="{{eventFun}}">Click me</view>
    
    data: {
        eventFun:"tapName"
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5

    事件分类

    #### 事件分为冒泡事件和非冒泡事件:

    1、冒泡事件 bind 开头:当一个组件上的事件被触发后,该事件会向父节点传递。

    2、非冒泡事件 catch 开头:当一个组件上的事件被触发后,该事件不会向父节点传递

    绑定并阻止事件冒泡

    除 bind 外,也可以用 catch 来绑定事件。与 bind 不同, catch 会阻止事件向上冒泡。

    例如在下边这个例子中,点击 inner view 会先后调用 handleTap3 和 handleTap2(因为 tap 事件会冒泡到 middle view,而 middle view 阻止了 tap 事件冒泡,不再向父节点传递),点击 middle view 会触发 handleTap2,点击 outer view 会触发 handleTap1。

    <view id="outer" bindtap="handleTap1">
        outer view
        <view id="middle" catchtap="handleTap2">
            middle view
            <view id="inner" bindtap="handleTap3">
                {' '}
                inner view{' '}
            </view>
        </view>
    </view>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    类型	            触发条件	        最低版本
    
    touchstart	       手指触摸动作开始
    
    touchmove	       手指触摸后移动
    
    touchcancel	        手指触摸动作被打断,如来电提醒,弹窗
    
    touchend	        手指触摸动作结束
    
    tap	               手指触摸后马上离开
    
    longpress	        手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发	1.5.0
    
    longtap	            手指触摸后,超过350ms再离开(推荐使用longpress事件代替)
    
    transitionend	    会在 WXSS transition 或 wx.createAnimation 动画结束后触发
    
    animationstart	    会在一个 WXSS animation 动画开始时触发
    
    animationiteration	会在一个 WXSS animation 一次迭代结束时触发
    
    animationend	    会在一个 WXSS animation 动画完成时触发
    
    touchforcechange	在支持 3D Touch 的 iPhone 设备,重按时会触发	1.9.90
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    注:除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件,如 form 的 submit 事件,input 的 input 事件,scroll-view 的 scroll 事件,(详见各个组件)

    事件的捕获阶段

    事件捕获是先外后里,且优于事件绑定。

    <view
    id="outer"
    bind:touchstart="handleTap1"
    capture-bind:touchstart="handleTap2"
    
    >
    
        outer view
        <view
            id="inner"
            bind:touchstart="handleTap3"
            capture-bind:touchstart="handleTap4"
        >
            inner view
        </view>
    
    </view>
    
    handleTap1() {
    console.log("handleTap1")
    },
    handleTap2() {
    console.log("handleTap2")
    },
    handleTap3() {
    console.log("handleTap3")
    },
    handleTap4() {
    console.log("handleTap4")
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    点击 inner view

    返回
    handleTap2
    handleTap4
    18 handleTap3
    handleTap1

    事件对象

    每次触发事件时都会传递一个对象给到 JS(逻辑层)

    BaseEvent的属性
    
    Type事件类型
    
    Timestamp 时间戳
    
    Target 属性集合(事件源组件)
    
    Id 事件源组件id
    
    Dataset data- 事件源组件上的自定义集合
    
    currentTarget 当前组件的一些属性值集合
    
    dataset data- 事件源组件上的自定义集合
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    二个盒子:当第二个子级盒子高度用 100%时,外面父盒子一定要有固定的高度。
    微信给一个获取屏幕高度、宽度的 API

    获取不同屏幕的高度、宽度 px,用一个固定的格式进行 rpx 的转换

    第一步
    /**
    * 生命周期函数--监听页面加载
    **/
    onLoad: function (options) {
        wx.getSystemInfo({
            success: function(res) {
                let clientHeight = res.windowHeight;
                let clientWidth = res.windowWidth;
                let ratio = 750 / clientWidth;
                let rpxHeight = clientHeight _ ratio;
                console.log(clientHeight);
                console.log(rpxHeight);
            },
        })
    },
        // 第二步在 data 定义变量
    data: {
        swiperRPXHeight:0
    },
        // 第三步修改变量
    onLoad: function (options) {
        let that = this;
        wx.getSystemInfo({
            success: function(res) {
                let clientHeight = res.windowHeight;
                let clientWidth = res.windowWidth;
                let ratio = 750 / clientWidth;
                let rpxHeight = clientHeight \* ratio;
                console.log(clientHeight);
                console.log(rpxHeight);
    
                that.setData({
                  swiperRPXHeight: rpxHeight
                })
            },
        })
    },
        第四步
        <swiper style="height:{{swiperRPXHeight}}rpx"> </swiper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    18、微信小程序媒体组件 audio

    audio 音频

    可以播放在线音频资源
    
    支持的属性:参考在线字典
    
    • 1
    • 2
    • 3

    支持 wx.createInnerAudioContext

    从内部代码完成播放操作,是 audio 的升级版本
    
    • 1

    案例演示

    <view>
      <audio name="{{name}}" poster="{{poster}}" author="{{author}}" src="{{src}}" id="myAudio"></audio>
    
    <button type="primary" bindtap="audioPlay">播放</button>
    <button type="primary" bindtap="audioPause">暂停</button>
    <button type="primary" bindtap="audio14">设置当前播放时间为 14</button>
    <button type="primary" bindtap="audioStart">回到开头</button>
    </view>
    
    
    /**
       * 播放
       */
        audioPlay() {
        this.audioCtx.play();
        },
    
      /**
       * 暂停
       */
        audioPause() {
        this.audioCtx.pause();
        },
    
     /**
       * 指定位置
       */
        audio14() {
        this.audioCtx.seek(14);
        },
    
      /**
       * 从头开始
       */
        audioStart() {
        this.audioCtx.seek(0);
        },
    
    /**
       * 生命周期函数--监听页面初次渲染完成
       */
    
        onReady: function () {
    
            // 创建一个音频对象(音频上下文)
            this.audioCtx = wx.createAudioContext("myAudio")
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    媒体组件 video

    video 视频组件:
    
    该组件为原生组件,需要注意部分事项
    
    小程序中的原生组件有如下
    
        camera,canvas,input,live-player,live-pusher,map,textarea,video
    
    原生组件的使用限制
    
    1.原生组件的层级是最高层,其他组件无法通过 z-index 来覆盖
    
    2.原生组件可以覆盖原生组件
    
    3.部分样式无法支持原生组件
    
    CSS 动画,position:fixed 4.在 IOS 下,原生组件不支持触摸事件
    
    属性:在线字典查询
    
    案例演示:弹幕制作
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    19、视图容器 movable-view 与 cover-view 的操作

    微信小程序控件 movable-view
    
    • 1

    movable-area,movable-view

    可移动区域

    需要设置movable-area高和宽,默认值:10px
    
    • 1

    movable-view 可拖动区域容器

    属性:参考在线字典

    案例演示
    照片的拖动缩放

    cover-view

    覆盖在组件上的文本视图

    cover-image

    覆盖在原生组件智商的图片

    案例演示

    20、件 rich-text 与 progress 操作

    微信小程序控件 rich-text 通过 rich-text 组件可以加载 HTML 的容器

    富文本对话框
    
    可以直接导入HTML标签文本
    
    nodes属性
    
    属性值可以是 array或string
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    在这里插入图片描述

    案例演示 加载逻辑层数据
    在这里插入图片描述

    下面是wxhtml结构

    在这里插入图片描述
    在这里插入图片描述

    微信小程序控件 progress->进度条

    percent 进度多少
    stroke-width:宽度

    进度条操作

    属性:参考在线字典

    案例演示

    20、表单 form 控件的提交原理与提交操作

    微信小程序 form 提交原理

    form 表单的提交

    和 PC 端的表单提交有所不同

    更贴近表单的异步提交模式

    两大重要事件

    bindsubmit

    bindreset

    <from bindsubmit="formSubmit" bindreset="formReset">
    
        <buttom form-type="submit">Submit</button>
        <buttom form-type="reset">Reset</button>
    </from>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    点击这二按钮后会完成事件的处理:formSubmit formReset

    微信小程序提交事件操作

    button

    size = “mini” 小的
    type = “primary” 颜色
    plain 镂空
    disabled=‘{{false}}’ 不是不可用
    loading = ‘{{true}}’ 名称前是否带 loading 图标

    用于 form 组件,点击分别会触发 form 组件的 submit/reset 事件

    <button form-type="submit"></button>
    <button fro-type ="reset"></button>
    
    • 1
    • 2
    radio

    用 radio-group 归为一类别

    <radio-group name="radio">
        <label>
            <radio value="radio1" />
            选项一
        </label>
        <label>
            <radio value="radio2" />
            选项二
        </label>
    </radio-group>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    checkbox

    用 checkbox 归为一类别
    用 e.detail.value 获取 value 值

      /**
       * 提交事件
       */
      checkedChange(e){
        console.log(e.detail.value)
        //获取数据
    
        //处理数据
    
        //提交数据
      },
    
    <checkbox-group checkbox='checkedChange'>
        <label>
            <checkbox value="checkbox1" />
            选项一
        </label>
        <label>
            <checkbox value="checkbox2" />
            选项二
        </label>
    </checkbox-group>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    editor 富文本编辑器
    input

    type 为键盘类型

    
    <input value='文本' type='tex' maxlength="5" focus="true">input>
    
    <input value='数字'>input>
    
    <input password placeholder="密码" placeholder-style='color:red'>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    confirm-type = send 发送 search 搜索 next 下一个 go 前往 done 完成

    label

    点击控件的区域大小

    21、导航组件 navigator 跳转与 tabbar 的跳转操作

    navigator 跳转
    主要用于直接在 wxml 的跳转

    可跳转其他小程序

    具体属性参考:在线微信字典

    tabbar 的跳转

    通过 app.json 的配置

    通过微信接口进行跳转

    注意事项

    tabbar 跳转与 navigator 跳转不可同时作用在一个对象上

    同一对象

    <navigator target='self' url="/pages/form/form' open-type='switchTab'>tabbar</navigator>
    
    • 1
    <navigator target="self" url="/pages/audio/audio" open-type="reLaunch">
        跳转操作
    </navigator>
    
    • 1
    • 2
    • 3
    <button bindtap="tabbarNivagtor">tatbar跳转</button>
    tabbarNivagtor(){
        wx.switchTab({
            url: '/pages/index/index'  //这个路径一定要在app.json中的
        })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    其他的跳转方式

    <button bindtap="otherNavigator">跳转</button>
    
    otherNavigator(){
        wx.redirectTo({
            url: '/pages/index/index'  //这个路径一定要在app.json中的
        })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    // open-type 的合法值

    navigate 与 reLaunch 的区别

    reLaunch可以把前面打开的页面关闭,而navigate前面页面打开着,当前页面跳转。
    
    • 1
    personCenter
    <view class="container">
        <view class="page">
            <form bindsubmit="regFormSubmit" bindreset="regFormReset">
                <view class="area">
                    <label class="model">
                        <text>name:</text>
                        <input class="input" bindblur="inputValue"></input>
                    </label>
                    <label class="model">
                        <text>password:</text>
                        <input
                            class="input"
                            password
                            bindblur="passwordValue"
                        ></input>
                    </label>
                    <label class="model">
                        <text>password:</text>
                        <radio-group
                            class="control-center"
                            bindchange="genderRadio"
                        >
                            <radio value="1" checked>
                                male
                            </radio>
                            <radio value="0">female</radio>
                        </radio-group>
                    </label>
                    <label class="model">
                        <text>hobby:</text>
                        <checkbox-group
                            class="control-center"
                            bindchange="hobbyCheckbox"
                        >
                            <checkbox value="tour">tour</checkbox>
                            <checkbox value="book" checked>
                                book
                            </checkbox>
                            <checkbox value="game">game</checkbox>
                        </checkbox-group>
                    </label>
                    <label class="model">
                        <text>birthday</text>
                        <picker mode="date" bindchange="birthdayValue">
                            <view>[please choose birthday]</view>
                        </picker>
                    </label>
                    <label class="model">
                        <text>study years:</text>
                        <slider
                            step="1"
                            show-value
                            bindchange="sliderValue"
                        ></slider>
                    </label>
                    <label class="model">
                        <view>
                            isMember:
                            <switch bindchange="isMemberValue"></switch>
                        </view>
                    </label>
                    <label class="model">
                        <text>agreemeng:</text>
                        <textarea class="textarea control-center">
                            this is psersonReg.please read it first.
                        </textarea>
                    </label>
                    <button size="default" form-type="submit">
                        submit
                    </button>
                    <button size="default" form-type="reset">
                        reset
                    </button>
                </view>
            </form>
        </view>
    </view>
    
    Page({
      //表单数据
      personName:'',
      password:'',
      gender:'',
      hobby:'',
      birthday:'',
      studyYears:'',
      isMember:'',
    
      /**
       * 页面的初始数据
       */
      data: {
    
      },
    
      /**
       * 获取姓名
       */
      inputValue(e){
        this.personName = e.detail.value;
        console.log(this.personName)
      },
    
      /**
       * 获取密码
       */
      passwordValue(e){
        this.password = e.detail.value;
        console.log(this.password)
      },
    
    
      /**
       * 获取性别
       */
      genderRadio(e){
        this.gender = e.detail.value == 1 ? "male" : "female";
        console.log(this.gender)
      },
    
      /**
       * 获取爱好
       */
      hobbyCheckbox(e){
        this.hobby = e.detail.value
        console.log(this.hobby)
      },
    
      /**
       * 获取生日
       */
      birthdayValue(e){
        this.birthday = e.detail.value;
        console.log(this.birthday)
      },
    
      /**
       * 获取学习年数
       */
      sliderValue(e){
        this.studyYears = e.detail.value;
        console.log(this.studyYears)
      },
    
      /**
       * 获取判断会员
       */
      isMemberValue(e){
        this.isMember = e.detail.value;
        console.log(this.isMember)
      },
    
      /**
       * 提交按钮
       */
      regFormSubmit(){
        let memberData = {
          personName: this.personName,
          password: this.password,
          gender: this.gender,
          hobby: this.hobby,
          birthday: this.birthday,
          isMember: this.isMember
        }
    
        if(memberData.personName == ""){
          wx.showModal({
            title: 'error',
            content: '姓名没有填写',
          })
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172

    手机验证码

    按钮-> 服务器 -> 电信(移动,联通) 渠道商接(短信下发) -> 在服务器端记录验证号,

    用户输入 -> 提交 -> 服务器

    用户输入 -> 服务器的记录匹配

    24、camera 系统相机。扫码二维码功能,

    <view class="page-body">
      <view class="page-body-wrapper">
        <camera device-position="back" flash="off" binderror="error" style="width: 100%; height: 300px;"></camera>
        <view class="btn-area">
          <button type="primary" bindtap="takePhoto">拍照</button>
        </view>
        <view class="btn-area">
          <button type="primary" bindtap="startRecord">开始录像</button>
        </view>
        <view class="btn-area">
          <button type="primary" bindtap="stopRecord">结束录像</button>
        </view>
        <view class="preview-tips">预览</view>
        <image wx:if="{{src}}" mode="widthFix" src="{{src}}"></image>
        <video wx:if="{{videoSrc}}" class="video" src="{{videoSrc}}"></video>
      </view>
    </view>
    
    /**
       * 页面的初始数据
       */
      data: {
        src:''
      },
    
      /**
       * 拍照
       */
      takePhoto(){
        let that = this
        //获取相机对象
        const ctx = wx.createCameraContext();
        //通过接口调用拍照方法
        ctx.takePhoto({
          quality:'high',  //高质量
          success:(res)=>{
            // 设定到缓存中
            wx.setStorage({
              key: 'photoPeople',
              data: restempImagePath, //存在本地的图片临时的路径
            })
            // 跳转页面
            wx.redirectTo({
              url: "/page/case/photo",
            })
            that.setData({
              src:res.tempImagePath
            })
          },
          error(e) {
            console.log(e)
          }
        })
      },
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    25、map 地图

    canvas 组件

    画布(原生组件)
    画布 canvas 标签默认宽度 300px、高度 225px
    同一页面中的 canvas-id 不可重复

    <view class="container">
    <!-- 画布区域 -->
      <view class='canvas-area'>
      <!-- 注意:同一个页面中的canvas-id不可重复,如果使用了已经出现过的canvase-id,该canvas标签对于的画布将被隐藏病不再正常工作 -->
        <canvas canvas-id='myCanvas' class='myCanvas'
          disable-scroll='false'
          bindtouchstart='touchStart'
          bindtouchmove='touchMove'
          bindtouchend='touchEnd'
        >
        </canvas>
      </view>
      <!-- 画布工具区域 -->
      <view class='canvas-tools'>
        <!-- 细笔绘制 -->
        <view class='box box1' bindtap='penSelect' data-param='5'></view>
        <!-- 粗笔绘制 -->
        <view class='box box2' bindtap='penSelect' data-param='15'></view>
        <!-- 红色笔 -->
        <view class='box box3' bindtap='colorSelect' data-param='#c03'></view>
        <!-- 黄色笔 -->
        <view class='box box4' bindtap='colorSelect' data-param='#f90'></view>
        <!-- 橡皮 -->
        <view class='box box5' bindtap='clearCanvas'></view>
      </view>
    </view>
    
    
    Page({
      data: {
        pen: 3, //画笔粗细默认值
        color: '#000' //画笔颜色默认值
      },
      startX: 0, //保存X坐标轴变量
      startY: 0, //保存X坐标轴变量
      isClear: false, //是否启用橡皮擦标记
      //手指触摸动作开始
      touchStart: function (e) {
        //得到触摸点的坐标
        this.startX = e.changedTouches[0].x
        this.startY = e.changedTouches[0].y
        this.context = wx.createContext()
    
        if (this.isClear) { //判断是否启用的橡皮擦功能  ture表示清除  false表示画画
          this.context.setStrokeStyle('#F8F8F8') //设置线条样式 此处设置为画布的背景颜色  橡皮擦原理就是:利用擦过的地方被填充为画布的背景颜色一致 从而达到橡皮擦的效果
          this.context.setLineCap('round') //设置线条端点的样式
          this.context.setLineJoin('round') //设置两线相交处的样式
          this.context.setLineWidth(20) //设置线条宽度
          this.context.save();  //保存当前坐标轴的缩放、旋转、平移信息
          this.context.beginPath() //开始一个路径
          this.context.arc(this.startX, this.startY, 5, 0, 2 * Math.PI, true);  //添加一个弧形路径到当前路径,顺时针绘制  这里总共画了360度  也就是一个圆形
          this.context.fill();  //对当前路径进行填充
          this.context.restore();  //恢复之前保存过的坐标轴的缩放、旋转、平移信息
        } else {
          this.context.setStrokeStyle(this.data.color)
          this.context.setLineWidth(this.data.pen)
          this.context.setLineCap('round') // 让线条圆润
          this.context.beginPath()
    
        }
      },
      //手指触摸后移动
      touchMove: function (e) {
    
        var startX1 = e.changedTouches[0].x
        var startY1 = e.changedTouches[0].y
    
        if (this.isClear) { //判断是否启用的橡皮擦功能  ture表示清除  false表示画画
    
          this.context.save();  //保存当前坐标轴的缩放、旋转、平移信息
          this.context.moveTo(this.startX, this.startY);  //把路径移动到画布中的指定点,但不创建线条
          this.context.lineTo(startX1, startY1);  //添加一个新点,然后在画布中创建从该点到最后指定点的线条
          this.context.stroke();  //对当前路径进行描边
          this.context.restore()  //恢复之前保存过的坐标轴的缩放、旋转、平移信息
    
          this.startX = startX1;
          this.startY = startY1;
    
        } else {
          this.context.moveTo(this.startX, this.startY)
          this.context.lineTo(startX1, startY1)
          this.context.stroke()
    
          this.startX = startX1;
          this.startY = startY1;
    
        }
        //只是一个记录方法调用的容器,用于生成记录绘制行为的actions数组。context跟不存在对应关系,一个context生成画布的绘制动作数组可以应用于多个
        wx.drawCanvas({
          canvasId: 'myCanvas',
          reserve: true,
          actions: this.context.getActions() // 获取绘图动作数组
        })
      },
      //手指触摸动作结束
      touchEnd: function () {
    
      },
      //启动橡皮擦方法
      clearCanvas: function () {
        if (this.isClear) {
          this.isClear = false;
        } else {
          this.isClear = true;
        }
      },
      penSelect: function (e) { //更改画笔大小的方法
        console.log(e.currentTarget);
        this.setData({ pen: parseInt(e.currentTarget.dataset.param) });
        this.isClear = false;
      },
      colorSelect: function (e) { //更改画笔颜色的方法
        console.log(e);
        console.log(e.currentTarget);
        this.setData({ color: e.currentTarget.dataset.param });
        this.isClear = false;
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
  • 相关阅读:
    Epoller
    ntfs磁盘格式是什么?NTFS如何读写Mac硬盘?
    从零实现自动求导以及线性回归实例
    uniapp的小程序中使用web-view进行相互传参,并监听web-view的返回键
    vue3语法糖+ts组件传值
    Tensorflow2 中模型训练标签顺序和预测结果标签顺序不一致问题解决办法
    代码随想录算法训练营第67天:图论5[1]
    全光谱台灯对孩子眼睛好吗有辐射吗?普通台灯和LED灯哪个辐射大
    org.springframework.web.reactive.function.server.ServerResponse设置响应头
    【splishsplash】PBD探究
  • 原文地址:https://blog.csdn.net/qq_41988669/article/details/126797962