普通的属性的绑定是单向的:
解答:这种的可以通过this.setData({ value :" nb "}),可以将this.data.value修改,也可以将页面上显示的value修改
但是通过页面上的input框来对数据修改是无法修改this.data.value中的值的。
可以使用双向数据绑定
对应属性前加入model:前缀:
解答:这样的话修改input里面的值时就可以修改this.data.value中的值。
但是小程序双向数据绑定有很大的局限性:
与vue相比,暂不支持表达式形式:
data: {
a:{b:'hello'}
}
自定义组件(子组件)向父组件传参数:
同样可以使用双向数据绑定:
自定义组件的js文件,通过properties接收父组件传递的数据myValue
// custom-component.js
Component({
properties: {
myValue: String
}
})
自定义组件的wxml文件,修改父组件传来的数据myValue
父组件中使用自定义组件custom-component
当输入框的值变更时,自定义组件的 myValue属性会同时变更,父组件页面的 this.data.pageValue 也会同时变更,页面 WXML 中所有绑定了 pageValue的位置也会被一同更新。
Page({
//声明节点查询的方法
queryMultipleNodes: function() {
const query = wx.createSelectorQuery() // 创建节点查询器 query
query.select('#productServe').boundingClientRect() // 这段代码的意思是选择Id=productServe的节点,获取节点位置信息的查询请求
query.select('#enterpriseServe').boundingClientRect() // 这段代码的意思是选择Id=enterpriseServe的节点,获取节点位置信息的查询请求
query.select('#normalServe').boundingClientRect() // 这段代码的意思是选择Id=normalServe的节点,获取节点位置信息的查询请求
query.selectViewport().scrollOffset() // 这段代码的意思是获取页面滑动位置的查询请求
query.selectAll('#txt-light1').boundingClientRect() //获取全部id为txt-light1的节点
query.exec((res) => { //获取这个节点(可以看成一个数组)通过下标获取里面的详细数据
res[0].top // #productServe节点的到页面顶部的距离
res[1].width // #enterpriseServe节点的宽度
res[2].height // #normalServe节点的高度
})
}
})
console.log(res) 输出节点信息详情
1,安装:
cnpm i @vant/weapp -S --production
2,修改app.json以及project.config.json:
将 app.json中的"style": "v2"去除,小程序的新版基础组件强行加上了许多样式,难以去除,不关闭将造成部分组件样式混乱。
3,构建npm包:
打开微信开发者工具,点击 工具 -> 构建 npm,并勾选 使用 npm 模块 选项,构建完成后,即可引入组件。
4,注册组件:
以 Button 组件为例,只需要在app.json或index.json中配置 Button 对应的路径即可。如果你是通过下载源代码的方式使用 @vant/weapp,请将路径修改为项目中 @vant/weapp 所在的目录。
// 通过 npm 安装
// app.json
"usingComponents": {
"van-button":"/miniprogram_npm/vant-weapp/button/index"
}
5、使用组件
引入组件后,可以在 wxml 中直接使用组件
按钮
1,下载:
git clone [email protected]:youzan/vant-weapp.git
2,将下载好项目中的dist目录拷贝到小程序目录下,改名为vant
3,在app.json中全局注册
"usingComponents":{
"van-button": "/vant/button/index"
},
4,在任意wxml中使用
按钮
对于小程序未授权的用户,官方取消wx.getUserInfo方法的直接调用,首次授权必须主动触发自定义按钮,给按钮设置open-type=“getUserInfo”,通过bindgetuserinfo触发自定义事件,获取到用户本身的信息,如果获取到,那么在进入小程序时我们要进行注册,注册时我们要传递三个参数(wx.login来获取code,wx.getuserinfo来获取iv和encryptedData , iv 加密后的值, code 微信登录接口返回的 code 参数 ,encryptedData 加密数据,),注册成功后在进行登录,执行登录的login方法,
再用wx.login来获取code,判断数据中的code来确定是否登录成功,成功之后通过登录拿到token,将用户信息和token通过setStroageSync存储在本地存储中,并触发(生命周期)onShow(),在onShow()中调用一个方法通过用户信息接口传入token来获取用户的详细信息,渲染到页面上
看代码:
封装网络模块 :创建http目录,下面生成三个文件 :api.js ,http.js ,fetch.js
//api
module.exports={
"registor":"/user/wxapp/register/complex",//注册
"login":"/user/wxapp/login",//登陆
"userDetail":"/user/detail"//用户详细信息
}
//fetch
module.exports=(url,method,data)=>{
let p=new Promise((resolve,reject)=>{
wx.request({
url: url,
method:method,
header:{'Content-Type': 'application/x-www-form-urlencoded'},
data:Object.assign({},data),
success(res){
resolve(res)
},
fail(err){
reject(err)
}
})
})
return p;
}
//http
const api = require('./api')
const fetch = require('./fetch')
const baseUrl="https://api.it120.cc/tianxing";//基础域名
//注册
function registor(data={}){
return fetch(baseUrl+api.registor,'post',data)
}
//登陆
function login(data){
return fetch(baseUrl+api.login,'post',data)
}
//用户详细信息
function userDetail(data){
return fetch(baseUrl+api.userDetail,'get',data)
}
module.exports={
registor,
login,
userDetail
}
通过一个事件来触发processLogin
立即登录
执行processLogin
//立即登录
processLogin(e) {
console.log(e);
if (!e.detail.userInfo) {
wx.showToast({
title: '已取消',
icon: 'none',
})
return;
}
// 如果有userinfo ,就调用register注册方法
this.registor();
},
如果获取到用户信息,使用registor注册方法
三个参数 iv 加密值,code 微信登录接口返回的 code 参数,encryptedData 加密数据
//注册
registor(){
let _this = this;
//调用接口获取登录凭证(code)唯一标识(openid)及本次登录的会话密钥(session_key)
wx.login({
success: function (res) {
let code = res.code; // 微信登录接口返回的 code 参数,下面注册接口需要用到
wx.getUserInfo({ //获取用户信息
success: function (res) {
let iv = res.iv; //加密算法的初始向量
let encryptedData = res.encryptedData; //完整用户信息的加密数据
// 下面开始调用注册接口
http.registor({ //微信小程序用户快速注册
code: code,
encryptedData: encryptedData,
iv: iv
}).then(function (res) {
console.log(res);
_this.login();
})
}
})
}
})
},
注册成功去登录,并获取token
//登陆
login(page){
const _this = this
wx.login({ // 获取登陆凭证 code
success: function (res) {
console.log(res)
//调用登陆接口,传code
http.login({code:res.code,type:2}).then(function (res) {
console.log(res)
res=res.data;
if (res.code != 0) {
// 登录错误
wx.showModal({
title: '无法登录',
content: res.msg,
showCancel: false
})
return;
}
console.log(res)
wx.setStorageSync('token', res.data.token)
wx.setStorageSync('uid', res.data.uid)
_this.onShow()
})
}
})
},
触发onshow()
onShow: function () {
this.getUserApiInfo();
},
利用getUserApiInfo方法获取用户详细信息,渲染到页面上
//获取用户详情信息
getUserApiInfo() {
console.log(10000)
var that = this;
//后去用户详细信息
http.userDetail({token:wx.getStorageSync('token')}).then(function (res) {
console.log(res);
if (res.data.code == 0) {
// let _data = {}
// _data.apiUserInfoMap = res.data
// that.setData(_data);
that.setData({
apiUserInfoMap:res.data.data
})
}
})
},
触发=一个事件通过removeStorageSync来删除本地存储里面的全部数据,在使用reLaunch重新跳转至当前页面,从而达到刷新页面的效果
点击退出按钮
//退出函数
loginOut(){
wx.removeStorageSync('token')
wx.removeStorageSync('uid')
wx.reLaunch({
url: '/pages/mylogin/mylogin'
})
},
要知道每个人openID都是不同的,它是用户身份识别的id,也就是说,为了知道谁在支付,我们需要先获取当前用户的openid,通过openID来区分不同的用户,所以
首先使用小程序调用登陆接口通过wx.login()获取临时的登录权限code,在使用wx.request并把它传到开发者服务器( 【url:商户服务器登陆url ,code: code,method: ‘ 方法 ’ ,建议使用post安全,以及获取成功的函数和获取失败的函数 】)用来获取用户唯一标识的openid 和 会话密钥session_key,可以在获取成功的函数里获取一个token来进行用户验证,并将token存在小程序缓存中,
getToken: function () {
//调用登录接口
wx.login({
success: function (res) {
var code = res.code;
wx.request({
url: "商户服务器登陆url",
data: {
code: code
},
method: 'POST',
success: function (res) {
wx.setStorageSync('token', res.data.token); //存在小程序缓存中
},
fail: function (res) {
console.log(res.data);
}
})
}
})
}
设置‘提交订单’事件,创建订单,并清空购物车(【调用创建订单接口,传递此次订单相关数据】 ),
const wxpay = require('../../utils/pay.js')'
//去创建订单
goCreateOrder(){
//检测实名认证状态
//创建订单
this.createOrder(true)
}
//创建订单
createOrder(){
var that = this;
var loginToken = wx.getStorageSync('token') // 用户登录 token
var remark = this.data.remark; // 备注信息
let postData = { //创建订单需要的参数
token: loginToken,//token
goodsJsonStr: that.data.goodsJsonStr, //购买的商品数据列表
remark: remark,//备注信息
peisongType: that.data.peisongType// // 配送方式 kd,zq 分别表示快递/到店自取
};
//调用创建订单接口,传递此次订单相关数据
WXAPI.orderCreate(postData).then(function (res) {
that.data.pageIsEnd = true
if (res.code != 0) {
that.data.pageIsEnd = false
wx.showModal({
title: '错误',
content: res.msg,
showCancel: false
})
return;
}
if ("buyNow" != that.data.orderType) { //订单类型,购物车下单或立即支付下单,默认是购物车,
// 清空购物车数据
WXAPI.shippingCarInfoRemoveAll(loginToken)
}
that.setData({
totalScoreToPay: res.data.score, //积分
isNeedLogistics: res.data.isNeedLogistics, 是否需要物流信息
allGoodsAndYunPrice: res.data.amountReal,//总价=总商品价+总运费
yunPrice: res.data.amountLogistics,//运费
hasNoCoupons,//没有优惠券
coupons,//优惠券
couponAmount: res.data.couponAmount //优惠金额
});
that.data.pageIsEnd = false
return;
}
//创建订单后的操作
that.processAfterCreateOrder(res)
})
//创建订单后的操作
async processAfterCreateOrder(res) {
// 直接弹出支付,取消支付的话,去订单列表
const balance = this.data.balance
if (balance || res.data.amountReal*1 == 0) {
// 有余额
const money = (res.data.amountReal * 1 - balance*1).toFixed(2)
if (money <= 0) {
// 余额足够
wx.showModal({
title: '请确认支付',
content: `您当前可用余额¥${balance},使用余额支付¥${res.data.amountReal}?`,
confirmText: "确认支付",
cancelText: "暂不付款",
success: res2 => {
if (res2.confirm) {
// 使用余额支付,传token,和订单id
WXAPI.orderPay(wx.getStorageSync('token'), res.data.id).then(res3 => {
if (res3.code != 0) {
wx.showToast({
title: res3.msg,
icon: 'none'
})
return
}
wx.redirectTo({
url: "/pages/order-list/index"
})
})
} else {
wx.redirectTo({
url: "/pages/order-list/index"
})
}
}
})
} else {
// 余额不够
wx.showModal({
title: '请确认支付',
content: `您当前可用余额¥${balance},仍需支付¥${money}`,
confirmText: "确认支付",
cancelText: "暂不付款",
success: res2 => {
if (res2.confirm) {
// 使用余额支付
wxpay.wxpay('order', money, res.data.id, "/pages/order-list/index");
} else {
wx.redirectTo({
url: "/pages/order-list/index"
})
}
}
})
}
} else {
// 没余额
wxpay.wxpay('order', res.data.amountReal, res.data.id, "/pages/order-list/index");
}
},
//查看用户资产
async userAmount() {
const res = await WXAPI.userAmount(wx.getStorageSync('token'))
if (res.code == 0) {
this.setData({
balance: res.data.balance
})
}
},
}
然后再调用一下下单接口,获取预支付信息prepay_id,将组合数据再一次签名,调用支付函数,会出现几种可能:1,直接弹出支付,取消支付的话,去别的也页面,2,如果购买余额足够 使用余额支付,需要传token,和订单id,3,余额不够,取消支付不再支付,2,通过WXAPI.wxpay调用微信余额进行支付,确定支付时:通过wx.requestPayment()获取五个参数后,调起支付
//五个重要的参数
timeStamp: res.data.timeStamp, //时间戳
nonceStr: res.data.nonceStr,,//随机字符串
package: res.data.package,//订单详情扩展字符串
signType: res.data.signType//签名方式
paySign: res.data.paySign,//签名
出现支付成功(【出现二维码扫码支付】)与支付失败(【网络不佳】)两种情况
小程序发布详细步骤…