微信小程序尺寸单位
rpx单位是微信小程序中css的尺寸单位,rpx可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。
设备 rpx换算成px(屏幕宽度/750) px换算成rpx(750/屏幕宽度)
iPhone5 1rpx = 0.42px 1px = 2.34rpx
iPhone6 1rpx = 0.5px 1px = 2rpx
iPhone6s 1rpx = 0.552px 1px = 1.81rpx
所以:在使用微信开发者工具开发时,使用iPhone6模拟器界面浏览效果 根据设计图尺寸*2=小程序尺寸rpx开发即可。
Demo1:tab选项卡
wxml: <view class="nav"> <view class="nav-tab {{currentNavTab==idx ? 'active':''}}" wx:for="{{navTab}}" wx:key="*this" wx:for-index="idx" data-idx="{{idx}}" bindtap="switchTab"> {{item}}{{idx}} </view> </view> js: Page({ data:{ navTab:["待付款","待发货","待收货","待评论"], currentNavTab : 0 }, switchTab:function(e){ this.setData({ currentNavTab: e.target.dataset.idx }) } }); wxss: .nav{display: flex;} .nav-tab{float:left;text-align: center;color:#333;font-size:28rpx;height:80rpx;line-height:80rpx;flex:1;} .nav-tab.active{border-bottom:2px solid #ef4f4f;color:#ef4f4f;}
1.wx:for控制属性绑定一个数组wx:for="{{array}}"
使用 wx:for-item
可以指定数组当前元素的变量名,
使用 wx:for-index
可以指定数组当前下标的变量名
2.target 和 currentTarget
3.bindtap不会阻止事件冒泡 catchtap会阻止事件冒泡
4.列表渲染 使用<block></block>
注意: <block/>
并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
小程序-template模板
一 、定义模板
1、新建一个template文件夹用来管理项目中所有的模板;
2、新建一个courseList.wxml文件来定义模板;
3、使用name属性,作为模板的名字。然后在
2、新建一个courseList.wxml文件来定义模板;
3、使用name属性,作为模板的名字。然后在
<template/>
内定义代码片段。注意:
a.可以看到一个
b.模板中的数据都是展开之后的属性。
a.可以看到一个
.wxml
文件中可以定义多个模板,只需要通过name
来区分; b.模板中的数据都是展开之后的属性。
二、使用模板
1、使用is引用 声明需要引用的模板
<import src="../../templates/courseList.wxml"/>
2、将模板所需要的 data 传入,一般我们都会使用列表渲染。
<block wx:for="{{courseList}}"> <template is="{{index%2 === 0 ? 'courseLeft' : 'courseRight'}}" data="{{...item}}"></template> </block>
三、模板样式
1、在新建模板的时候同时新建一个courseList.wxss
的文件,与CSS同样的写法控制样式。
2、在需要使用模板的页面 (父页面).wxss
文件中import
进来;或者直接在app.wxss中引入,这样只需要一次引入,其他文件就不用引入了。
@import "../template/courseList.wxss";
小程序-组件
picker
从底部弹起的滚动选择器,现支持五种选择器,通过mode来区分,分别是普通选择器,多列选择器,时间选择器,日期选择器,省市区选择器,默认是普通选择器。
普通选择器:mode = selector
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
range | Array / Object Array | [] | mode为 selector 或 multiSelector 时,range 有效 |
range-key | String | 当 range 是一个 Object Array 时,通过 range-key 来指定 Object 中 key 的值作为选择器显示内容 | |
value | Number | 0 | value 的值表示选择了 range 中的第几个(下标从 0 开始) |
bindchange | EventHandle | value 改变时触发 change 事件,event.detail = {value: value} | |
disabled | Boolean | false | 是否禁用 |
Demo:
<view class="section"> <view class="section__title">普通选择器</view> <picker bindchange="bindPickerChange" value="{{index}}" range="{{array}}"> <!-- {{index}}表示选中了range对应项中的第几项 --> <view class="picker"> 当前选择:{{array[index]}} </view> </picker> </view>
Page({ data: { array:['男','女'] }, bindPickerChange:function(e){ var genderIndex = e.detail.value; this.setData({ index: genderIndex }) }, });
小程序-获取文本框的值的两种方式
方式一:
<!-- form表单提交 --> <form bindsubmit="saveInfo" type="submit"> <input type="text" name="username" value="{{username}}"/> <input type="password" name="pwd" value="{{pwd}}"/> <button formType="submit" class="edit-btn">保 存</button> </form>
Page({ saveInfo:function(e){ var data = e.detail.value; console.log(data); this.setData({ username: data.username, pwd: data.pwd }) } })
方式二:
<view> <input type="text" bindinput='userName' value="{{username}}"/> <input type="password" bindinput='password' value="{{pwd}}"/> <button bindtap="saveInfo1">保 存</button> </view>
Page({ userName:function(e){ this.setData({ userName:e.detail.value }) }, password: function (e) { this.setData({ pwd: e.detail.value }) }, saveInfo1:function(){ console.log(this.data.userName+"//"+this.data.pwd); } })
小程序-图片的binderror事件
1 <view class="service-list" wx:for="{{productList}}" wx:for-index="idx" wx:key="productList" wx:for-item="item"> 2 <navigator url="../product/index?id={{item.ShopID}}" class="item"> 3 <view class="pic_item"><image src="{{item.ImagePath}}" class="pic" binderror="binderrorimg" data-errorimg="{{idx}}"></image></view> 4 <view class="content_item"> 5 <view class="title_item">{{item.ProductName}}</view> 6 <view class="price"> 7 <text>¥</text>{{item.ShopAttrList[0].Price}}</view> 8 <view class="item_bottom"><text>深圳市</text><text class="split-line">|</text><text>销量0 单</text></view> 9 </view> 10 </navigator> 11 </view>
1 var commonJs = require("../../Static/js/common.js"); 2 3 Page({ 4 data:{productList:[]} 5 binderrorimg:function(e){ 6 var that = this; 7 commonJs.binderrorimg(e,that); 8 } 9 10 })
1 function binderrorimg(e,that) { 2 var errorImgIndex = e.target.dataset.errorimg; //获取循环的下标 3 var imgObject = "productList[" + errorImgIndex + "].ImagePath" //productLisy为数据源,对象数组 4 var errorImg = {} 5 errorImg[imgObject] = "http://xxx.com/Static/images/Public/img_null-120.png" //图片报错或无图片显示时 用来代替的图片 6 that.setData(errorImg) //修改数据源对应的数据 7 } 8 9 module.exports = { 10 binderrorimg: binderrorimg 11 } 12
小程序-wxRequest封装及使用
common.js
1 module.exports = { 2 webApi : "http://localhost:8779", 3 GET: GET, 4 POST: POST 5 } 6 7 8 var requestHandler = { 9 data: {}, 10 url:"", 11 success: function (res) { 12 // success 13 }, 14 fail: function () { 15 // fail 16 }, 17 } 18 19 //GET请求 20 function GET(requestHandler) { 21 request('GET', requestHandler) 22 } 23 //POST请求 24 function POST(requestHandler) { 25 request('POST', requestHandler) 26 } 27 28 function request(method, requestHandler) { 29 30 var host = module.exports.webApi; 31 var data = requestHandler.data; 32 var apiUrl = requestHandler.url; 33 var userId = wx.getStorageSync('userId'); 34 var device = wx.getStorageSync('device'); 35 wx.request({ 36 url: host + apiUrl, 37 data: data, 38 method: method, 39 //此处因为请求后台需要header中的两个参数 所以直接写在封装方法里 40 header: { 41 'AccessId': userId, 42 'Req-Device': device 43 }, 44 success: function (res) { 45 requestHandler.success(res) 46 }, 47 fail: function () { 48 requestHandler.fail() 49 } 50 }) 51 } 52 53
以下app.js文件代码包含以下内容:
wx.Request封装方法的使用
授权登录接口的使用
检测当前用户登录态是否有效
获取操作系统版本信息
数据缓存
拒绝授权后提示确认授权操作
1 //app.js 2 var commonJs = require("Static/js/common.js"); 3 App({ 4 5 onLaunch: function () { 6 7 var userId = wx.getStorageSync('userId');// 绑定成功的后台返回userId 8 // 获取操作系统版本信息 9 var device = ''; 10 wx.getSystemInfo({ 11 success: function (res) { 12 device = res.system; 13 wx.setStorageSync('device', device); 14 } 15 }), 16 17 // 检测当前用户登录态是否有效 18 wx.checkSession({ 19 success:function(){ 20 //session 未过期,并且在本生命周期一直有效 21 }, 22 fail:function(){ 23 // 登录 24 wx.login({ 25 success: function (res) { 26 // 发送 res.code 到后台换取 openId, sessionKey, unionId 27 if (res.code) { 28 wx.getUserInfo({ 29 withCredentials: true, 30 success: function (res_user) { 31 //发起请求 32 commonJs.POST( 33 { 34 data: { 35 code: res.code, 36 encryptedData: res_user.encryptedData, 37 iv: res_user.iv 38 }, 39 url: '/Login/LoginByCode', 40 success: function (res) { 41 console.log(res) 42 if (res.data.Success) { 43 var isBind = res.data.Data.IsBind; 44 } 45 46 var rdm = res.data.Data.Rdm; 47 if (isBind) { 48 console.log("登录成功"); 49 if (res.data.Data.UserID) { 50 wx.setStorageSync('userId', res.data.Data.UserID); 51 } 52 } 53 54 }, 55 fail: function () { 56 wx.navigateTo({ 57 url: '../bindMobile/index?rdm=' + rdm + '' 58 }) 59 }, 60 }) 61 }, 62 63 fail: function () { 64 wx.showModal({ 65 title: '警告通知', 66 content: '您点击了拒绝授权,将无法正常显示个人信息,点击确定重新获取授权。', 67 success: function (res) { 68 if (res.confirm) { 69 //设置界面只会出现小程序已经向用户请求过的权限。 70 wx.openSetting({ 71 success: function () { 72 wx.login({ 73 success: function (res) { 74 if (res.code) { 75 wx.getUserInfo({ 76 withCredentials: true, 77 success: function (res_user) { 78 79 commonJs.POST( 80 { 81 data: { 82 code: res.code, 83 encryptedData: res_user.encryptedData, 84 iv: res_user.iv 85 }, 86 url: '/Login/LoginByCode', 87 success: function (res) { 88 if (res.data.Success) { 89 var isBind = res.data.Data.IsBind; 90 } 91 var rdm = res.data.Data.Rdm; 92 if (isBind) { // 授权成功并绑定手机号/邮箱成功 才代表登录成功 93 console.log("登录成功"); 94 if (res.data.Data.UserID) { 95 wx.setStorageSync('userId', res.data.Data.UserID); 96 } 97 98 } else { // 若授权成功但未绑定手机号/邮箱 则跳转到手机/邮箱绑定界面 99 wx.navigateTo({ 100 url: '../bindMobile/index?rdm=' + rdm + '' 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
小程序-携带参数跳转界面并在该界面获取参数
以以上代码跳转链接为例: url : '../bindMobile/index?rdm=' + rdm + ''
在该界面的onLoad事件中获取
1 Page({ 2 onLoad: function (options) { 3 var that = this; 4 that.setData({ 5 rdm: options.rdm 6 }) 7 } 8 }
小程序-获取点击到的元素的值
注意:以下js
1 <view class="search_button_box clearfix"> 2 <block wx:for="{{hotWordList}}" wx:key="hotword" wx:for-item="item"> 3 <view class="item" bindtap="searchHotWordTap" data-name="{{item.ShowName}}">{{item.ShowName}}</view> 4 </block> 5 </view>
1 searchHotWordTap:function(e){ 2 var that = this; 3 var hotWord = e.currentTarget.dataset.name; // 此处的name与被点击元素的data-xx 的 xx对应 4 that.setData({ 5 keyWord: hotWord 6 }) 7 }
小程序-实现文本框数量的增减
1 <view class="cart_num cf"> 2 <button class="cart_min pull-left" bindtap='cutNumTap'>-</button> 3 <input class="cart_text_box" value="{{cartNum}}" type="text" bindchange='bindCartNum' /> 4 <button class="cart_add pull-right" bindtap='addNumTap'>+</button></view>
Page({ data:{ cartNum:1 }, onLoad:function(){ }, cutNumTap:function(){ var that = this; var num = that.data.cartNum; if(num > 1){ num--; } that.setData({ cartNum: num }) }, addNumTap:function(){ var that = this; var num = that.data.cartNum; num++; that.setData({ cartNum: num }) }, bindCartNum:function(e){ var that = this; var num = e.detail.value; that.setData({ cartNum: num }) } })