提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
要开发小程序首先得有个官方认可的账号才行注册账号,有了账号接下来就必须有个开发小程序的开发工具开发工具,接下来就可以大显身手敲代码了
微信公共平台登录
第一行代码
1.开发工具目录
这里先讲解一下后裔wxml,这个文件就是写入网页标签的地方,js就是写入代码的地方,wxss就是写入样式的地方搞明白这些就开始我们的第一行代码.
2.数据绑定与点击事件
首先在wxml这个文件里写入代码(先把这个页面的内容全删除)
<view>{{mes}}</view>
<view id="tapTest" bindtap="tapName"> Click me! </view>
找到JS文件在把代码写入
Page({
/**
* 页面的初始数据
*/
data: {
mes:"你好"
},
tapName: function(event) {
this.setData({
mes:"你好 /n Click me!"
})
},
})
可能你这个文件里有其他代码,全删除敲这些就够了,其它的用到了再说,现在
点击翻译按钮,如果没出错的话就会显示下面的样子.
右边就是模拟器显示的内容.点击 Clik me 按钮,看有什么变化.
好,接下来开始讲解一下来龙去脉.
先看一下wxml文件里都写了什么东西,两个 “view” 标签.
第一个标签两个大括号里面有个 "mes"变量,现在知道为啥显示"你好"字符了吧,那么数据是怎么绑定的那.
数据绑定使用"Mustache"语法(双大括号)将变量包起来.
动态数据均来自对应Page的data。
接下来看下第二个标签 有个"bindtap"属性,这个就是指向点击事件的函数名.
this.setData({
mes:"你好,Click me!"
})
setData方法就是动态改变数据的指令.
是不是很简单_
3.数据绑定
上一章我们讲了简单的数据绑定,接下来研究一下还有那些名堂.
绑定组件属性
<view id="item-{{id}}"> </view>
Page({
data: {
id: 0
}
})
这里稍微说明一下,上面绑定的id属性,“item-{{id}}”,其中"item-"是文本不是变量,被两个大括号包括的 "id"才是变量,这个需要高明白.
控制属性(需要在双引号之内)
<view wx:if="{{condition}}"> </view>
Page({
data: {
condition: true
}
})
关键字(需要在双引号之内)
true:boolean 类型的 true,代表真值。
false: boolean 类型的 false,代表假值。
注意一点,控制属性不能像下面这样表达
<view wx:if="false"> </view>
这种是错误的,欲要表达的是为假值,但其实这样是赋值的真值.说白了就是赋值了一个 字符串"false".
还可以在{{}}内进行简单的运算,支持的有如下几种方式:
<view hidden="{{flag ? off1 : 0ff2}}"> Hidden </view>
<view> {{a + b}} + {{c}} + d </view>
<view wx:if="{{length > 5}}"> </view>
<view>{{object.key}} {{array[0]}}</view>
<view wx:for-items="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view>
Page({
data: {
off1:true,
off2:false,
a: 1,
b: 2,
c: 3,
length:6,
object: {
key: 'Hello '
},
array: ['MINA'],
zero: 0
}
})
第一个view显示状态
第二个view中的内容为3 + 3 + d
第三个为显示状态
第四个显示内容为 hello MINA
执行第五个view的代码后,就会创建包含在内的5个view,他们显示的内容分别为 “0” “1” “2” “3” “4”
4.登录页面
接下来干点有意思的活了,登录功能的实现,了解具体实现的过程后,将会对小程序开发有个模糊的框架了解了.
先来看下展示的页面是什么样子
wxml代码示例:
<!--头部区域-->
<view class="header">
<image src="../img/2.png" mode="heightFix" class="imagelogin"></image>
</view>
<!--登录区域-->
<view class="formlogin" >
<form bindsubmit="uplogin">
<view>账号:</view>
<view>
<input type="text" name="use" placeholder="请输入账号"/>
</view>
<view>密码:</view>
<view >
<input type="safe-password" name="pwd" placeholder="请输入密码"/>
</view>
<button type="primary" form-type="submit" >账号登录</button>
</form>
</view>
当用户填写完表单并点击提交按钮时,可以通过表单的bindsubmit事件获取到所有input元素的值。这种方式适用于需要收集用户填写信息并提交的场景,如登录、注册等。
注意:在form中使用bindsubmit事件时,需要在input元素中指定name属性,以便在事件回调中通过e.detail.value对象获取对应的值。
wxss代码
/**index.wxss**/
/*头部布局*/
.header{
height:100px;
display: flex;
flex-direction: row;
justify-content: space-between;
border-bottom: 2rpx solid gray;
}
.imagelogin{
height: 80rpx;
}
/* 登录内容布局*/
.formlogin{
height: 730rpx;
display: flex;
justify-content: center;
line-height: 100rpx;
}
.formlogin input{
height: 75rpx;
width: 370rpx;
border-radius: 20rpx;
border: 2rpx solid green;
padding-left: 20rpx;
box-sizing: border-box;
}
.formlogin button{
margin-top: 60rpx;
}
js代码
Page({
/**
* 页面的初始数据
*/
data: {
loginMode:true,
},
//登录方法代码实现
uplogin:function(e){
let ls= e.detail.value;
let u=ls.use;
let p=ls.pwd;
//如果账号密码等于 test 123 跳转到登录成功页面
if(u=="test"&&p=="123")
{
wx.redirectTo({
url: '../htm/dlcg/dlcg',
})
}else{
wx.showToast({
title: '账户密码错误',
icon: 'none', // 可选值:success、loading、none
duration: 2000, // 提示框持续时间,单位为毫秒
});
}
},
})
5.列表渲染
wx:for
在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。
默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item
wxml代码
<view wx:for="{{array}}">
{{index}}: {{item.message}}
</view>
js代码
Page({
data: {
array: [{
message: 'foo',
}, {
message: 'bar'
}]
}
})
编译代码会出现两个view组件显现为
0:foo
1:bar
这在编程中很常用,可以动态的添加组件
在编写中还有两个很友好的指令
使用 wx:for-item 可以指定数组当前元素的变量名,
使用 wx:for-index 可以指定数组当前下标的变量名:
如:
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
{{idx}}: {{itemName.message}}
</view>
<view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="i">
<view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="j">
<view wx:if="{{i <= j}}">
{{i}} * {{j}} = {{i * j}}
</view>
</view>
</view>
原理是一样是这样的,单这样代码会更加清晰.
获取用户头像和昵称
wxml
<button class="avatar-wrapper" open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar">
<image class="avatar" src="{{userInfo.avatarUrl}}"></image>
</button>
<input type="nickname" class="nickname-input" placeholder="请输入昵称" bind:change="onInputChange" />
重点是绑定的事件名
js
const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'
const app=getApp();
Page({
data: {
userInfo: {
avatarUrl: defaultAvatarUrl,
nickName: '',
}
},
onChooseAvatar(e) {
const { avatarUrl } = e.detail
// const { nickName } = this.data.userInfo
this.setData({
"userInfo.avatarUrl": avatarUrl,
})
},
onInputChange(e) {
const nickName = e.detail.value
//const { avatarUrl } = this.data.userInfo
this.setData({
"userInfo.nickName": nickName,
//hasUserInfo: nickName && avatarUrl && avatarUrl !== defaultAvatarUrl,
})
},
})
开发工具撤销操作
在微信开发者工具中,可以使用快捷键Ctrl + Z来快速撤回上一步操作。这个快捷键在大多数编辑器和操作系统中都是通用的。如果想要重做上一步操作,可以使用快捷键Ctrl + Y。这两个快捷键非常简单易用,适合大多数开发者在编写代码时使用。
APP生命周期
微信小程序的APP生命周期函数是指在小程序从启动到销毁的过程中,微信提供的特定函数,这些函数允许开发者对小程序的运行状态进行监控和操作。以下是微信小程序APP的主要生命周期函数及其详解:
onLaunch
描述:当小程序启动时触发,全局只触发一次。
用途:常用于初始化操作,如获取全局数据、配置等。
onShow
描述:当小程序启动或从后台进入前台显示时触发。
用途:页面或组件的显示逻辑,如更新UI、重新加载数据等。
onHide
描述:当小程序从前台进入后台时触发。
用途:常用于保存当前页面的状态或数据,为下次显示做准备。
onError
描述:当小程序发生脚本错误或API调用错误时触发。
用途:用于捕获和处理错误,如记录日志、弹出错误提示等。
onPageNotFound
描述:当页面路由不存在时触发。
用途:常用于处理404页面或进行重定向。
onPageScroll (页面滑动事件)
描述:当页面滚动时触发。
用途:常用于监听页面滚动事件,如实现下拉刷新、上拉加载等功能。
onTabClick (Tab点击事件)
描述:当用户点击Tab栏时触发。
用途:用于处理Tab栏的点击事件,如切换页面或内容。
onShareAppMessage (分享事件)
描述:当用户点击小程序右上角菜单并选择“分享”时触发。
用途:用于自定义分享内容,如标题、路径等。
onUnload (页面卸载事件)
描述:当页面被卸载或跳转时触发。
用途:常用于清理页面资源、取消网络请求等操作。
onPageScrollToBottom (页面滚动到底部事件)
描述:当用户滚动页面到底部时触发(某些版本或特定场景下)。
用途:常用于实现无限加载、加载更多等功能。
这些生命周期函数为开发者提供了极大的便利,使得他们可以更好地控制小程序的运行和用户体验。在使用这些函数时,建议根据实际需求和场景进行合理使用和优化,以达到最佳的效果和性能。
页面生命周期
onLoad
描述:当页面初次加载时触发。
用途:常用于页面初始化,如获取数据、设置初始状态等。
onShow
描述:当页面显示时触发。
用途:当用户进入页面时,可以执行一些需要持续进行的操作,如监听滚动事件等。
onReady
描述:当页面初次渲染完成时触发。
用途:常用于在页面DOM结构准备好后进行一些操作,如设置定时器、初始化第三方插件等。
onHide
描述:当页面隐藏时触发。
用途:用于在页面被其他页面覆盖或需要隐藏某些内容时执行相关操作。
onUnload
描述:当页面被销毁或跳转离开时触发。
用途:用于清理页面在onLoad或onShow中创建的资源,如关闭网络请求、停止计时器等。
onPullDownRefresh
描述:当用户下拉页面时触发(针对非uni-app小程序)。
用途:常用于实现下拉刷新的功能。
onReachBottom
描述:当用户上拉页面触底时触发(针对非uni-app小程序)。
用途:常用于实现分页加载数据的功能。
onShareAppMessage(分享)
描述:当用户点击分享按钮时触发。可以设置分享内容标题、路径等信息。
其他生命周期方法(根据具体需求可能有更多):一些特定的微信小程序框架可能还提供了其他与页面生命周期相关的函数,比如在onLaunch(小程序启动时)、onPageScroll(页面滚动)等场景下的特定处理函数。
在使用这些生命周期函数时,需要注意以下几点:
确保在合适的时间点调用相关函数,避免不必要的性能损耗和逻辑错误。
在onUnload中清理资源,避免内存泄漏和资源浪费。
根据具体需求选择合适的生命周期函数,并确保其逻辑的完整性和正确性。
总之,了解并正确使用微信小程序的页面生命周期函数对于开发高效、稳定的小程序非常重要。
API
提示框
在微信小程序中,你可以使用多种方法来显示提示框,包括 wx.showToast、wx.showLoading 和 wx.showModal 等。下面是一些示例代码,展示了如何使用这些方法:
1.wx.showToast:用于显示一条浮动的提示框,一般用于短暂的提示信息。
wx.showToast({
title: '提示内容',
icon: 'success', // 可选值:success、loading、none
duration: 2000, // 提示框持续时间,单位为毫秒
success: function () {
// 提示框显示成功后的回调函数
}
});
**2.wx.showLoading:**用于显示一个加载提示框,表示正在加载数据或执行操作。
wx.showLoading({
title: '加载中...',
mask: true, // 是否显示透明蒙层,防止触摸穿透,默认为 false
});
// 执行完异步操作后,隐藏加载提示框
wx.hideLoading();
3.wx.showModal:用于显示一个带有确定和取消按钮的模态对话框,用于用户确认或选择操作。
wx.showModal({
title: '提示',
content: '确定要删除吗?',
success: function (res) {
if (res.confirm) {
console.log('用户点击了确定');
} else if (res.cancel) {
console.log('用户点击了取消');
}
}
});
你可以根据你的具体需求,选择适合的方法来显示提示框。如果你需要更多的自定义功能,比如设置提示框的样式或位置,你可能需要借助一些第三方库或自定义组件来实现
页面跳转
在微信小程序中,实现页面跳转有多种方法,主要包括使用 组件和调用相关的 API 方法。以下是详细的说明和示例代码:
使用 组件
在 WXML 文件中,你可以使用 组件来设置页面跳转。通过设置 url 属性来指定要跳转的页面路径,还可以设置 open-type 属性来控制跳转的方式。
<!-- 跳转到详情页 -->
<navigator url="/pages/detail/detail">跳转到详情页</navigator>
open-type 属性的可选值包括:
navigate:保留当前页面,跳转到应用内的某个页面(默认)。
redirect:关闭当前页面,跳转到应用内的某个页面。
switchTab:跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。
使用 API 方法
1.wx.navigateTo
保留当前页面,跳转到应用内的某个页面。使用相对路径或绝对路径来指定目标页面。
wx.navigateTo({
url: '/pages/detail/detail'
});
**注意:**小程序最多只能打开五层页面,如果超过五层,可以考虑使用 wx.redirectTo 或其他方式。
2.wx.redirectTo
关闭当前页面,跳转到应用内的某个页面。
wx.redirectTo({
url: '/pages/detail/detail'
});
3.wx.reLaunch
关闭所有页面,打开到应用内的某个页面。
wx.reLaunch({
url: '/pages/detail/detail'
});
4.wx.switchTab
跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。
wx.switchTab({
url: '/pages/index/index'
});
5.wx.navigateBack
返回上一页面或多级页面。可以通过 delta 参数指定返回的页面层数。
wx.navigateBack({
delta: 1 // 表示返回上一页
});
页面间参数传递
在进行页面跳转时,你可能需要传递参数。这可以通过在 URL 路径后添加参数,或在目标页面的 onLoad 生命周期函数中接收参数来实现。
例如,使用 wx.navigateTo 传递参数:
wx.navigateTo({
url: '/pages/detail/detail?id=123'
});
在目标页面的 onLoad 生命周期函数中接收参数:
Page({
onLoad: function(options) {
const id = options.id;
console.log('接收到的参数 id:', id);
}
});
使用 组件传递参数的方式类似,只需在 url 属性中添加参数即可。
全局函数getApp()
在微信小程序中,App() 函数用于注册小程序的全局实例,并接受一个对象参数来指定小程序的生命周期函数、全局数据等。以下是关于如何正确调用并注册 App() 的详细解释:
一、App() 的基本用法
App() 函数必须在 app.js 文件中调用,并且只能调用一次。它接受一个对象参数,该对象可以包含以下属性:
onLaunch:小程序启动时触发的生命周期函数。
onShow:小程序启动或从后台进入前台显示时触发的生命周期函数。
onHide:小程序从前台进入后台时触发的生命周期函数。
onError:小程序发生脚本错误或 API 调用失败时触发的错误处理函数。
globalData:用于存放全局数据。
二、示例代码
以下是一个简单的 app.js 文件示例,展示了如何正确调用并注册 App():
App({
onLaunch(options) {
// 小程序启动时执行的代码
console.log('App Launched');
},
onShow(options) {
// 小程序显示时执行的代码
console.log('App Shown');
},
onHide() {
// 小程序隐藏时执行的代码
console.log('App Hidden');
},
onError(msg) {
// 小程序发生错误时执行的代码
console.error('App Error:', msg);
},
globalData: {
userInfo: null, // 用户信息
apiBaseURL: 'https://api.example.com' // API 基础 URL
}
//这里还可以添加全局方法
});
三、注意事项
确保在 app.js 中调用:App() 函数必须在 app.js 文件中调用,这是小程序的全局入口文件。
只能调用一次:App() 函数在整个小程序的生命周期中只能调用一次,否则会引发错误。
生命周期函数的使用:在 App() 中定义的生命周期函数,会在小程序的不同状态下被自动调用,开发者可以在这些函数中执行相应的逻辑。
全局数据的访问:通过 App() 定义的 globalData 属性,可以在小程序的任何页面中通过 getApp().globalData 来访问全局数据。
四、全局数据的访问示例
在子页面中访问全局数据的示例代码如下:
Page({
onLoad() {
// 获取全局的 app 实例
const app = getApp();
// 访问全局数据
console.log(app.globalData.apiBaseURL); // 输出 API 基础 URL
// 假设我们要更新用户信息
app.globalData.userInfo = { name: '新用户', avatarUrl: '新头像URL' };
},
// 其他页面逻辑代码...
});
更新页面this.setData
this.setData 是微信小程序中用于更新页面数据的方法。它允许你在页面的 JavaScript 文件中动态地改变页面的状态,并触发页面的重新渲染。下面是对 this.setData 方法的详细解释:
作用
this.setData 的主要作用是更新页面数据,并触发页面的重新渲染。当你需要改变页面上显示的内容时,可以使用这个方法。
使用方法
this.setData 方法接受一个对象作为参数,这个对象的键是页面中 data 对象里已定义的属性名,值是你想要设置的新值。
this.setData({
// 键是 data 对象中的属性名,值是你想要设置的新值
propertyName: newValue
});
注意事项
避免频繁调用:由于每次调用 this.setData 都会触发页面的重新渲染,因此频繁调用可能会影响性能。尽量将多次数据更新合并成一次调用。
数据响应式:只有 data 对象中已定义的属性才能通过 this.setData 更新,并且更新后会触发页面的重新渲染。如果尝试更新一个未定义的属性,将不会有任何效果。
路径问题:在更新复杂类型的数据(如对象或数组)时,可以使用路径来指定要更新的属性。例如,要更新一个对象中的某个属性,可以这样做:
this.setData({
'object.property': newValue
});
//更新数组中的某个元素:
this.setData({
'array[index]': newValue
});
异步更新:this.setData 的调用是异步的,这意味着在调用之后立即检查 data 对象可能看不到更新后的值。如果需要基于更新后的数据进行操作,可以在 setData 的回调函数中执行。但是,从微信小程序基础库版本 2.11.0 开始,setData 支持同步调用(使用 sync 修饰符),但需要注意性能影响。
示例
假设你有一个页面,页面上有一个计数器,每次点击按钮时计数器加 1。你可以这样实现:
js
Page({
data: {
count: 0
},
increment() {
this.setData({
count: this.data.count + 1
});
}
});
wxml
<button bindtap="increment">{{count}}</button>
每次点击按钮时,increment 方法会被调用,count 的值会增加 1,并且页面会重新渲染以显示新的计数值
测试可用wx.canIUse
wx.canIUse 是微信小程序提供的一个全局函数,用于判断小程序的 API、组件、接口等是否在当前版本可用。下面是对 wx.canIUse 方法的详细解释:
作用
wx.canIUse 的主要作用是帮助开发者在编写小程序代码时,判断某个 API 或功能是否在当前用户的小程序版本中可用。这有助于开发者编写兼容不同版本小程序的代码。
使用方法
wx.canIUse 方法接受一个字符串参数,该字符串表示要查询的 API、组件或接口的名称。方法会返回一个布尔值,表示该 API、组件或接口在当前版本是否可用。
let isAvailable = wx.canIUse('someAPI');
if (isAvailable) {
// 如果可用,则执行相关代码
} else {
// 如果不可用,则执行兼容代码或给出提示
}
获取用户图像
<button class="avatar-wrapper" open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar">
<image class="avatar" src="{{userInfo.avatarUrl}}"></image>
</button>
js
onChooseAvatar(e) {
const { avatarUrl } = e.detail
// const { nickName } = this.data.userInfo
this.setData({
"userInfo.avatarUrl": avatarUrl,
})
},
选取图片与上传图片
wxml
<view class="container">
<button bindtap="chooseImage">选择图片</button>
<image wx:if="{{tempFilePath}}" src="{{tempFilePath}}" mode="widthFix" style="width: 300px;"></image>
<button bindtap="uploadImage" wx:if="{{tempFilePath}}">上传图片</button>
</view>
js
Page({
data: {
tempFilePath: ''
},
chooseImage: function() {
const that = this;
wx.chooseImage({
count: 1, // 默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success(res) {
// tempFilePath可以作为img标签的src属性显示图片
const tempFilePaths = res.tempFilePaths;
that.setData({
tempFilePath: tempFilePaths[0]
});
}
});
},
uploadImage: function() {
const that = this;
wx.uploadFile({
url: 'https://your-server-url/upload', // 仅为示例,非真实的接口地址
filePath: that.data.tempFilePath,
name: 'file',
formData: {
user: 'test'
},
success(res) {
const data = res.data;
// do something with response data
console.log('upload success', data);
},
fail(err) {
console.error('upload fail', err);
}
});
}
});
注意:
如果出现 不在以下 uploadFile 合法域名列表中的错误,请参考地址
如果想与本地服务器连接请参考 下面的 连接本地服务器 章节
python后端读取
@app.route('/upload_file', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return jsonify({'success': False, 'message': 'No file part'})
file = request.files['file']
if file.filename == '':
return jsonify({'success': False, 'message': 'No selected file'})
if file:
filename = file.filename
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
try:
da=request.form.get('user') #这里读取额外的JSON数据
print(da)
except:
print('读取失败')
return jsonify({'success': True, 'message': 'File uploaded successfully', 'filename': filename})
提交数据
js
wx.request({
url:app.fwqurl+ '/jspost', //仅为示例,并非真实的接口地址
data: {
x: '12',
y: '34'
},
header: {
'content-type': 'application/json' // 默认值
},
method:'POST',
success (res) {
console.log(res.data)
}
})
服务端python
@app.route('/jspost',methods=['POST'])
def jspost():
# 获取请求中的数据
data = request.get_json()
print('接受数据:')
print(data)
return "{'a':'一个','b':'二个'}"
获取用户openid
openid在微信小程序中具有极其重要的意义。
它是用户在小程序 appid 下的唯一标识。就像每个人的身份证号码是独一无二的一样,每个用户在特定的小程序中的 openid 也是独一无二的。
获取openid首先要在客户端发送临时凭证 code
wx.login({
success(res) {
if (res.code) {
// 发送res.code到后台换取openId, sessionKey, unionId
console.log('登录凭证(code):' + res.code);
var data={'code':res.code}
// 这里可以将code发送到你的后端服务器进行进一步处理
my.post(_this.fwqurl+'upload',data);
} else {
console.log('登录失败!' + res.errMsg);
}
}
});
后端代码
@app.route('/upload', methods=['POST'])
def upload():
APPID = ini['appid']
SECRET = ini['appsecret']
data = request.json
code = data['code']
# 调用微信API获取access_token
url = f'https://api.weixin.qq.com/sns/jscode2session?appid={APPID}&secret={SECRET}&js_code={code}&grant_type=authorization_code'
response = requests.get(url)
data = response.json()
print(data)
openid = data['openid'] # 获取openid
session_key = data['session_key'] # 获取session_key
return jsonify({'openid': openid})
session_key
session_key 是微信小程序中用于用户身份验证和授权的关键参数。以下是对 session_key 的详细解释:
- 功能与用途
唯一性与有效性:每个用户在每个时刻仅拥有一个有效的 session_key。它用于保障用户数据的安全传输和处理。
登录态管理:通过 wx.login 接口获取到的用户登录态会生成一个 session_key。该登录态具有一定的时效性,用户长时间不使用小程序可能导致 session_key 过期。
数据加密与解密:session_key 用于加密和解密敏感数据,例如通过 wx.getWeRunData 获取的用户健康数据等。 - 检测 session_key 的有效性
开发者可以使用 wx.checkSession 接口来检测当前用户的 session_key 是否有效:
调用成功:表示 session_key 未过期,可以继续使用。
调用失败:表示 session_key 已过期,需要重新执行登录流程以获取新的 session_key。
示例代码:
wx.checkSession({
success () {
// session_key 未过期,可以继续使用
},
fail () {
// session_key 已过期,需要重新登录
wx.login() // 重新执行登录
}
})
组件
什么是组件:
组件是视图层的基本组成单元。
组件自带一些功能与微信风格一致的样式。
一个组件通常包括 开始标签 和 结束标签,属性 用来修饰这个组件,内容 在两个标签之内。
注意:所有组件与属性都是小写,以连字符-连接
属性类型
类型 | 描 述 | 注释 |
---|---|---|
Boolean | 布尔值 | 组件写上该属性,不管是什么值都被当作 true;只有组件上没有该属性时,属性值才为false。 |
Number | 数字 | 比如1 2 3 |
String | 字符串 | 文本 |
Array | 数组 | [1,2,3] |
Object | 对象 | {off:0} |
EventHandler | 事件处理函数名 |
公共属性
所有组件都有以下属性:
属性名 | 类型 | 描述 |
---|---|---|
id | String | 组件的唯一标示 |
class | String | 组件的样式类 |
style | String | 组件的内联样式 |
hidden | Boolean | 组件是否显示 |
data-* | Any | 自定义属性,组件上触发的事件时,会发送给事件处理函数 |
bind* / catch* | EventHandler | 组件的事件 |
特殊属性
几乎所有组件都有各自定义的属性,可以对该组件的功能或样式进行修饰,请参考各个组件的定义
表单组件
基本概念
form组件是微信小程序中用于收集用户输入信息的一种方式。它通常用于注册、登录、调查问卷等场景。通过在form标签内放置不同的表单控件,如input、textarea、radio、checkbox、slider、switch、picker等,可以构建出满足不同需求的表单。
常用属性
form组件支持多种属性,这些属性可以帮助开发者更好地控制表单的行为。以下是一些常用的属性:
report-submit:布尔值,用于指定是否返回formId,该formId可用于发送模板消息。
bindsubmit:事件处理函数,当表单提交时会触发此事件,并携带表单中的数据。
bindreset:事件处理函数,当表单重置时会触发此事件。
使用方法
在wxml文件中,通过标签创建一个表单。表单内可以包含各种表单控件,并通过设置控件的name属性来标识它们。同时,需要为标签绑定bindsubmit和bindreset(不是必须的)事件处理函数。
例如:
wxml代码
<view style="padding:10px;">
<form bindsubmit="submit" bindreset="reset" >
<input name="username" placeholder="请输入用户名"/>
<input name="pass" type="password" placeholder="请输入密码"/>
<!--单选框-->
<view style="margin-top:20px;">单选框</view>
<radio-group name="radiog" style="padding:10px;border:1px double">
<label><radio value="radio1"/>单选框1</label>
<label><radio value="radio2"/>单选框2</label>
</radio-group>
<view></view>
<view style="padding:10px;margin-top:10px;border:1px double">多选框
<checkbox-group name="cbox">
<label><checkbox value="checkbox1"/>checkbox1</label>
<label><checkbox value="checkbox2"/>checkbox2</label>
</checkbox-group>
</view>
<button form-type="submit" style="margin-top:10px;">提交</button>
<button form-type="reset" style="margin-top:10px;">重置</button>
</form>
</view>
为了组件显示的不那么拥挤添加了 style样式
js代码如下
Page({
data:{
},
submit: function(e) {
var obj=e.detail.value;
console.log(obj); // 打印表单数据
var use= obj.username; // 获取用户名
var pass=obj.pass;//获取密码
var rname=obj.radiog;//获取单选框选中的组件 name 值
var chenames=obj.cbox;//获取多选框选中的 name数组
// 这里可以添加发送数据到后端的代码
},
reset: function() {
// 表单重置逻辑,如果需要的话
}
});
代码里e是事件传递过来的参数,从这个参数里可以获取表单里的所有数据.前提是你表单内的组件都有唯一的name属性值才可以区分出来.
注意事项
确保密码输入框的type属性正确设置为password,以隐藏用户输入的密码。
在处理用户输入的密码时,注意保护用户隐私,避免在控制台或日志中输出明文密码。
如果需要验证用户输入的密码,请在服务器端进行验证,而不是在客户端进行简单的比较。
总之,微信小程序中的密码框是通过input组件实现的,通过合理配置属性和事件处理函数,可以满足基本的密码输入需求。同时,通过样式定制和高级用法,可以创建出更加美观和实用的密码输入框。
官网详解
block
在微信小程序中,是一个非常实用的逻辑结构组件,它用于包裹其他标签而不对应任何实际的HTML标签。这使得可以用来控制多个子节点而不会引入额外的DOM结构,从而优化渲染性能和简化模板逻辑
一、基本用法
的主要作用是作为一个逻辑容器,它不会在页面中渲染任何可见的节点。但作为一个逻辑上的容器,在条件渲染和循环渲染中发挥着不可替代的作用。
- 条件渲染
使用可以根据条件来包裹一组元素,从而实现对这些元素的统一控制。例如:
<block wx:if="{{condition}}">
<view>这里的内容会在 condition 为 true 时显示</view>
<view>这些内容都会被一起控制显示或隐藏</view>
</block>
在这个例子中,如果condition的值为true,则内的所有子节点都会被渲染;如果为false,则这些节点都不会被渲染。
- 循环渲染
<block wx:for="{{items}}" wx:key="unique">
<view>索引:{{index}}, 内容:{{item.name}}</view>
</block>
在这个例子中,items是一个数组,会为数组中的每个元素创建一个组件。注意,这里的wx:key属性用于提高列表渲染的性能。
二、注意事项
并不是一个组件,它仅仅是一个包装元素。因此,它不能使用class、style等样式相关的属性,因为它不会生成实际的DOM节点。
不能单独使用,它必须包含至少一个子节点。
使用的好处在于它可以保持WXML结构的清晰,同时不会引入额外的节点。这在进行条件渲染或循环渲染时非常有用。
三、应用场景
在微信小程序中广泛应用于需要控制多个子节点的显示与隐藏,或者进行循环渲染的场景。通过使用,开发者可以保持WXML结构的清晰和简洁,同时避免不必要的DOM层级和性能开销。
自定义组件
微信小程序自定义组件是一种可以复用的代码块,它允许开发者将页面的某部分结构、样式和功能进行封装,以便在多个页面中重复使用。
创建自定义组件
1.在微信小程序的 components 目录下(如果没有,则创建该目录.当然不是必须创建这个名的文件夹,可以是a,也可以是b文件夹都可以),创建一个新的文件夹来存放你的组件,比如 my-component。
2.在新建的文件夹 my-component鼠标右键点击 选择 “新建component”,这样工具会自动生成四个文件my-component.wxml、my-component.wxss、my-component.js 和 my-component.json。
例如,一个简单的自定义组件 my-component 如下所示:
my-component.wxml:
<view class="container">
<text>{{text}}</text>
</view>
my-component.wxss:
.container {
padding: 10px;
background-color: #fff;
}
my-component.js:
Component({
properties: {
//这里定义了一个自定义组件属性
text: {
type: String,
value: ''
}
},
data: {},
/**
* 组件的方法列表,包括事件都在这里
*/
methods: {
// method1(){}
}
})
my-component.json:
{
"component": true, //一定要有这个
"usingComponents": {} //说明自定义组件也可以引用自定义组件
}
注意
在自定义组件内获取属性 this.properties.属性名
使用自定义组件:
在需要使用该组件的页面中,通过 usingComponents 字段声明该组件。
在页面的 WXML 文件中,使用 的形式来引用组件,其中 component-tag 是你在 json 文件中定义的组件名(如果不指定,则默认为文件夹名)。
例如,在一个名为 index 的页面中:
index.json:
{
"usingComponents": {
"my-component": "/components/my-component/my-component"
}
}
index.wxml:
<view>
<my-component text="Hello, World!"></my-component>
</view>
注意事项
自定义组件的命名应避免与现有 HTML 标签或微信小程序内置组件冲突。
组件的样式默认是隔离的,即组件内的样式不会影响到组件外的元素,反之亦然。如果需要修改这一行为,可以在组件的 json 文件中设置 styleIsolation 字段。
组件的属性和数据是响应式的,当它们发生变化时,组件会自动重新渲染。
通过以上步骤,你就可以在微信小程序中创建和使用自定义组件了。自定义组件可以大大提高代码的可复用性和可维护性,是开发大型微信小程序时不可或缺的工具。
属性
<!--components/my_1.wxml-->
<view>
<text>{{txt}}</text>
</view>
properties: {
txt:{
type:String,
value:"默认"
}
},
调用
<my_1 txt="ADC"></my_1>
slot 子节点
在组件模板中可以提供一个 节点,用于承载组件引用时提供的子节点。
<!--components/my_1.wxml-->
<view>
<text>{{txt}}</text>
<slot></slot>
</view>
引用:
<!--index.wxml-->
<my_1 txt="ADC">
<view>这里是插入到组件slot中的内容,如果组件中没有slot,这个不会显示</view>
</my_1>
事件
<!--components/my_1.wxml-->
<view class="tou">
<text>{{txt}}</text>
<button bind:tap="dianji">触发事件</button>
</view>
自定义组件触发事件时,需要使用 triggerEvent 方法,指定事件名、detail对象和事件选项:如下
// components/my_1.js
properties: {
txt:{
type:String,
value:"默认"
}
},
methods: {
dianji:function(){
this.triggerEvent('mysj', {txt:this.properties.txt});
}
}
调用
<!--index.wxml-->
<view class="container" >
<my_1 txt="ADC" bind:mysj="dianji">
</my_1>
</view>
// index.js
dianji(e){
console.log("事件触发",e.detail.txt);
},
事件
事件绑定
在微信小程序中,事件绑定是通过在 WXML 文件中为组件添加特定的事件属性来实现的。这些事件属性以 bind 或 catch 开头,后面跟着事件类型,如 tap(点击事件)、input(输入事件)等。
bind:表示冒泡事件绑定,即事件会从触发它的组件开始,向上冒泡到父组件,直到被某个组件处理或到达顶层。
catch:表示捕获事件绑定,即事件会从顶层开始,向下捕获到触发它的组件,并在该组件处被处理,不再继续向下传播。
例如,为一个按钮绑定点击事件:
wxml
<button bindtap="handleTap">点击我</button>
事件处理函数
在页面的 JavaScript 文件中,你需要定义与事件绑定相对应的事件处理函数。这些函数通常接受一个事件对象作为参数,该对象包含了事件的详细信息,如触发事件的组件、事件类型、触发事件时传递的数据等。
Page({
handleTap(event) {
// 处理点击事件的逻辑
console.log('按钮被点击了', event);
}
});
事件对象的属性
事件对象包含了丰富的属性,可以帮助你了解事件的上下文信息。以下是一些常用的事件对象属性:
type:事件类型,如 tap、input 等。
**currentTarget:**绑定事件的当前组件。
**target:**触发事件的组件。注意,在事件冒泡过程中,target 始终指向触发事件的组件,而 currentTarget 会随着事件的传播而改变。
detail:包含了一些与事件相关的额外信息。例如,在 input 事件中,detail 对象会包含输入框的值。
timeStamp:事件触发的时间戳。
注意事项
**避免事件冒泡导致的意外行为:**当使用 bind 绑定事件时,要注意事件冒泡可能导致的事件处理函数被意外调用。如果不需要冒泡行为,可以使用 catch 来绑定事件。
合理使用事件对象:在处理事件时,要合理利用事件对象的属性来获取所需的信息,但要避免不必要的属性访问以提高性能。
**注意事件处理函数的命名:**事件处理函数的名称必须与 WXML 文件中绑定的事件名称相对应(区分大小写)。
希望这些信息能帮助你更好地理解微信小程序中的事件处理机制
轮播图案例
wxml
<view class="ht">
<!-- 轮播图 -->
<swiper indicator-dots="{{yuandian}}" autoplay="{{autoplay}}" indicator-color="{{color}}" interval="{{interval}}" duration="{{duration}}" >
<block >
<swiper-item wx:for="{{imgUrls}}" wx:for-index="idx" bindtap="onClickBanner" data-idx="{{ idx }}">
<image src="{{item}}" class="swiper-image" />
</swiper-item>
</block>
</swiper>
</view>
这里用bindchange 轮播滑动事件来获取 图片的索引,还有一种就是
<swiper-item wx:for="{{banner}}" wx:for-index="idx" bindtap="onClickBanner" data-idx="{{ idx }}">
添加一个自定义属性动态赋值,然后在点击事件中获取 自定义属性值就行,下面是获取属性值
onClickBanner:function (e) {
//获取自定义属性值
let ban = e.currentTarget.dataset.idx;
console.log(ban);
},
wxss
.ht{
padding-left:10px;
padding-right:10px;
}
swiper {
height: 400rpx;
width: 100%;
border-radius: 20rpx; /* 设置圆角 */
overflow: hidden; /* 确保swiper内的内容不会溢出圆角边界 */
}
.swiper-image {
width: 100%;
height: 100%;
border-radius: inherit; /* 继承父容器的圆角 */
object-fit: cover; /* 确保图片按比例缩放并填充容器 */
}
JS
Page({
data:{
pageLoading:true,
yuandian: true,
autoplay: true,
interval: 3000,
duration: 800,
color:"brown",
index:0,
imgUrls:[
'https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner1.png',
'https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner2.png',
'https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner3.png',
'https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner4.png',
'https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner5.png',
'https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner6.png',
]
},
onClickBanner(e){
let banner = e.currentTarget.dataset.idx//获取自定义idx属性值
console.log(banner);
}
})
配置
全局配置
entryPagePath
指定小程序的默认启动路径(首页),常见情景是从微信聊天列表页下拉启动、小程序列表启动等。如果不填,将默认为 pages 列表的第一项。不支持带页面路径参数。
{
"entryPagePath": "pages/index/index"
}
pages
用于指定小程序由哪些页面组成,每一项都对应一个页面的 路径(含文件名) 信息。文件名不需要写文件后缀,框架会自动去寻找对应位置的 .json, .js, .wxml, .wxss 四个文件进行处理。
未指定 entryPagePath 时,数组的第一项代表小程序的初始页面(首页)。
小程序中新增/减少页面,都需要对 pages 数组进行修改。
{
"pages": ["pages/index/index", "pages/logs/logs"]
}
window
用于设置小程序的状态栏、导航条、标题、窗口背景色。
"navigationBarTitleText"属性是导航栏标题内容
{
"window":{
"navigationBarTitleText": "首页"
}
}
tabBar
如果小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。就是小程序下面的导航栏.在app.json中添加,比如如果想添加三的栏目,分别是 首页 分类 我的 具体如下
{
"pages": [
"pages/index/index",
"pages/xfjf/xfjf",
"pages/my/my" //必须得有三个页面才行
],
"tabBar":{
"list":[
{
"pagePath": "pages/index/index",
"text": "首页"
},
{
"pagePath": "pages/xfjf/xfjf",
"text": "分类"
},
{
"pagePath":"pages/my/my",
"text": "我的"
}
]
}
}
详细的设置参考
页面配置
app.json 中的部分配置,也支持对单个页面进行配置,可以在页面对应的 .json 文件来对本页面的表现进行配置。
页面中配置项在当前页面会覆盖 app.json 中相同的配置项(样式相关的配置项属于 app.json 中的 window 属性,但这里不需要额外指定 window 字段
属性navigationBarTitleText 当前页导航栏标题
本地缓存
本地缓存是一种在客户端储存数据的一种方式,他允许小程序在用户的客户端储存一定量的数据方便下次启动时更快的加载.
目前官方说明:
同一个微信用户,同一个小程序 storage 上限为 10MB。storage 以用户维度隔离,同一台设备上,A 用户无法读取到 B 用户的数据;不同小程序之间也无法互相读写数据。
同一小程序使用不同插件:不同插件之间,插件与小程序之间 storage 不互通。
不同小程序使用同一插件:同一插件 storage 不互通。
清理策略
本地缓存的清理时机跟代码包一样,只有在代码包被清理的时候本地缓存才会被清理。
设置本地缓存数据
// 异步设置本地缓存数据
wx.setStorage({
key: 'myData', // 缓存的键
data: {name: 'John', age: 30}, // 需要存储的数据
success: function() {
console.log('数据已缓存');
}
});
// 同步设置本地缓存数据
try {
wx.setStorageSync('myDataSync', {name: 'Jane', age: 25});
console.log('数据已同步缓存');
} catch (e) {
console.error('缓存数据失败', e);
}
获取本地数据
你可以使用 wx.getStorage 或 wx.getStorageSync 方法来获取本地缓存数据。以下是使用这两个方法的示例:
// 异步获取本地缓存数据
wx.getStorage({
key: 'myData', // 缓存的键
success: function(res) {
console.log('获取到的数据:', res.data);
}
});
// 同步获取本地缓存数据
try {
const data = wx.getStorageSync('myDataSync');
console.log('同步获取到的数据:', data);
} catch (e) {
console.error('获取缓存数据失败', e);
}
注意
在回调函数success中如果使用 this.setData是不行的.这里的this是无定义的.可以在函数外 声明变量 赋值后调用.
删除本地缓存数据
你可以使用 wx.removeStorage 或 wx.removeStorageSync 方法来删除指定的本地缓存数据,或者使用 wx.clearStorage 或 wx.clearStorageSync 方法来清除所有本地缓存数据。以下是使用这些方法的示例:
// 异步删除指定的本地缓存数据
wx.removeStorage({
key: 'myData', // 缓存的键
success: function() {
console.log('数据已删除');
}
});
// 同步删除指定的本地缓存数据
try {
wx.removeStorageSync('myDataSync');
console.log('数据已同步删除');
} catch (e) {
console.error('删除缓存数据失败', e);
}
// 异步清除所有本地缓存数据
wx.clearStorage({
success: function() {
console.log('所有缓存数据已清除');
}
});
// 同步清除所有本地缓存数据
try {
wx.clearStorageSync();
console.log('所有缓存数据已同步清除');
} catch (e) {
console.error('清除缓存数据失败', e);
}
页面传参
在微信小程序中,页面传参是常见需求,比如从列表页跳转到详情页传递ID,或在页面间共享数据。以下是 5种常用传参方式 的详细代码示例和场景分析:
一、URL Query 传参(最常用)
适用场景:简单数据传递(如ID、名称)
// 页面A:跳转并传参
wx.navigateTo({
url: '/pages/detail/detail?id=123&name=foo' // 参数拼接在URL
})
// 页面B(detail.js):接收参数
Page({
onLoad(options) { // options自动解析URL参数
console.log(options.id) // 输出 "123"
console.log(options.name) // 输出 "foo"
}
})
特点:
参数会暴露在URL中,适合非敏感数据
参数类型自动转为字符串(需手动转换数字/布尔值)
二、全局变量传参
适用场景:复杂对象或跨多页面共享数据
// app.js 中定义全局变量
App({
globalData: {
userInfo: { name: 'Alice', age: 25 }
}
})
// 页面A:设置数据
const app = getApp()
app.globalData.tempData = { productId: 456 }
// 页面B:读取数据
Page({
onShow() {
const app = getApp()
console.log(app.globalData.tempData.productId) // 输出 456
}
})
特点:
数据保存在内存中,关闭小程序后失效
需注意变量命名冲突
三、Storage 本地存储传参
适用场景:需持久化或大数据量传递
// 页面A:存储数据
wx.setStorageSync('key', { list: [1, 2, 3] }) // 同步写法
// 页面B:读取数据
Page({
onLoad() {
const data = wx.getStorageSync('key')
console.log(data.list) // 输出 [1, 2, 3]
}
})
特点:
数据持久化到本地,除非手动清除
异步API为 wx.setStorage/wx.getStorage
四、EventChannel 事件通道传参
适用场景:页面间需要双向通信
// 页面A:跳转并建立通信
wx.navigateTo({
url: '/pages/detail/detail',
events: {
// 监听detail页面的事件
acceptData: (data) => {
console.log('收到回调数据:', data)
}
},
success(res) {
// 向detail页面发送数据
res.eventChannel.emit('sendData', { msg: '来自首页' })
}
})
// 页面B(detail.js):
Page({
onLoad() {
const eventChannel = this.getOpenerEventChannel()
// 接收首页数据
eventChannel.on('sendData', (data) => {
console.log(data.msg) // 输出 "来自首页"
})
// 回调数据
eventChannel.emit('acceptData', { status: 'OK' })
}
})
特点:
支持页面间双向通信
适合复杂交互场景(如表单提交回调)
五、页面栈传参(getCurrentPages)
适用场景:返回上一页时传递数据
// 页面B:返回上一页并传参
const pages = getCurrentPages()
const prevPage = pages[pages.length - 2] // 获取上一页实例
prevPage.setData({ callbackData: '更新数据' })
wx.navigateBack()
特点:
直接操作页面实例,灵活但耦合性高
需确保页面栈存在目标页面
六、WXS 脚本传参(模板内使用)
适用场景:在WXML模板中处理数据
// utils.wxs
function formatPrice(price) {
return '¥' + price.toFixed(2)
}
module.exports = {
formatPrice: formatPrice
}
<!-- 页面WXML -->
<wxs src="../../utils.wxs" module="tools" />
<view>{{tools.formatPrice(item.price)}}</view>
参数传递方案对比
方式 数据量 生命周期 适用场景
URL Query 小 单次跳转有效 简单参数传递
全局变量 中/大 小程序运行期间有效 跨页面共享数据
Storage 大 手动清除前有效 持久化数据或复杂对象
EventChannel 中 页面关闭前有效 双向通信/回调
页面栈 中 页面关闭前有效 返回上一页更新数据
export导入其它模块
export 关键字用于导出模块中的变量、函数或类等内容,以便在其他模块中导入和使用。
用法:
导出单个变量或函数:export const variable = …; 或 export function functionName() {…}
导出多个变量或函数:使用花括号 {} 包围要导出的内容,如 export { variable1, variable2, functionName };
使用 export default 导出默认成员,这样导入时可以不使用花括号。
案例:
// 导出单个变量和函数
export const API_URL = 'https://example.com/api';
export function fetchData() {
// ...
}
// 导出多个变量和函数
const anotherVariable = ...;
function anotherFunction() {...}
export { anotherVariable, anotherFunction };
// 使用 export default 导出默认成员
export default class MyClass {
// ...
}
在另一个模块中导入这些导出的内容:
// 导入单个变量和函数
import { API_URL, fetchData } from './path/to/module';
// 导入默认成员
import MyClass from './path/to/module';
// 导入所有导出的内容(需要使用花括号)
import * as myModule from './path/to/module';
console.log(myModule.API_URL);
console.log(myModule.fetchData());
自定义模块常用写法如:
module.exports={
add(a,b){return a+b;},
tssc(nr)
{
console.log(nr);
}
}
获取小程序源码
手机里小程序的源文件包
根目录/data/data/com.tencent.mm/MicroMsg/{一串16进制字符}/appbrand/pkg/
在这个目录下,会发现一些 xxxxxxx.wxapkg 类型的文件,这些就是微信小程序的包
微信小程序的格式就是:.wxapkg
这里重要声明一下:虽然微信小程序的包后缀是.wxapkg,但有一些包的依赖后缀也是.wxapkg,真正的小程序包大小1M左右,而依赖包大小2、3M甚至更多。所以一股脑的反编译.wxapkg 类型的文件可能会报错: Error: This Package is unrecognizable, please decrypted every type of file by hand.,遇见这个问题的小伙伴请自知,你可能没找对包哦!
现在开始说下具体怎么获取获取
1.安装node.js 已经安装跳的2. 下载地址 https://nodejs.org/en/
2.下载反编译的脚本
地址:https://github.com/qwerty472123/wxappUnpacker
提取码: sx2f
地址2:https://pan.baidu.com/s/1cqraKpAltLg3F6IBPhfyZw
3.安卓模拟器(要求自带root权限)
我使用的是夜神模拟器,你也可以自选
怎么获取小程序包
在安卓模拟器中下载 微信 ,然后找到你想获取包的小程序,做好把页面全部点下,这样获取的全面一些,下面是目录
根目录/data/data/com.tencent.mm/MicroMsg/{一串16进制字符}/appbrand/pkg/
你会看到发现里面的一些.wxapkg后缀的文件,就是它们没错啦,可以根据使用的时间来判断那个是你刚才从服务器下载过来的
一般小程序的文件不会太大.夜神模拟器现在的版本有个 手机电脑文件件互传的功能,
如果你不确定那个是主包就全部转到电脑夹
怎么反编译
把下载的反编译脚本解压出来到一个文件夹
js和json才是有用的,其他无所谓,在这个脚本文件夹目录上鼠标点击选中后 输入 cmd
然后就出现node命令窗口 .输入指令 npm install 回车 安装依赖成功
就是最后一步了,反编译 .wxapkg 文件
例如:我有一个需要反编译的文件 _163200311_32.wxapkg 已经解压到了D盘根目录下,那么就输出命令
node .\wuWxapkg.js D:_163200311_32.wxapkg
成功后就会在反编译的文件夹中多出来一个刚反编译文件名的文件夹,里面就是想要的了.
注意一点: .wxapkg 文件名,不要有空格。有些.wxapkg 文件名中自带空格,请自行把空格去掉,或者把文件名改成其他的
其他获取可参考
https://www.cnblogs.com/micr067/p/15524643.html
设置全局Icon 图标
创建全局wxss文件
在根目录下创建 style 目录 然后创建 Icon.wxss文件,文件内容如下
@font-face {
font-family: 'wr';
src: url('https://cdn3.codesign.qq.com/icons/gqxWyZ1yMJZmVXk/Yyg5Zp2LG8292lK/iconfont.woff?t=cfc62dd36011e60805f5c3ad1a20b642')
format('woff2');
}
.wr {
font-family: 'wr' !important;
font-size: 32rpx;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.wr-deliver:before {
content: '\e033';
}
.wr-indent_close:before {
content: '\e041';
}
.wr-edit:before {
content: '\e002';
}
.wr-succeed:before {
content: '\e00d';
}
.wr-goods_return:before {
content: '\e03c';
}
.wr-wallet:before {
content: '\e051';
}
.wr-package:before {
content: '\e047';
}
.wr-comment:before {
content: '\e037';
}
.wr-exchang:before {
content: '\e03e';
}
.wr-credit_card:before {
content: '\e035';
}
.wr-service:before {
content: '\e04a';
}
.wr-shop_bag:before {
content: '\e02a';
}
.wr-goods_refund:before {
content: '\e03d';
}
.wr-check:before {
content: '\e053';
}
.wr-wechat:before {
content: '\e065';
}
.wr-cartAdd:before {
content: '\e05d';
}
.wr-home:before {
content: '\e020';
}
.wr-person:before {
content: '\e02c';
}
.wr-cart:before {
content: '\e023';
}
.wr-location:before {
content: '\e016';
}
.wr-arrow_forward:before {
content: '\e012';
}
.wr-close:before {
content: '\e021';
}
.wr-search:before {
content: '\e011';
}
.wr-clear_filled:before {
content: '\e027';
}
.wr-arrow_drop_up:before {
content: '\e071';
}
.wr-arrow_drop_down:before {
content: '\e070';
}
.wr-filter:before {
content: '\e038';
}
.wr-copy:before {
content: '\e001';
}
.wr-arrow_back:before {
content: '\e003';
}
.wr-add_circle:before {
content: '\e004';
}
.wr-Download:before {
content: '\e006';
}
.wr-map:before {
content: '\e007';
}
.wr-store:before {
content: '\e008';
}
.wr-movie:before {
content: '\e00a';
}
.wr-done:before {
content: '\e00b';
}
.wr-minus:before {
content: '\e00c';
}
.wr-list:before {
content: '\e00e';
}
.wr-expand_less:before {
content: '\e00f';
}
.wr-person_add:before {
content: '\e010';
}
.wr-Photo:before {
content: '\e013';
}
.wr-preview:before {
content: '\e014';
}
.wr-remind:before {
content: '\e015';
}
.wr-info:before {
content: '\e017';
}
.wr-expand_less_s:before {
content: '\e018';
}
.wr-arrow_forward_s:before {
content: '\e019';
}
.wr-expand_more_s:before {
content: '\e01a';
}
.wr-share:before {
content: '\e01d';
}
.wr-notify:before {
content: '\e01e';
}
.wr-add:before {
content: '\e01f';
}
.wr-Home:before {
content: '\e020';
}
.wr-delete:before {
content: '\e022';
}
.wr-error:before {
content: '\e025';
}
.wr-sort:before {
content: '\e028';
}
.wr-sort_filled:before {
content: '\e029';
}
.wr-shop_bag_filled:before {
content: '\e02b';
}
.wr-person_filled:before {
content: '\e02d';
}
.wr-cart_filled:before {
content: '\e02e';
}
.wr-home_filled:before {
content: '\e02f';
}
.wr-add_outline:before {
content: '\e030';
}
.wr-compass:before {
content: '\e034';
}
.wr-goods_exchange:before {
content: '\e03a';
}
.wr-group_buy:before {
content: '\e03b';
}
.wr-group:before {
content: '\e03f';
}
.wr-indent_goods:before {
content: '\e040';
}
.wr-help:before {
content: '\e042';
}
.wr-group_takeout:before {
content: '\e043';
}
.wr-label:before {
content: '\e044';
}
.wr-indent_wating:before {
content: '\e045';
}
.wr-member:before {
content: '\e046';
}
.wr-scanning:before {
content: '\e04b';
}
.wr-tv:before {
content: '\e04d';
}
.wr-to_top:before {
content: '\e04f';
}
.wr-visibility_off:before {
content: '\e050';
}
.wr-error-1:before {
content: '\e052';
}
.wr-arrow_right:before {
content: '\e054';
}
.wr-arrow_left:before {
content: '\e056';
}
.wr-picture_filled:before {
content: '\e057';
}
.wr-navigation:before {
content: '\e058';
}
.wr-telephone:before {
content: '\e059';
}
.wr-indent_time:before {
content: '\e05c';
}
.wr-cart_add:before {
content: '\e05d';
}
.wr-classify:before {
content: '\e060';
}
.wr-place:before {
content: '\e063';
}
.wr-wechat_pay:before {
content: '\e064';
}
.wr-security:before {
content: '\e066';
}
.wr-alarm:before {
content: '\e067';
}
.wr-person-1:before {
content: '\e068';
}
.wr-open_in_new:before {
content: '\e069';
}
.wr-uncheck:before {
content: '\e06b';
}
.wr-thumb_up:before {
content: '\e06c';
}
.wr-thumb_up_filled:before {
content: '\e06d';
}
.wr-star:before {
content: '\e06e';
}
.wr-star_filled:before {
content: '\e06f';
}
.wr-cards:before {
content: '\e072';
}
.wr-picture_error_filled:before {
content: '\e076';
}
.wr-discount:before {
content: '\e077';
}
设置全局 app.wxss
打开 app.wxssw文件,写入内容
@import 'style/Icon.wxss';
在任何页面调用
在任何一个 wxml文件中添加
<view class="sy">
<view class="wr wr-deliver">wr-deliver</view>
<view class="wr wr-indent_close">wr-indent_close</view>
<view class="wr wr-edit">wr-edit</view>
<view class="wr wr-succeed">wr-succeed</view>
<view class="wr wr-goods_return">wr-goods_return</view>
<view class="wr wr-wallet">wr-wallet</view>
<view class="wr wr-package">wr-package</view>
<view class="wr wr-comment">wr-comment</view>
<view class="wr wr-exchang">wr-exchang</view>
<view class="wr wr-credit_card">wr-credit_card</view>
<view class="wr wr-service">wr-service</view>
<view class="wr wr-shop_bag">wr-shop_bag</view>
<view class="wr wr-goods_refund">wr-goods_refund</view>
<view class="wr wr-check">wr-check</view>
<view class="wr wr-wechat">wr-wechat</view>
<view class="wr wr-cartAdd">wr-cartAdd</view>
<view class="wr wr-home">wr-home</view>
<view class="wr wr-person">wr-person</view>
<view class="wr wr-cart">wr-cart</view>
<view class="wr wr-location">wr-location</view>
<view class="wr wr-arrow_forward">wr-arrow_forward</view>
<view class="wr wr-close">wr-close</view>
<view class="wr wr-search">wr-search</view>
<view class="wr wr-clear_filled">wr-clear_filled</view>
<view class="wr wr-arrow_drop_up">wr-arrow_drop_up</view>
<view class="wr wr-arrow_drop_down">wr-arrow_drop_down</view>
<view class="wr wr-filter">wr-filter</view>
<view class="wr wr-copy">wr-copy</view>
<view class="wr wr-arrow_back">wr-arrow_back</view>
<view class="wr wr-add_circle">wr-add_circle</view>
<view class="wr wr-Download">wr-Download</view>
<view class="wr wr-map">wr-map</view>
<view class="wr wr-store">wr-store</view>
<view class="wr wr-movie">wr-movie</view>
<view class="wr wr-done">wr-done</view>
<view class="wr wr-minus">wr-minus</view>
<view class="wr wr-list">wr-list</view>
<view class="wr wr-expand_less">wr-expand_less</view>
<view class="wr wr-person_add">wr-person_add</view>
<view class="wr wr-Photo">wr-Photo</view>
<view class="wr wr-preview">wr-preview</view>
<view class="wr wr-remind">wr-remind</view>
<view class="wr wr-info">wr-info</view>
<view class="wr wr-expand_less_s">wr-expand_less_s</view>
<view class="wr wr-arrow_forward_s">wr-arrow_forward_s</view>
<view class="wr wr-expand_more_s">wr-expand_more_s</view>
<view class="wr wr-share">wr-share</view>
<view class="wr wr-notify">wr-notify</view>
<view class="wr wr-add">wr-add</view>
<view class="wr wr-Home">wr-Home</view>
<view class="wr wr-delete">wr-delete</view>
<view class="wr wr-error">wr-error</view>
<view class="wr wr-sort">wr-sort</view>
<view class="wr wr-sort_filled">wr-sort_filled</view>
<view class="wr wr-shop_bag_filled">wr-shop_bag_filled</view>
<view class="wr wr-person_filled">wr-person_filled</view>
<view class="wr wr-cart_filled">wr-cart_filled</view>
<view class="wr wr-home_filled">wr-home_filled</view>
<view class="wr wr-add_outline">wr-add_outline</view>
<view class="wr wr-compass">wr-compass</view>
<view class="wr wr-goods_exchange">wr-goods_exchange</view>
<view class="wr wr-group_buy">wr-group_buy</view>
<view class="wr wr-group">wr-group</view>
<view class="wr wr-indent_goods">wr-indent_goods</view>
<view class="wr wr-help">wr-help</view>
<view class="wr wr-group_takeout">wr-group_takeout</view>
<view class="wr wr-label">wr-label</view>
<view class="wr wr-indent_wating">wr-indent_wating</view>
<view class="wr wr-member">wr-member</view>
<view class="wr wr-scanning">wr-scanning</view>
<view class="wr wr-tv">wr-tv</view>
<view class="wr wr-to_top">wr-to_top</view>
<view class="wr wr-visibility_off">wr-visibility_off</view>
<view class="wr wr-error-1">wr-error-1</view>
<view class="wr wr-arrow_right">wr-arrow_right</view>
<view class="wr wr-arrow_left">wr-arrow_left</view>
<view class="wr wr-picture_filled">wr-picture_filled</view>
<view class="wr wr-navigation">wr-navigation</view>
<view class="wr wr-telephone">wr-telephone</view>
<view class="wr wr-indent_time">wr-indent_time</view>
<view class="wr wr-cart_add">wr-cart_add</view>
<view class="wr wr-classify">wr-classify</view>
<view class="wr wr-place">wr-place</view>
<view class="wr wr-wechat_pay">wr-wechat_pay</view>
<view class="wr wr-security">wr-security</view>
<view class="wr wr-alarm">wr-alarm</view>
<view class="wr wr-person-1">wr-person-1</view>
<view class="wr wr-open_in_new">wr-open_in_new</view>
<view class="wr wr-uncheck">wr-uncheck</view>
<view class="wr wr-thumb_up">wr-thumb_up</view>
<view class="wr wr-thumb_up_filled">wr-thumb_up_filled</view>
<view class="wr wr-star">wr-star</view>
<view class="wr wr-star_filled">wr-star_filled</view>
<view class="wr wr-cards">wr-cards</view>
<view class="wr wr-picture_error_filled">wr-picture_error_filled</view>
<view class="wr wr-discount">wr-discount</view>
</view>
效果
引用外部组件库(Vant Weapp)
这里使用的是Vant Weapp,官网
快速上手
1.在小程序 package.json 所在的目录中执行命令安装 npm 包(在当前目录路径处点击 输入 cmd):(没有创建一个)
npm install
如果执行失败 可能没有安装 node.js如果安装了就是没设置系统环境变量
2.再输入 npm i @vant/weapp -S --production
3.在小程序开发环境 构建
如果没有使用 npm模块 不用管
4.在 tsconfig.json 中增加如下配置,以防止 tsc 编译报错。
请将path/to/node_modules/@vant/weapp修改为项目的 node_modules 中 @vant/weapp 所在的目录。
{
...
"compilerOptions": {
...
"baseUrl": ".",
"types": ["miniprogram-api-typings"],
"paths": {
"@vant/weapp/*": ["path/to/node_modules/@vant/weapp/dist/*"]
},
"lib": ["ES6"]
}
}
5.引入组件
以 Button 组件为例,只需要在app.json或index.json中配置 Button 对应的路径即可。
所有组件文档中的引入路径均以 npm 安装为例,如果你是通过下载源代码的方式使用 @vant/weapp,请将路径修改为项目中 @vant/weapp 所在的目录。
// 通过 npm 安装
// app.json
"usingComponents": {
"van-button": "@vant/weapp/button/index"
}
// 通过下载源码使用 es6版本
// app.json
"usingComponents": {
"van-button": "path/to/@vant/weapp/dist/button/index"
}
// 通过下载源码使用 es5版本
// app.json
"usingComponents": {
"van-button": "path/to/@vant/weapp/lib/button/index"
}
下载源码引用
如果想看组件具体怎么实现的可下载源码
下载
文件夹 dist 就是组件源码了
公告组件
wxml
<view class="notice">
<van-notice-bar color="#474f66" background="#ffffff" left-icon="volume-o" text="{{ txt }}" />
</view>
wxjson
这里引用了
"van-notice-bar": "@vant/weapp/notice-bar/index",
wxss
.notice {
width: 92%;
margin: 0rpx auto;
border-radius: 20rpx;
overflow: hidden;
}
Layout 布局
css一般设置
标题样式
font-size: 36rpx;
font-weight: bolder;
text
一般的正文
color: #474f66;
font-size: 28rpx;
自定义图标按钮
wxml
<view class="zdy" bindtap="onStartCamera">
<view class="icon">
<image class='img' src="../../images/index-icon-carema.png" />
</view>
<view class="biaoti">拍照搜题</view>
</view>
.img{
height: 70rpx;
width: 70rpx;
margin: 0 auto;
}
.icon{
padding-right:30rpx;/*设置内右边距30 与文本离开的距离*/
}
.biaoti{
color: #474f66;
font-size: 28rpx;
}
.zdy{
margin-left:20rpx;/*外左边距*/
padding: 20rpx 20rpx;/*设置内边距上下为10 左右20*/
width: 140px;
background-color: #DFF1FF;/*背景颜色*/
border-radius: 15rpx;/*圆角半径15*/
display: flex;/*设置元素的显示方式为Flex布局。Flex布局是一种用于管理一维布局的CSS3模块*/
flex-direction: row;/*在Flex布局中,设置子项沿着水平方向(行)排列*/
justify-content: center;/*在Flex布局中,使子项在主轴(这里是水平方向)上居中对齐*/
align-items: center;/*在Flex布局中,使子项在交叉轴(这里是垂直方向)上居中对齐*/
}
圆形头像
border-radius: 80rpx; /*高宽/2*/
height: 160rpx;
width: 160rpx;
连接本地服务器
在开发中微信是不容许连接http://127.0.0.1:5000地址的.如果想连接本地服务器可以使用花生壳内网穿通
详细简绍
注意事项
微信小程序在编写代码中,变量,函数命名仅支持英文字母、数字(必须子母开头)和下划线,就是说不支持中文.