微信小程序学习记录
小程序文件结构
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() |