微信小程序学习记录
小程序文件结构
wxml(对应html),wxss(对应css),js(对应js),json配置文件
app.json
{
"pages":[
"pages/index/index",
"pages/logs/logs",
"pages/demo/demo"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "Weixin",
"navigationBarTextStyle":"black"
},
"style": "v2",
"sitemapLocation": "sitemap.json"
} |
注意:
navigationBarTextStyle值必须为black或者white
window.backgroundTextStyle 字段需为 dark,light
更多参考设置
https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/page.html
checkbox
<checkbox checked="{{checked}}"></checkbox> checked为false
<checkbox checked=" {{checked}}"></checkbox> checked为false,有空格会选中 |
循环
<view wx:for="{{lists}}" wx:for-item="item" wx:key="id">
{{item.id}} -- {{index}} -- {{item.name}}
</view> |
隐藏标签
wx:if 当标签不是频繁的切换显示 优先使用
hidden 当标签频繁的切换显示的时候,优先使用hidden
获取输入框的值
<input type="text" bindinput="handleInput"/>
handleInput(e){
console.log(e)
this.setData({
num:e.detail.value
})
} |
按钮事件
<button bindtap="plus" data-num="{{1}}">+</button>
plus(e){
console.log(e.currentTarget.dataset.num)
this.setData({
num: this.data.num + e.currentTarget.dataset.num
})
} |
注意:data-num=”1″ 会被识别为字符串
rpx
rpx可以根据屏幕尺寸进行自适应,规定屏幕宽度为750rpx,如在iphone6上,屏幕宽度为375px,共有750个物理像素,则750rpx=375px=750物理像素,1rpx = 0.5px = 1物理像素
需要把页面中某些元素的单位 由px改成rpx
①设计稿750px
750px = 750rpx
1px = 1rpx
②把屏幕宽度改为 375px(iphone678尺寸)
375px = 750rpx
1px = 2rpx
1rpx = 0.5px
③存在一个设计稿 宽度 414 或者 未知宽度 widthNum
1.设计稿page存在一个元素,宽度为100px,如何适配
widthNum px = 750rpx
1px = 750rpx/widthNum
100px= 750rpx * 100 / widthNum
比如设计稿为414时,1px = 750rpx/414 = 1.81159420, 100px 为 181rpx (750rpx * 100 / 414),wxss中可以写calc(750rpx * 100 / 414)
app.wxss样式引入字体样式
引入的代码是通过@import来引入的,路径只能写相对路径
@import "./styles/iconfont.wxss";
/* 在微信小程序中不支持*通配符 */
page,view,text,swiper,swiper-item,image,navigator {
padding: 0;
margin: 0;
box-sizing: border-box;
}
page {
/*定义主题颜色*/
--themeColor: #eb4450;
/* 定义统一字体大小 假设设计稿大小是 375px
1px = 2rpx
14px = 28rpx
*/
font-size: 28rpx;
}
image{
width: 100%;
} |
vscode使用less输出wxss文件配置
在vscode的设置中加入如下配置
"less.compile":{
"outExt":".wxss"
} |
swiper
1.swiper标签存在默认样式
①width:100% ②height:150px image存在默认宽度和高度 ③swiper高度无法实现由内容撑开
2.先找出来原图的宽度和高度 等比例给swiper设定宽度和高度
原图的宽度和高度 1024 * 768px
swiper宽度 / swiper高度 = 原图的宽度/原图的高度
swiper高度 = swiper宽度 * 原图的高度/原图的宽度
height:100vw * 768 / 1024
<swiper class="swiper" indicator-dots >
<swiper-item>
<image mode="widthFix" src="https://car2.autoimg.cn/cardfs/product/g14/M0D/B1/45/1024x0_1_q95_autohomecar__ChsEvWA3aPiAOgIOABsTvS_C-O8702.jpg"/>
</swiper-item>
<swiper-item>
<image mode="widthFix" src="https://car2.autoimg.cn/cardfs/product/g14/M0A/B1/45/1024x0_1_q95_autohomecar__ChsEvWA3aPeAYSu9ABmyOa8xNbs093.jpg"/>
</swiper-item>
<swiper-item>
<image mode="widthFix" src="https://car2.autoimg.cn/cardfs/product/g14/M0B/B1/51/1024x0_1_q95_autohomecar__ChwEoGA3aPaAbcciABvyVzokfFk000.jpg"/>
</swiper-item>
</swiper>
swiper {
width: 100%;
height: calc(100vw*768/1024);
}
swiper image {
width: 100%;
} |
navigator
1.块级元素
2.url 要跳转的路径 绝对路径 或 相对路径
3.open-type跳转的方式
navigate默认 保留当前页面,跳转到应用内的某个页面,但是不能跳到tabbar
redirect 关闭当前页面,跳转到应用内的某个页面,但是不允许跳转到tabbar页面。
switchTab 跳转到tabbar页面,并关闭其他所有非tabbar页面
reLaunch 关闭所有页面,打开到应用内的某个页面
navigateBack 关闭当前页面,返回上一页面或多级页面,可通过getCurrentPages()获取当前的页面栈,决定需要返回几层
exit 退出小程序,target=”miniProgram”时生效
rich-text
// 第一种方式
// html:'<div style="font-weight:bold;">哈哈哈</div>',
// 第二种方式
html: [{
name: "div", //html标签
attrs: { //class 和 style属性
class: "my_div",
style: "color:red"
},
children: [{ //子节点
name: "p",
attrs: {
},
children: [{ // 文本
type: "text",
text: "hello"
}]
}]
}]
<rich-text nodes="{{html}}"></rich-text> |
button开放能力
<button open-type="getPhoneNumber">getPhoneNumber</button> |
必须企业小程序才有权限使用
①获取用户手机号
拒绝
detail: {errMsg: "getPhoneNumber:fail user deny"} |
允许
detail:{
encryptedData: "oVfmZElDZ96kL6LdHbHgFJc1j4m8m9qn4/loYpxPpneSxt3Ddc7nig7rJU/bfr9IDt8rJOuVLswPY2HumtvYhxxN1HN4eNF6oB8noDJ0dij3/Ab3DlD/oIGDraJEgTXBExDMHBk3OGMF/AEFooalQsT1k+OHvvEryJXCQrpwrd2fE982cvSoL4ysDBMLDOpzo4J3Qjs+n6+lia/Qsm3jKA=="
errMsg: "getPhoneNumber:ok"
iv: "Q/UKb2OWlc30p0s3VgnpnA=="
} |
允许获取的数据已经加密了,需要用户自己对接的小程序后台服务器解密手机号
②获取用户信息 该接口已作废
<button open-type="getUserInfo" bindgetuserinfo="getUserInfo">getUserInfo</button>
getUserInfo(res){
console.log(res)
} |
允许
{
"detail": {
"encryptedData": "sXMfQwe8HOINrlNDF3rvsn0z2giBX3mVvBt0wR4fk+RdmZyAprucNMGHWJyWGLsT0QFr38G3f54u9Co+vDUGx841mrPWEMQcnND0khgtryuhhIZowsTLVl66mZb6aLCNB8yT5aYTI8Fazje4F7asqw0NihiLqy2gycDD+sySlT9Q7m3ZBstSIqTxaSi9cKo2M/3L2YPw9/jK28BxuWmCalBzGOEJ/Rdjl4UblrCnvhpETFb4a9QBvoZlkpoNX6rDkAYZvO0Z9mOQY8V6UiwKsyO2xowI4B6mvFRPkgAPsYCTYym0vD5hNnmj89U8BD28KV/9SUUbNyCI6tbZSJ9vL7gy66hW/kTvKLUTqVjSZFBdFlZBmYckaNx8cqb+TQPLNn9LT9ErXBOD95aT2oI39n5jXzcx9rENLbQukp+Kmd/2XRx3JHfLuAmDShAt279oF+AqHIlYAXDTqLtrhq5PaA==",
"errMsg": "getUserInfo:ok",
"iv": "Z3bkPdJ2DIa6OFwFHb/fEw==",
"rawData": {
"nickName": "微信用户",
"gender": 0,
"language": "",
"city": "",
"province": "",
"country": "",
"avatarUrl": "https://thirdwx.qlogo.cn/mmopen/vi_32/POgEwh4mIHO4nibH0KlMECNjjGxQUq24ZEaGT4poC6icRiccVGKSyXwibcPq4BWmiaIGuG1icwxaQX6grC9VemZoJ8rg/132"
},
"signature": "fe60f76d12989e7e32e7be582eac3caccfd0de61",
"userInfo": {
"avatarUrl": "https://thirdwx.qlogo.cn/mmopen/vi_32/POgEwh4mIHO4nibH0KlMECNjjGxQUq24ZEaGT4poC6icRiccVGKSyXwibcPq4BWmiaIGuG1icwxaQX6grC9VemZoJ8rg/132",
"city": "",
"country": "",
"gender": 0,
"language": "",
"nickName": "微信用户",
"province": ""
}
}
} |
以上使用方法已作废,可以使用如下方式获取
获取用户信息
export function getUserinfo() {
return new Promise((resolve, reject) => {
wx.getUserProfile({
desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
success: (res) => {
resolve(res)
},
fail: (res) => {
console.log('拒绝走失败回调')
reject(res)
}
})
})
} |
返回数据
{
"errMsg": "getUserProfile:ok",
"rawData": "{"nickName":"null","gender":1,"language":"zh_CN","city":"Jinan","province":"Shandong","country":"China","avatarUrl":"https://thirdwx.qlogo.cn/mmopen/vi_32/5fvHVvoO1VHCf9qBCtt4L17P6eFpy3X1dlPjhe61Yhic8ny5WV1nwYeaenAeUs4ticWKkyuAvhzk4wLWzdFeXibyg/132"}",
"userInfo": {
"nickName": "null",
"gender": 1,
"language": "zh_CN",
"city": "Jinan",
"province": "Shandong",
"country": "China",
"avatarUrl": "https://thirdwx.qlogo.cn/mmopen/vi_32/5fvHVvoO1VHCf9qBCtt4L17P6eFpy3X1dlPjhe61Yhic8ny5WV1nwYeaenAeUs4ticWKkyuAvhzk4wLWzdFeXibyg/132"
},
"signature": "b592fdad190ca35aff1a95b3d991c89d13b92fba",
"encryptedData": "eBZc51pP8U1RGUlIsS2KOGWt25KJ/tjGr9mZKRhGCp5bIMM32WBoqOcNlRcJl/FfJLyrlR9T/FmxqaPgtqPgW8EcnndXip5h/RsEH5I/jl/UpzL2gz26KvJqoVVE2h51gV24C6eU4L6ZSCI5a+erGDeap5IjRYmpbzwsDQpp6GQvK2Bgmm1zCVx3HSKuSrgXmVvHDaX5SilNZHHhWmHwUsMWa2Lvus5WAuIyhDgSrTT4kHIa/WIDAtJZsCR9u6zz9hRy/4wkPJEtwaCROnjNv6rY1T7u9CT42RAoS/dj4GV9Gf6Ic9DfvANb+yMABzRQRU+tmJAf32Dz5doTeqCBd04NFPUkhqRn7xNrJcLsa9HgULTfXZp0he39bguoB80IVaftsNeMLbAJghhYGLkas/phRxew6XuYMVzNGsw2SdE=",
"iv": "osYLTR1L7IMFumf2VFk6ug=="
} |
radio
<radio-group bindchange="bindChange">
<radio value="male">男</radio>
<radio value="female">女</radio>
</radio-group>
bindChange(e){
console.log(e.detail.value) // female
} |
checkbox
<checkbox-group bindchange="checkBoxChange">
<checkbox value="苹果">苹果</checkbox>
<checkbox value="橘子">橘子</checkbox>
<checkbox value="香蕉">香蕉</checkbox>
<checkbox value="橙子">橙子</checkbox>
</checkbox-group>
checkBoxChange(e){
console.log(e.detail.value) // ["橙子", "香蕉"]
} |
微信小程序自定义组件
①创建组件
components\tabs\tab
tab.js
Component({
properties: {
tabs:{
type:Array,
default:[]
}
},
/**
* 组件的初始数据
*/
data: {
// tabs: [{
// id: 1,
// name: '首页',
// isActive: true
// },
// {
// id: 2,
// name: '原创',
// isActive: false
// },
// {
// id: 3,
// name: '分类',
// isActive: false
// },
// {
// id: 4,
// name: '关于',
// isActive: false
// }
// ]
},
/**
* 页面.js 定义事件的时候 存放在data同层级下
* 组件.js 定义事件的时候 必须存放在methods中
*/
methods: {
tabClick(e) {
let {id} = e.currentTarget.dataset
// let {tabs} = this.data
// tabs.forEach(function (ele) {
// ele.isActive = ele.id == id ? true : false
// })
// this.setData({
// tabs
// })
console.log('aaaa')
this.triggerEvent('tabClick',{id})
}
}
}) |
tab.wxml
<view class="tab">
<view class="title">
<!-- <view class="title_item active">首页</view>
<view class="title_item">原创</view>
<view class="title_item">分类</view>
<view class="title_item">关于</view> -->
<view
wx:for="{{tabs}}"
wx:item="item"
wx:key="index"
class="title_item {{item.isActive?'active':''}}"
data-id="{{item.id}}"
bindtap="tabClick"
>
{{item.name}}
</view>
</view>
<view class="content">
<!--slot标签其实就是一个占位符-->
<slot></slot>
</view>
</view> |
②注册组件
{
"usingComponents": {
"tabs":"../../components/tabs/tab"
}
} |
③使用组件
demo.wxml
<tabs tabs="{{tabs}}" bind:tabClick="tabClick">
啊啊啊啊啊
</tabs> |
demo.js
Page({
data: {
tabs: [{
id: 1,
name: '首页',
isActive: true
},
{
id: 2,
name: '原创',
isActive: false
},
{
id: 3,
name: '分类',
isActive: false
},
{
id: 4,
name: '关于',
isActive: false
}
]
},
tabClick(e){
let {id} = e.detail
let {tabs} = this.data
tabs.forEach(function (ele) {
ele.isActive = ele.id == id ? true : false
})
this.setData({
tabs
})
}
}) |
接口地址
https://www.showdoc.com.cn/128719739414963/2513235043485226
wx.chooseAddress 获取的地址
{
cityName: "广州市"
countyName: "海珠区"
detailInfo: "新港中路397号"
errMsg: "chooseAddress:ok"
nationalCode: "510000"
postalCode: "510000"
provinceName: "广东省"
telNumber: "020-81167888"
userName: "张三"
} |
获取api授权信息 并且 调用api
wx.getSetting({
success: (result) => {
console.log(result)
const scopeAddress = result.authSetting['scope.address']
// 已授权
if (scopeAddress === true || scopeAddress === undefined) {
wx.chooseAddress({
success: (result) => {
console.log(result)
}
});
} else {
// 拒绝授权
wx.openSetting({
success: (result) => {
wx.chooseAddress({
success: (result) => {
console.log(result)
}
});
},
});
}
}
}); |
优化为 async方式调用
utils/asyncWx.js文件定义
export function getSetting() {
return new Promise((resolve, reject) => {
wx.getSetting({
success: (result) => {
resolve(result)
},
});
})
}
export function chooseAddress() {
return new Promise((resolve, reject) => {
wx.chooseAddress({
success: (result) => {
resolve(result)
}
});
})
}
export function openSetting() {
return new Promise((resolve, reject) => {
wx.openSetting({
success: (result) => {
resolve(result)
},
});
})
} |
引用
import { getSetting, openSetting, chooseAddress } from '../../utils/asyncWx'
const res1 = await getSetting();
const scopeAddress = res1.authSetting['scope.address']
if (scopeAddress === false) {
await openSetting()
}
const res2 = await chooseAddress() |