微信小程序 实现省市区县四级联动
实现
template
<template>
<view class="">
<view class="flex_s index_center_tops">
<view class="flex index_center-center">
<!-- <view class="icon_left" /> -->
<view class="index_left">
居住地址
</view>
</view>
<view class="flex">
<picker
mode="multiSelector"
:value="multiIndex"
:range="multiArray"
@change="multiChange"
@columnchange="columnChange"
range-key="name"
>
<view class="picker">
<!-- {{ multiArray }}, -->
{{ multiArray[0][multiIndex[0]].name }}
{{ multiArray[0][multiIndex[0]].children[multiIndex[1]].name }}
{{
multiArray[0][multiIndex[0]].children[multiIndex[1]].children[
multiIndex[2]
].name
}}
{{
multiArray[0][multiIndex[0]].children[multiIndex[1]].children[
multiIndex[2]
].children[multiIndex[3]].name
}}
</view>
</picker>
<view class="icon_right" />
</view>
</view>
<view style="width:100%;">
<textarea
type="text"
v-model="text"
maxlength="100"
style="padding:20px;background-color:#fff"
placeholder="请输入居住地址"
/>
</view>
<view class="btns">
<view class="btn">保存</view>
</view>
</view>
</template>
script
JSON自己去找
<script>
export default {
data() {
return {
text: "",
multiData: require("../../utils/data.json"),
multiIndex: ["0", "0", "0", "0"],
multiArray: [],
text1: ""
};
},
mounted() {
var _this = this;
console.log(_this.multiData);
var multiData = _this.multiData;
var multiIndex = _this.multiIndex;
console.log();
console.log(283, multiData);
// 初始化多列数据
this.multiArray = [
multiData,
multiData[0].children,
multiData[0].children[0].children,
multiData[0].children[0].children[0].children
];
},
methods: {
// 获取多列的索引
multiChange: function(e) {
var multiIndex = e.detail.value;
// console.log(multiIndex);
this.multiIndex = multiIndex;
this.text1 =
this.multiArray[0][multiIndex[0]].name +
this.multiArray[0][multiIndex[0]].children[multiIndex[1]].name +
this.multiArray[0][multiIndex[0]].children[multiIndex[1]].children[
multiIndex[2]
].name +
this.multiArray[0][multiIndex[0]].children[multiIndex[1]].children[
multiIndex[2]
].children[multiIndex[3]].name;
console.log(this.text1);
},
// 选择列
columnChange: function(e) {
// console.log(e);
var _this = this;
var multiData = _this.multiData;
var multiIndex = _this.multiIndex;
var columnIndex = e.detail.column;
var columnValue = e.detail.value;
multiIndex[columnIndex] = columnValue;
this.multiArray = [
multiData,
multiData[multiIndex[0]].children,
multiData[multiIndex[0]].children[multiIndex[1]].children,
multiData[multiIndex[0]].children[multiIndex[1]].children[multiIndex[2]]
.children
];
}
},
components: {},
computed: {}
};
</script>
style
<style lang="scss">
.picker {
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 28px;
// color: #999999;
letter-spacing: 0.46px;
text-align: right;
margin-right: 30px;
margin-top: 8px;
}
.btns {
position: relative;
top: 30px;
width: 100%;
}
.btn {
margin: 81px auto 0 auto;
width: 690px;
height: 100px;
line-height: 100px;
background: #3aa1f2;
border-radius: 6px;
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 32px;
color: #ffffff;
text-align: center;
}
.index_center_tops {
width: 100%;
background: #ffffff;
padding: 25px 30px;
border-bottom: 1px solid #ccc;
.icon_leftadd {
background: url("../../static/image/my/APP_grxxxg.png");
background-size: 100% 100%;
width: 50px;
height: 50px;
}
.icon_left {
background: url("../../static/image/my/APP_gywm.png");
background-size: 100% 100%;
width: 50px;
height: 50px;
}
.icon_leftone {
background: url("../../static/image/my/APP_tcdl.png");
background-size: 100% 100%;
width: 50px;
height: 50px;
}
}
.flex {
display: flex;
input {
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 28px;
// color: #999999;
letter-spacing: 0.46px;
text-align: right;
margin-right: 30px;
}
}
.flex_s {
display: flex;
justify-content: space-between;
}
.index_left {
margin-left: 20px;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 28px;
color: #333333;
margin-top: 8px;
}
.icon_right {
background: url("../../static/image/my/wd_fh.png");
background-size: contain;
width: 18px;
height: 30px;
margin-top: 12px;
}
</style>
以下是 支付宝支付
业务场景介绍:
H5移动端支持微信支付 [ 微信支付分为微信内支付(JSAPI支付官方API)和微信外支付(H5支付官方API)] && 支付宝支付 [手机网站支付转 APP 支付 官方API ]
订单生成逻辑:前端请求后端提交订单,后端去和微信或者支付宝对接生成订单(后续支付都是这个逻辑进行的对接)
一、移动端微信支付,vue中如何玩?
在移动端微信支付分为微信内支付和微信外支付。
1.在订单组件中选择支付方式之后在支付页面先去判断是否是在微信内:
//判断是否微信
is_weixn(){
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == 'micromessenger'){
return true;
} else {
return false;
}
},
2.触发立即支付方法,根据微信内外的不同请求后端不同的接口,如果是微信外支付非常简单了~
3.【微信外支付】下面先看微信外支付,官方文档也写的很清楚,后端返回一个url地址,前端的工作就是拿到这个url地址进行跳转就可以了,看一下2-3步代码:
handelPay() {
if(this.wechatpayType == 'wxpay'){
// console.log("微信内支付")
let data={
amount:this.number,
}
this.$http.insideWeChatPay(data).then( res => {
if(res.data.code === 200){
this.weChatParameter=res.data.data
// console.log(this.weChatParameter,"微信内支付需要参数")
this.weixinPay()
}else{
Toast({
message: res.data.msg,
position: 'middle',
duration: 1000
});
}
});
} else if(this.wechatpayType == 'wxpay_php'){
// console.log("微信外支付")
let data={
amount:this.number,
}
this.$http.outsideWeChatPay(data).then( res => {
if(res.data.code === 200){
let url=res.data.data
window.location.replace(url) //这里是后端返回的URL直接进行跳转即可完成微信外支付
}else{
Toast({
message: res.data.msg,
position: 'middle',
duration: 1000
});
}
});
}
},
4.在调起支付的页面监听从其他页面返回的事件,进行一些刷新业务逻辑的实现即可,至此微信外支付已经完成。
document.addEventListener("visibilitychange", function() {
//需要的操作
});
5.【微信内支付】微信内支付比起微信外支付稍微复杂一点,但是也不难,(3步骤代码里面已经请求支付方式接口拿到了微信内支付所需要的参数)根据官方API
微信内置js对象 WeixinJSBridge,进行开发,至此微信浏览器内支付已经完成
//解决微信内置对象报错
weixinPay(data){
var vm= this;
if (typeof WeixinJSBridge == "undefined"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', vm.onBridgeReady(data), false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', vm.onBridgeReady(data));
document.attachEvent('onWeixinJSBridgeReady',vm.onBridgeReady(data));
}
}else{
vm.onBridgeReady();
}
},
//微信内置浏览器类,weChatParameter对象中的参数是3.步骤代码中从后端获取的数据
onBridgeReady(){
var vm = this;
var timestamp=Math.round(vm.weChatParameter.timeStamp).toString();
WeixinJSBridge.invoke(
'getBrandWCPayRequest',{
debug:true,
"appId":vm.weChatParameter.appId, //公众号名称,由商户传入
"timeStamp":timestamp, //时间戳,自1970年以来的秒数
"nonceStr":vm.weChatParameter.nonceStr, //随机串
"package":vm.weChatParameter.package,
"signType":vm.weChatParameter.signType, //微信签名方式:
"paySign":vm.weChatParameter.paySign, //微信签名
jsApiList: [
'chooseWXPay'
]
},
function(res){
// 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
if(res.err_msg == "get_brand_wcpay_request:ok" ){
Toast({
message: '支付成功',
position: 'middle',
duration: 3000
});
vm.number=null
vm.$router.go(-1)
//window.location.href = vm.BASE_URL + 'index.html#/depositResult'
}else{
Toast({
message: '支付失败',
position: 'middle',
duration: 3000
});
}
}
);
},
6.微信内部浏览器支付也可以封装一下,在全局都可以直接调用:
//微信浏览器支付
function wxpay(params,callback){
if (typeof WeixinJSBridge == "undefined"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', onBridgeReady(params,callback), false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', onBridgeReady(params,callback));
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady(params,callback));
}
}else{
onBridgeReady(params,callback);
}
}
function onBridgeReady(params,callback){
var that = this
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId":params.appId,
"timeStamp":params.timeStamp,
"nonceStr":params.nonceStr,
"package":params.package,
"signType":params.signType,
"paySign":params.paySign
},
function(res){
callback(res)
}
);
}
7.组件中调用微信支付:
this.commonUtils.wxpay(res.data.data,function(payResult){
if(payResult.err_msg == "get_brand_wcpay_request:ok" ){
//执行
}
})
二、移动端支付宝支付,vue中如何玩?
其实支付宝支付也有H5支付和支付宝浏览器支付,这里只做H5支付,因为已经满足了业务需求。
1.支付宝中的H5支付和PC端的一样,主要是后端的工作量,后端完成订单的生成之后返给前端的是form表单,前端只需要负责做页面的跳转即可:
//立即支付按钮
onSubmit() {
if (this.payWay == 1) {
//支付宝支付
this.$router.push({path: '/aliPay', query: {orderId: this.orderId}});
} else if (this.payWay == 2) {
//微信支付,这里跳转到本文的微信支付模块的3.步骤handelPay方法
}
},
2.选择支付宝方式之后进入支付宝承载页面:
<template>
<div v-html="html"></div>
</template>
<script>
export default {
data(){
return{
html:''
}
},
methods:{
fetchVideoPay(){
let param={
orderId: this.$route.query.orderId
};
this.$api.orderpage.videoAliPay(param).then( res => {
this.html = res.data;
this.$nextTick(() => {
document.forms[0].submit() //渲染支付宝支付页面
})
})
}
},
mounted(){
this.fetchVideoPay()
}
}
</script>
当然不想写承载页的还有其他方法调起支付,具体逻辑具体分析,根据不同的业务类型去变通比如:
const div = document.createElement('div');
div.innerHTML = (res.data); //res.data是返回的表单
document.body.appendChild(div);
document.forms.alipaysubmit.submit();
3.进入到支付宝支付页(至此但有一个问题,调起支付后,用户中途取消支付或者点返回键会整个网页一起关闭退出,或者一直在进入支付页面,不知道有没有更好的SEO方案)