微信小程序——mpvue
框架原理
mpvue
保留了 vue 的核心方法,
mpvue-template-compiler
提供了将 vue 的模板语法转换到小程序的 wxml 语法的能力
- 修改了 vue 的建构配置,使之构建出符合小程序项目结构的代码格式: json/wxml/wxss/js 文件
生命周期函数
- 同 vue , 不同的是会在小程序
onReady
后,再去触发 vue mounted 生命周期。
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
activated
deactivated
beforeDestroy
destroyed
除了 Vue 本身的生命周期外,mpvue 还兼容了小程序生命周期,这部分生命周期钩子的来源于
- 除了 Vue 本身的生命周期外,mpvue 还兼容了小程序生命周期,这部分生命周期钩子的来源于:微信小程序的 Page, 除特殊情况外,不建议使用小程序的生命周期钩子。
app 部分:
onLaunch,初始化
onShow,当小程序启动,或从后台进入前台显示
onHide,当小程序从前台进入后台
onError起到错误监听的作用。
page 部分:
onLoad,监听页面加载
onShow,监听页面显示
onReady,监听页面初次渲染完成
onHide,监听页面隐藏
onUnload,监听页面卸载
onPullDownRefresh,监听用户下拉动作
onReachBottom,页面上拉触底事件的处理函数
onShareAppMessage,用户点击右上角分享
onPageScroll,页面滚动
onTabItemTap, 当前是 tab 页时,点击 tab 时触发 (mpvue 0.0.16 支持)
- 总体执行流程:
beforeCreate—> created —> onLunch/onLoad --> onShow --> onReady --> beforeMounte --> mounted……
- 周期图:
注意事项:
- 几乎全支持 Vue 的模板语法。
- 不支持
纯-HTML
,v-html
指令不能用。
- 在插值表达式
{{}}
中不支持复杂的 JavaScript 渲染表达式:
<!-- 这种就不支持,建议写 computed -->
<p>{{ message.split('').reverse().join('') }}</p>
<!-- 但写在 @event 里面的表达式是都支持的,因为这部分的计算放在了 vdom 里面 -->
<ul>
<li v-for="item in list">
<div @click="clickHandle(item, index, $event)">{{ item.value }}</p>
</li>
</ul>
- 不支持 ElementUI 和 Vue-router
- 列表渲染: 只是需要注意一点,嵌套列表渲染,必须指定不同的索引!
<!-- 在这种嵌套循环的时候, index 和 itemIndex 这种索引是必须指定,且别名不能相同,正确的写法如下 -->
<template>
<ul v-for="(card, index) in list">
<li v-for="(item, itemIndex) in card">
{{item.value}}
</li>
</ul>
</template>
- 原生组件上的事件绑定,需要以
vue
的事件绑定语法来绑定。
- 如
bindchange="eventName"
事件,需要写成 @change="eventName"
表单控件绑定 picker
- 表单控件绑定 picker
- picker 有多种选择形式,参考官网:https://developers.weixin.qq.com/miniprogram/dev/component/picker.html
- select 组件用 picker 组件进行代替
- 默认 mode 格式:
<template>
<div>
<picker @change="bindPickerChange" :value="index" :range="array">
<view class="picker">
当前选择:{{array[index]}}
</view>
</picker>
</div>
</template>
<script>
export default {
data () {
return {
index: 0,
array: ['A', 'B', 'C']
}
},
methods: {
bindPickerChange (e) {
console.log(e)
// 切换index位置
this.index = e.mp.detail.value
}
}
}
</script>
- 日期 mode=date 格式选择:
<template>
<div>
<!-- value选中的日期 ,start有效开始日期 , end有效结束的日期 ,所选择的日期需要在start-end之间 -->
<picker mode="date" :value="date" start="2015-09-01" end="2017-09-01" @change="bindDateChange">
<view class="picker">
当前选择: {{date}}
</view>
</picker>
</div>
</template>
<script>
export default {
data () {
return {
date: '2020-05-01'
}
},
methods: {
bindDateChange (e) {
console.log(e)
// 修改时间
this.date = e.mp.detail.value
}
}
}
</script>
radio-group 组件
- radio 使用 radio-group 组件代替:
- 代码如下:
<template>
<div>
<!-- radio-group 一组radio的集合 , @change 为触发选中单选时调用的方法,会传入一个默认的 e 标签对象 -->
<radio-group class="radio-group" @change="radioChange">
<label v-for="(item, index) in items" :key="index">
<!-- value设置单选绑定搞得值,当选中后可以作为参数到method方法中 -->
<!-- checked默认刚进来 选中的 -->
<radio :value="item.name" :checked="item.checked"/> {{item.value}}
</label>
</radio-group>
</div>
</template>
<script>
export default {
data () {
return {
items: [
{name: 'USA', value: '美国'},
{name: 'CHN', value: '中国', checked: 'true'},
{name: 'BRA', value: '巴西'},
{name: 'JPN', value: '日本'},
{name: 'ENG', value: '英国'},
{name: 'TUR', value: '法国'}
]
}
},
methods: {
radioChange (e) {
console.log(e)
console.log('radio发生change事件,携带value值为:', e.target.value)
}
}
}
</script>
目录介绍
页面跳转
- 小程序自带五中页面跳转方法,分别为 , ,
- wx.navigateTo() :保留当前页面,跳转到另一个页面(主要表现为左上角含有返回按钮)
- wx.navigateBack() : 配合 navigateTo 使用,跳回到上 N 层界面
- wx.redirectTo() : 关闭当前页面,跳转到某一个页面上(左上角没有返回按钮)
- wx.switchTab() : 主要用于跳转到 tabBar 的操作,如果想要跳转 tabBar 只能使用这个。
- wx.relaunch() : 关闭所有页面,跳转到某一页面
发送 Http 请求
- 小程序中只有 Get , Post 两种请求方式。
- 使用 wx.request 发送 http 网络请求。具体参数有 url,data,header,method,success 等。
- 列如代码:
wx.request({
url: 'http://47.95.199.43/abnormalFlight/ninfo',
method: 'POST',
header: {
'content-type': 'application/json'
},
data: {
flightdateid: this.flightdateid,
createdate: this.plandt
},
success: (res) => {
this.ninfos = res.data.data
}
Fail:(res)=>{
Console.log(“失败”)
}
Complete:(){
Console.log(“回调函数”)
}
})
推送消息功能
小程序登录流程:
- 详情图:
- 小程序前端通过
wx.login()
的方法。可以获取一个 code 值。
- 携带着 code 值,访问 java 后端。
- java 后端,通过 appId 和 secret,+code 值。访问 微信 的 API 接口。获取到 用户登录的 openID 和 session_key。
- 将 openId 和 session_key 返回给前端。
- 每次进入页面,前端调用
wx.checkSession
方法,判断 session_key 是否过期,过期的话,就 调用 wx.login
进行访问 java 后端登录。
注意点:
- session_key 默认的有效时间为 3 天
- openId 为登录用户的 唯一 Id,一般存储在 数据表中
wx.login
中的 code 值,是根据用户的信息进行生成的。虽然每次都不一样,但是均代表用户的信息。所以传递给后台,调用微信 API 接口后,不会生成新的 openID,还是和以前一致,会刷新 session_key 会话 ID。
- session_key 的作用为,可以解密出用户的 个人信息,手机号,所在地区..等等
获取用户信息
引入 Vant Weapp 样式 UI
- 官网地址:https://youzan.github.io/vant-weapp/#/quickstart
- 引入方式(官网的不好用):
# 通过 npm 安装
npm i @vant/weapp -S --production
//进入node_modules\@vant\weapp包下,将dist 复制到 项目的 static 目录下
//在需要使用 Vant组件 的页面目录中创建 main.json 文件。
//需要什么组件就引入什么
{
"navigationBarTitleText": "home首页",
"usingComponents": {
"van-button": "/static/vant/dist/button/index"
}
}
- 效果如下:
- 使用组件:
<van-button type="primary">主要按钮</van-button>
- 在微信开发者平台,需要在详情中设置 ES6 转 ES5 , 不勾选无法使用
注意事项(踩坑点)
- 组件的函数调用属性 bind:change="xxx" 要写为 @change="xxx",调用 methods 中的方法
- 上传组件
Uploader
的上传回调函数, after-read 不能用,要修改引入的 index.js。
在 dist/uploader/index.js 文件中
将after-read 修改为 afterread
然后在组件中 就以 @afterread="xxx" 的方式使用(貌似是不能中间有 - )
- 修改组件的样式,自定义样式:
custom-style="background-color=xxx"
小程序原生组件
小程序事件
touchstart 手指触摸动作开始
touchmove 手指触摸后移动
touchcancel 手指触摸动作被打断,如来电提醒,弹窗
touchend 手指触摸动作结束
tap 手指触摸后马上离开
longpress 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发 1.5.0
longtap 手指触摸后,超过350ms再离开(推荐使用longpress事件代替)
transitionend 会在 WXSS transition 或 wx.createAnimation 动画结束后触发
animationstart 会在一个 WXSS animation 动画开始时触发
animationiteration 会在一个 WXSS animation 一次迭代结束时触发
animationend 会在一个 WXSS animation 动画完成时触发
touchforcechange 在支持 3D Touch 的 iPhone 设备,重按时会触发
页面 style 中 设置 page 全局样式:
获取用户的个人信息
- 获取用户的信息 需要用户的授权。 通过 button 来进行
- 如果没有授权,就会弹出一个 是否确认授权的 按钮。
获取用户信息
// 获取用户的个人信息
getUser (event) {
console.log(event)
}
- 自动获取用户的 信息。 需要进行过 授权处理。不然无法获取 会走 fail 方法
// 需要写在 mounted 函数中
mounted () {
wx.getUserInfo({
withCredentials: true,
// 成功方法
success: function (res) {
console.log(res)
var userInfo = res.userInfo
console.log(userInfo)
},
fail () {
// 失败方法
}
})
},
- 进入页面 自动弹出 获取信息 授权窗口(暂时不能使用):
- 授权网址:https://developers.weixin.qq.com/miniprogram/dev/api/open-api/authorize/wx.authorize.html
// 可以通过 wx.getSetting 先查询一下用户是否授权了 "scope.record" 这个 scope
var self = this
wx.getSetting({
success (res) {
if (!res.authSetting['scope.userInfo']) {
wx.authorize({
scope: 'scope.userInfo',
success () {
// 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问
console.log('授权成功')
self.getUser()
}
})
}
}
})
无需授权获取用户信息
原生跳转页面
- 进行页面跳转的是可使用小程序提供的 API
- 在组件中 按钮 进行跳转:https://developers.weixin.qq.com/miniprogram/dev/component/navigator.html
跳转到新页面
在当前页打开
切换 Tab
打开绑定的小程序
- 在 js 方法中 进行跳转:https://developers.weixin.qq.com/miniprogram/dev/api/route/wx.switchTab.html
wx.navigateTo() 保留当前页面,可回退
wx.redirectTo() 不保留,不能回退
wx.switchTab() 使用于tabBar页面
//代码示例
wx.navigateTo({
url: 'page/list/main', // 路径要写成 对应的main.js文件
events: {
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
acceptDataFromOpenedPage: function(data) {
console.log(data)
},
someEvent: function(data) {
console.log(data)
}
...
},
success: function(res) {
// 通过eventChannel向被打开页面传送数据
res.eventChannel.emit('acceptDataFromOpenerPage', { data: 'test' })
}
})
//test.js文件中,可以获取参数
const eventChannel = this.getOpenerEventChannel()
// 监听acceptDataFromOpenerPage事件,获取上一页面通过eventChannel传送到当前页面的数据
const eventChannel = this.getOpenerEventChannel()
eventChannel.emit('acceptDataFromOpenedPage', {data: 'test'});
eventChannel.emit('someEvent', {data: 'test'});
// 监听acceptDataFromOpenerPage事件,获取上一页面通过eventChannel传送到当前页面的数据
eventChannel.on('acceptDataFromOpenerPage', function(data) {
console.log(data)
})
url 请求中参数
- 在 url 中使用 ? 参数需要。 encodeURIComponent 和 decodeURIComponent 编解码,否则会被截断,导致?后面的数据无法传递后跳转页面。
- 对于多行字符串,可以使用反引号 `` 拼接,避免使用一大堆 和加号。
var encodeUrl = encodeURIComponent(param.url)
wx.navigateTo({ url: "../articleDetail/articleDetail?title=" + title + "&mid=" + this.data.mid + "&id=" + id + "&url=" +encodeUrl });
跳转后页面js文件
...
onLoad:function(options){
this.setData({
title:options.title,
id:options.id,
url: decodeURIComponent(options.url), // 使用 decode进行解码
}),
使用 flyio 发送 HTTP 请求
- 需要下载并且在 需要的组件 main.js 中引入使用
- 官方文档:https://github.com/wendux/fly
npm install flyio // 下载
// 在需要的组件 main.js中引入
// pages/logs/main.js中进行配置
// 配置网络请求 flyio
var Fly = require('flyio/dist/npm/wx')
var fly = new Fly()
// 添加全局配置、拦截器等
Vue.prototype.$http = fly
// 使用
this.$http.post('url' , { request playod中的请求数据 })
.then((d) => {
console.log(d) // 返回的数据
}).catch(err =>{
console.log(err.status , err.message) // 错误信息
})
- post 请求默认会在 request playod 中发送数据。但是可以设置为以 requestBody 中发送请求数据:
// 第一种,通过 content-type设置
fly.post("../package.json",{aa:8,bb:9,tt:{xx:5}},{headers:{
"content-type":"application/x-www-form-urlencoded"
}})
.then(console.log)
// 第二种 使用 qs 库
var qs = require('qs');
fly.post('/foo', qs.stringify({ 'bar': 123 }));
使用 Vuex 数据管理
- 需要下载 vuex
// 下载 vuex
npm install vuex
- 创建 vuex 声明文件
//在src下创建store/store.js文件
import Vue from 'vue'
import Vuex from 'vuex'
// 声明使用vuex
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
actions: {
},
getters: {
},
mutations: {
}
})
- 在 src 根目录下的 main.js 文件中,配置 Vuex,使每一个实例组件都可以使用
import store from './store/store'
// 将store 对象防止Vue的原型上,每个实例都可以使用 Vuex
Vue.prototype.$store = store
- 具体组件 (page/index/index.vue) 中使用 vuex 管理状态
import {mapState} from 'vuex'
// 在计算属性中,注册使用 vuex中的数据
computed: {
...mapState(['state中的数据名称'])
}
// 调用 vuex中 mutations 的方法
this.$store.commit("add")
分包管理
- 微信小程序规定,一个包的总大小不能超过 2M , 所有包的总大小不能超过 10M
- 小程序分为 主包 和 分包。
- 主包:是 app.json 中 pages 属性定义的 路径内容,都是主包。
- 分包:subpackages 中定义的路径是分包。
- 当我们主包的大小超过 2M 就会报错。 所以我们要将 主包的 一些代码。可以放在分包中,当我们进入分包页面,才会加载其里面的内容。
- app.json 中分包设置:
{
// 主包设置
"pages": [
"pages/login/main",
"pages/index/main",
"pages/logs/main",
"pages/counter/main"
],
// 分包设置 , 分包页面不能设置 tabBar 导航标签
"subpackages": [
{ // {} 为一个分包
"root": "pages/custom", // root设置 这个分包的 根目录 , 不能与主包的相同
"pages": [
"main" // 设置这个分包下几个 路径页面,写main.js
],
"plugins": { // 当前分包可以使用的 plugins 插件
"myPlugin": {
"version": "0.0.5",
"provider": "wxfea216762bcf4ad9"
}
}
}
],
}
- 主包 跳转 到分包:
wx.navigateTo({ url: '../custom/main' })
第三方插件使用:
快递查询插件
地图导航插件
反编译出微信小程序
需要工具
- 夜神模拟器,node 环境,反编译脚本代码:
- 反编译代码:M:\wxapp\wxappUnpacker-master
反编译过程
- 在夜神模拟器上下载 微信 软件。进行登录。
- 安装 PE 文件管理器: E:\百度云下载\Root_Explorer-v4.2.4(3.0 )-Origin_icon_group-Patched_by_Alphaeva.apk . (直接拉进夜神中即可安装)
- 在微信程序中,打开一个小程序。
- 然后通过 PE 找到 /data/data/com.tencent.mm/MicroMsg/{一串 16 进制字符}/appbrand/pkg/ 目录。(通过事件判断,哪个是刚打开的小程序)
- 一般文件大小不会超过 2M .
- 长按文件,进行压缩。 然后通过微信发送给一个好友。
- 电脑端也能查看这个发送的文件 (
.wxapkg
结尾)。
- 通过 反编译 脚本。进行反编译:
cmd 进入到 反编译文件夹中: M:\wxapp\wxappUnpacker-master
安装依赖:
1、npm install esprima
2、npm install css-tree
3、npm install cssbeautify
4、npm install vm2
5、npm install uglify-es
6、npm install js-beautify
7、npm install escodegen -g
//进行反编译命令 C:_163200311_32.wxapkg 为要编译的 小程序代码
node wuWxapkg.js C:_163200311_32.wxapkg
- 编译出的代码文件夹,直接在 微信小程序开发者工具中,导入打开即可。
- 出现 _vd_version_info_is not defined 错误:: 解决:https://www.cnblogs.com/wukong8/p/11612470.html
Git 拉取代码强制覆盖
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于