微信小程序开发-2(原生)-具体开发-1

数据绑定:

1.data 中定义数据(在页面对应的 .js 文件中,把数据定义到data 对象中)

2. 在WXML 中使用数据(把data 中的数据绑定到页面中渲染,使用Mustache 语法(双大括号)将变量包起来即可)

// index.js

page({
    data:{
       info:'hello'
    }
})

// index.wxml

<view>{{info}}</view>

// Mustache 语法的主要应用场景如下(动态绑定与vue 种不同的是不用绑定v-bind(:),直接使用{{}}包起来就行,例如:<img src='{{url地址}}'></img>):
// 1. 绑定内容
// 2. 绑定属性
// 3. 运算(三元运算、算数运算等)

// 三元运算
// index.js
page({
data:{
randomNum:Math.random() * 10 // 生成10以内的随机数
}
})

// index.wxml
<view>{{randomNum >= 5 ? '大于或等于5' : '小于5'}}</view>
 
// 算数运算
// index.js
page({
data:{
randomNum:Math.random().toFixed(2) // 生成一个带两位小数的随机数
}
})

// index.wxml
<view>生成100以内的随机数:{{randomNum * 100}}</view>

 

事件绑定:

是渲染层到逻辑层的通讯方式,通过事件可以将用户在渲染层产生的行为,反馈到逻辑层进行业务的处理。

小程序中常用的事件:

 

当事件回调触发的时候,会收到一个事件对象event,它的详细属性如下:

 

 

// target 和currentTarget 区别
// target 是触发该事件的源头组件,而currentTarget 则是当前事件所绑定的组件
// 例:点击内部的按钮时,点击事件以冒泡的方式向外扩散,也会触发外层view 的tap 事件处理函数,此时对于外层 view 来说,
// e.target 指向的是触发事件的源头组件,因此,e.target 是内部的按钮组件
// e.currentTarget 指向的是当前正在触发事件的那个组件,因此,e.currentTarget 是当前的view 组件

<view bindtap='outerHandler'>
    <button type='primary'>按钮</button>
</view>

 

// bindtap 语法
// 在小程序中,不存在HTML 中的onclick 鼠标点击事件,而是通过tap 事件来响应用户的触摸行为
// 1. 通过bindtap 可以为组件绑定tap 触摸事件
<button type='primary' bindtap='btnTapHandler'></button>

// 2. 在页面的 .js 文件中定义对用的事件处理函数,事件参数通过形参 event(一般简写成 e)来接收
page({
   batTapHandler(e){
       console.log(e)   // 打印事件参数对象 e
   }
})

 

// 在事件处理函数中为 data 中的数据赋值
// 通过调用 this.setData(dataObject) 方法,可以给页面 data 中的数据重新赋值

// 页面的 html 文件
<button type='primary' bindtap='changeCount'>+1</button>

// 页面的 .js 文件
page({
   data:{
      count:0
   }
})

changeCount(){  // 修改 count 值
    this.setData({
       count:this.data.count +1
    })
}

 

// 事件传参(小程序中的事件传参比较特殊,不能在绑定事件的同时为事件处理函数传递参数)
// 例如vue中的绑定事件后面跟着小括号内写入传参值,这种就不可行
// 因为小程序会把 bindtap 的属性值,统一当作事件名称来处理,相当于要调用一个名称 btnHandler(123) 的事件处理函数


// 可以为组件提供 data-* 自定义属性传参,其中 * 代表的是参数的名字
// 例:下面传递一个名为 info 的参数值 为2
// info 会被解析为参数的名字,数值2 会被解析为参数的值
<button bindtap='btnHandler' data-info='{{2}}'>传递参数 info</button>

// 在事件处理函数中,通过event.target.dataset.参数名 获取具体参数的值
btnHandler(event){
   console.log(event.target.dataset) // dataset 是一个对象包含了所有通过 data-* 传递过来的参数项
   console.log(event.target.dataset.info) // 通过dataset 可以访问到具体参数的值
}

 

// bindinput (小程序中通过input 事件来影响文本框的输入事件)

// 通过bindinput 可以为文本框绑定输入事件
<input bindinput='inputHandler'></input>

// 页面的.js 文件中定义事件处理函数
inputHandler(e){
   console.log(e.detail.value)  // e.detail.value 是变化后文本框最新的值
}

 

// 实现文本框和data 中间的数据同步
// 1. 定义数据==》2. 渲染结构==》3. 美化样式==》4. 绑定input 事件处理函数

//.js 文件中
page({
   data:{
     msg:'hello!    '
   }
})

iptHandler(e){ // 重新赋值
   this.setData({
       msg:e.detail.value  // 通过e.detail.value 获取到文本框最新的值
   })
}

// .wxml 文件中
<input value='{{msg}}' bindinput='iptHandler'></input>

// .wxss 文件中
input{
  border:1rpx solid #eee;
  padding:5rpx;
  margin:5rpx;
  border-radius:3rpx;
}

 

// 条件渲染     wx:if
// 小程序中使用 wx:if="{{condition}}" 来判断是否需要渲染该代码块,例:
<view wx:if="{{condition}}">true</view>

// 也可以用wx:elif 和 wx:else 来添加else 判断,例:
<view wx:if="{{type === 1}}">男</view>
<view wx:elif="{{type === 2}}">女</view>
<view wx:else="{{type === 3}}">保密</view>


// 结合 <block> 使用 wx:if
// 如果要一次性控制多个组件的展示与隐藏,可以使用一个<block></block> 标签将多个组件包装起来,并在<block> 标签上使用 wx:if 控制属性,例:
// 注意:<block> 不是一个组件,它只是一个包裹性质的容器,不会在页面中做任何渲染
<block wx:if="{{true}}">
   <view>显示值1</view>
   <view>显示值2</view>
</block>

 

// 条件渲染   hidden
// 小程序中直接使用hidden="{{condition}}" 也能控制元素的显示与隐藏,例:
<view hidden="{{condition}}">条件为 true 隐藏,条件为false 显示</view>

 

// wx:if 与 hidden :
// 1. 运行方式不同
// 1-1. wx:if 以动态创建和移除元素的方式,控制元素的展示与隐藏
// 1-2. hidden 以切换样式的方式(display:none/block)控制元素的显示与隐藏

// 2. 使用建议
// 2-1. 频繁使用时,建议使用hidden
// 2-2. 控制条件复杂时,建议使用 wx:if 搭配wx:elif、wx:else 进行展示与隐藏的切换

 

// 列表渲染 wx:for(通过 wx:for 可根据指定的数组,循环渲染重复的组件结构)
// 默认情况下,当前循环项的索引用index 表示,当前循环项用item 表示
<view wx:for="{{array}}">索引时:{{index}},当前值是:{{item}}</view>


// 可以手动指定索引和当前想的变量名
// 使用wx:for-index 可以指定当前循环项的索引的变量名
// 使用wx:for-item 可以指定当前想的变量名
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">索引时:{{idx}},当前项是:{{itemName}}</view>


// wx:key 的使用(类似于vue 列表渲染中的:key ,小程序在列表渲染时也建议为渲染的列表项指定唯一的key 值,从而提高渲染的效率)

// data 数据
data:{
   userList:[
     {id:1,name:'小红'},
     {id:2,name:'小黄'},
     {id:3,name:'小白'},
   ]
}
// wxml 结构
<view wx:for="{{userList}}" wx:key='id'>{{item.name}}</view>

下面开始介绍下WXSS 模板样式:

WXSS(WeiXin style Sheets)是一套样式语言,用于美化WXML 的组件样式,类似于网页开发中的css

WXSS 和 CSS 的关系:

WXSS 具有CSS 大部分特性,同时,WXSS 还对CSS 进行了扩充以及修改,以适应微信小程序的开发,与CSS 相比,WXSS 扩展的特性有(1. rpx 尺寸单位;2. @import 样式导入)

 

 

 

// rpx(responseive pixel) 是微信小程序独有的,用来解决屏适配的尺寸单位
// rpx 的实现原理:
// 鉴于不同设备屏幕的大小不同,为了实现屏幕的自动适配,rpx 把所有设备的屏幕在宽度上等分位750 份(即:当前屏幕的总看宽度为750rpx)
// 在较小的设备上,1rpx 所代表的宽度较小
// 在较大的设备上,1rpx 所代表的宽度较大
// 小程序在不同设备上运行的时候,会自动把rpx 样式单位换算成对应的像素单位来渲染,从而实现屏幕适配

// rpx 和 px 之间的单位换算
// 在iPhone6 上,屏幕宽度为375px,共有750个物理像素,等分为750rpx则:
// 750rpx = 375px =750物理像素
// 1rpx = 0.5px = 1 物理像素

// 官方建议:开发小程序时,设计师可以用iPhone6 作为视觉稿的标准

// 样式导入(使用wxss 提供的@import 语法,可以导入外联的样式表)
// @import 后跟需要导入的外联样式表的相对路径,用 ; 表示语句结束

// commpon.wxss(公共样式文件)
.small{
    padding:5px;
}

// index.wxss(页面的样式文件)
@import "commpon.wxss";
.middle{
  padding:15px;
}

全局样式:定义在app.wxss 中的样式为全局样式,作用于每一个页面

局部样式:在页面的.wxss 文件中定义的样式为局部样式,只作用于当前页面

注意:

1. 当局部样式和全局样式冲突时,根据就近原则,局部样式会覆盖全局样式

2. 当局部样式的权重大于或等于全局样式的权重时,才会覆盖全局的样式

全局配置

全局配置文件及常用的配置项(小程序根目录下的app.json文件是小程序的全局配置文件,常用的配置项如下):

1. pages(记录当前小程序所有页面的存放路径)

2. window(全局设置小程序窗口的外观)

3. tabBar(设置小程序底部的tabBar效果)

4. style(是否启用新版的组件样式)

之前已经说过pages和style的配置,这里重点说下window和tabBar

window配置项(如下图所示,window配置的主要是红色导航栏区域):

 

 

 window 节点常用的配置项:

 

 

 

// 设置导航栏的标题(例:把顶部导航条上的标题从默认的 WeChat 改为 某某商城)
// app.json==》window==>navigationBarTitleText


// 设置导航栏的背景色
// app.json==》window==》navigationBARBackgroundColor


// 设置导航栏的标题颜色(可选值只有black 和 white)
// app.json==》window==》navigationBarTextStyle


// 全局开启下拉刷新功能(在app.json中启用下拉刷新功能,会作用于每个小程序页面)
// 下拉刷新是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为
// app.json==》window==》enablePullDownRefresh(设置为true)
// 注意:模拟器的效果不能真正100%还原手机的使用效果,类似下拉功能这种还是要用真机测试


// 设置下拉刷新时窗口的背景颜色(当全局开启下拉刷新功能之后,默认的窗口背景为白色)
// app.json==》window==》为backgroundColor指定16进制的颜色值


// 设置下拉刷新时loading 的样式(全局开启下拉刷新功能后,默认窗口的loading样式(三个小圆点)为白色)
// app.json==》window==》为backgroundTextStyle指定dark值(可选值只有light 和dark)


// 设置上拉触底的距离
// 是指移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为
// app.json==》window==》为onReachBottomDistance 设置新的数值
// 注意:默认距离值为50px,如果没有特殊需求,建议使用默认值即可(意思就是在右侧的滚动条距离页面底部不足50px的时候就自动触发加载下一页的行为)

tabBar配置项(tabBar是移动端应用常见的页面效果,用于实现多页面的快速切换,如下图所示,小程序通常tabBar分为两种 == 底部tabBar;顶部tabBar):

 

 

注意:

1. tabBar 中只能配置最少2个,最多5个tab页签

2. 当渲染顶部tabBar 时,不显示icon ,只显示文本

tabBar 的6个组成部分:

 

 

在app.json 中配置tabBar,节点的配置项如下:

 

 

 其中,每个tab 项的配置选项如下:

 

 

 实现tabBar的配置步骤:拷贝图标资源==》新建3个对应的tab页面==》配置tabBar选项

注意:tabBar的页面必须放在pages的最前面

 

 

 

页面配置文件的作用:小程序中,每个页面都有自己的.json 配置文件,用来对当前页面的窗口外观、页面效果等进行配置。

页面配置和全局配置的关系:

1. 小程序中,app.json中的window 节点,可以全局配置小程序中么个页面的窗口表现。

2. 如果某些小程序页面想要拥有特殊的窗口表现,此时,页面级别的.json 配置文件就可以实现这种需求。

注意:当页面配置与全局配置冲突时,根据就近原则最终的效果以页面配置为准

页面配置中常用的配置项:

 

 

 

网络数据请求:

小程序中网络数据请求的限制(出于安全性方面的考虑,小程序官方对数据接口的请求做出了如下两个限制):

1. 只能请求HTTPS 类型的接口

2. 必须将接口的域名添加到信任列表中

 

 

 如何配置 request 合法域名(假设自己的微信小程序中,希望请求https://www.*****/ 域名下的接口):

配置步骤:登录微信小程序管理后台==》开发==》开发设置==》服务器域名==》修改request 合法域名

 

 

 

 

 

 注意:

1. 域名只支持https 协议

2. 域名不能使用 IP 地址或 localhost

3. 域名必须经过ICP 备案

4. 服务器域名一个月内最多可申请5次修改

// 发起get 请求(调用微信小程序提供的 wx.request() 方法,可以发起get 数据请求)

// 页面的 .wxml 文件
<button bindtap='getInfo'>发起get 请求</button>

// 页面的 .js 文件
getInfo(){
    wx.request({
        url:'http://www.escook.cn/api/get',  // 请求的接口地址,必须基于https 协议并且已经配置过
        method:'GET', // 请求的方式
        data:{     // 发送到服务器的数据
           name:'tom',
           age:22
        },
        success:(res) => {   // 请求成功之后的回调函数
           console.log(res) 
        }
    })
}



// 发起post 请求(调用微信小程序提供的 wx.request() 方法,可以发起post 数据请求)

// 页面的.wxml 文件
<button bindtap='postInfo'>发起post 请求</button>

// 页面的.js 文件
postInfo(){
    wx.request({
         url:'https://www.escook.cn/api/post',
         method:'POST',
         data:{
             name:'tom',
             age:33
         },
         success:(res)=>{
             console.log(res)
         }
    })
}


// 在页面刚加载时请求数据
// 需要在页面刚加载的时候,自动请求一些初始化的数据,此时需要在页面的 onLoad 事件中调用获取数据的函数


// 页面的 .js 文件中(找到onLoad事件)
onLoad:function(){
    this.getInfo()

    this.postInfo()

}

跳过 request 合法域名校验:

如果后端仅仅提供了 http 协议的接口,暂时没有提供 https 协议的接口,此时为了不耽误开发进度,可以在微信开发者工具中,临时开启(开发环境不校验请求域名、TLS 版本及HTTPS证书 几个选项),跳过request 合法域名的校验

注意:跳过 request 合法域名校验的选项,仅限在开发与调试阶段使用

 

 关于跨域 和 Ajax :

1. 跨域问题只存在于基于浏览器的web 开发中。由于小程序的宿主环境不是浏览器,而是微信客户端,所以小程序中不存在跨域问题

2. Ajax 技术的核心是依赖于浏览器中的 XMLHttpRequest 这个对象,由于小程序的宿主环境是微信客户端,所以小程序中不能叫做"发起Ajax 请求",而叫"发起网络数据请求"

 

下面介绍下小程序中的视图与逻辑:

什么是页面导航:页面导航指的是页面之前的相互跳转。

例如:浏览器中实现页面导航的方式:1.<a> 链接  2. location.href

小程序中实现页面导航的两种方式:

1. 声明式导航( 在页面声明一个<navigator> 导航组件,通过点击<navigator> 组件实现页面跳转)   

2. 编程式导航(调用小程序的导航API ,实现页面的跳转)

// 声明式导航

//
导航到 tabBar 页面(tabBar页面指的是被配置为 tabBar 的页面) // 在使用 <navigator> 组件跳转到指定的tabBar 页面时,需要指定url 属性和 open-type 属性 // url 表示要跳转的页面的地址,必须 / 开头 // open-type 表示跳转的方式,必须为 switchTab // 单击页面里的文本跳转到tabBar 上对应的导航页面 <navigator url='/pages/message/message' open-type='switchTab'>导航到消息页面</navigator> // 导航到非tabBar 页面(非 tabBar 页面指的是没有被配置为tabBar的页面) // 在使用<navigator> 组件跳转到普通的非 tabBar 页面时,则需要指定url 属性和 open-type 属性 // url 表示要跳转的页面的地址,必须 / 开头 // pen-type 表示跳转的方式,必须为 navigate // 注意:为了简便,在导航到非tabBar 页面时,open-type=‘navigate’ 属性可以省略 // 点击页面里的文本跳转到对应的非tabBar 的普通页面 <navigator url='/pages/info/info' open-type='navigate'>导航到info页面</navigator> // 后退导航(如果要后退到上一页面或多级页面,则需要指定open-type 属性和 dalta 属性) // open-type 的值必须是navigateBack,表示要进行后退导航 // delta 的值必须是数字,表示要后退的层级 // 注意:为了简便,如果只是后退到上一页面,则可以省略 delta 属性,因为其默认值就是1 // 点击页面里的文本,后退到上一个页面 <navigator open-type='navigateBack' delta=''1>返回上一级</navigator>

 

// 声明式导航传参
// navigate 组件的 url 属性用来指定将要跳转到的页面的路径,同时,路径的后面还可以携带参数
// 1. 参数与路径之间使用 ?分隔
// 2. 参数键与参数值用 = 相连
// 3. 不同参数用 & 分隔
<navigator url='/pages/info/info?name=tom&age=20'>跳转到熬info页面时的传参</navigator>

编程式导航

导航到tabBar 页面(调用 wx.switchTab(Object,Object) 方法,可以跳转到tabBar 页面,其中 Object 参数对象的属性列表如下:)

// 导航到tabBar 页面

// 页面结构
<button bindtap='gotoMessage'>跳转到消息页面</button>

// 通过编程式导航,跳转到 message 页面
gotoMessage(){
   wx.switchTab({
      url:'pages/message/message'
   })
}

导航到非 tabBar 页面(调用 wx.navigateTo(Object,Object) 方法,可以跳转到非tabBar的页面,其中Object 参数对象的属性列表如下:)

// 导航到非 tabBar 页面

// 页面结构
<button bindtap='gotoInfo'>跳转到info页面</button>

// 通过编程式导航,跳转到info 页面
gotoInfo(){
   wx.navigateTo({
      url:'/pages/info/info'
   })
}

后退导航(调用 wx.navigateBack(Object,Object) 方法,可以返回上一页面或多级页面,其中Object 参数对象可选的属性列表如下:)

// 后退导航

// 页面结构
<button bindtap='gotoBack'>后退</button>

// 编程式导航,后退到上一页面
gotoBack(){
   wx.navigateBack()
}

 

// 编程式导航传参
// 调用 wx.navigateTo(Object,Object) 方法跳转页面时,也可以携带参数

// 页面结构
<button bindtap='gotoInfo2'>跳转到info页面</button>

// 通过编程式导航,跳转到info 页面,并携带参数
gotoInfo2(){
    wx.navigateTo({
        url:'/pages/info/info?name=tom&age=10'
    })
}

 

// 在onLoad 中接收导航参数
// 通过声明式导航传参或编程式导航传参所携带的参数,可以直接在onLoad 事件中直接获取到

onLoad:function(options){
   console.log(options)   // options 就是导航传递过来的参数对象
}

页面事件(下拉刷新)

下拉刷新是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为

启用下拉刷新有两种方式:

1. 全局开启下拉刷新(在app.json 的window 节点中,将enablePullDownRefresh 设置为true)

2. 局部开启下拉刷新(在页面的.json 配置文件中,将enablePullDownRefresh 设置为true)

实际开发中,推荐使用第二种方式为需要的页面单独开启下拉刷新的效果

 

配置下拉刷新窗口的样式:

在全局或页面的.json 配置文件汇总,通过 backgroundColor 和 backgroundTextStyle 来配置下拉刷新窗口的样式

backgroundColor 用来配置下拉刷新窗口的背景颜色,仅支持16进制的颜色值

backgroundTextStyle 用来配置下拉刷新loading 的样式,仅支持dark 和light

 

监听页面的下拉刷新事件:

在页面的.js 文件中,通过 onPullDownRefresh() 函数即可监听当前页面的下拉刷新事件

// 页面中的 .js 文件

onPullDownRefresh:function(){
   console.log('触发了页面的下拉刷新...')
}

 

停止下拉刷新的效果:

当处理完下拉刷新后,下拉刷新的loading 效果会一直显示,不会主动消失,所以需要手动隐藏loading 效果,此时,调用 wx.stopPullDownRefresh() 可以停止当前页面的下拉刷新

// 页面的.js 文件

onPullDownRefresh:function(){ this.setData({ count:0 }) wx.stopPullDownRefresh() // 当数据重置成功后,调用此函数关闭下拉刷新的效果 }

 

上拉触底事件

什么是上拉触底:是移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为

监听页面的上拉触底事件(在页面 .js 文件中,通过 onReachBottom() 函数即可监听当前页面的上拉触底事件)

监听事件是可以重复发起的,实际项目中可以做节流处理,同一时间内放置重复下拉刷新,当上一个没有完成时,禁止再次请求

 

 配置上拉触底距离(这个指的是触发上拉触底事件时,滚动条距离页面底部的距离。可以在去全局或页面的 .json 配置文件中,通过onReachBottomDistance 属性来配置上拉触底的距离)

 

// 上拉触底刷新(节流)案例

// .wxml
<view 
  wx:for="{{colorList}}" 
  wx:key='index' 
  class="num-item" 
  style="background-color:rgba({{item}})">
  {{item}}
</view>

// .wxss
.num-item{
  border: 1rpx solid #efefef;
  border-radius: 8rpx;
  line-height: 200rpx;
  margin: 15rpx;
  text-align: center;
  text-align: center;
  text-shadow: 0rpx 0rpx 5rpx #fff;
  box-shadow: 1rpx 1rpx 6rpx #aaa;
}

// .js
data: {
    colorList:[], // 列表值
    isLoading:false, // 定义节流阀
},

getColors(){ // 调接口获取列表
    this.setData({ // 开启节流阀
      isLoading:true
    })
    wx.showLoading({ // 上拉触底时展示loading效果
      title: '数据加载中....',
    })
    wx.request({ // 调接口获取列表
      url: 'https://www.escook.cn/api/color',
      method:'get',
      success:({data:res})=> {
        this.setData({
          colorList:[...this.data.colorList,...res.data]
        })
        console.log(this.data.colorList,'getColors')
      },
      complete:()=>{ // 不论结果成功还是失败隐藏loading效果
        wx.hideLoading()
        this.setData({
          isLoading:false
        })
      }
    })
},

onLoad: function (options) {
    this.getColors()
},

onReachBottom: function () {  // 页面上拉触底事件的处理函数
    if(this.data.isLoading) return
    this.getColors()
},

每次保存代码后自动编译后的页面跳转到指定页面:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    

 

posted on 2022-05-14 15:06  一名小学生呀  阅读(336)  评论(0编辑  收藏  举报

导航