尺寸单位
当屏幕宽度等于 750px 时,1px = 1rpx
当屏幕宽度等于375px时, 1px =0.5rpx
样式导入只支持相对路径
内置组件
**view标签 **相当于 div标签
text标签能嵌套text标签 长按文字可以复制
image标签 ** ** 打包上线的大小不能超过2M,使用图片的时候统一使用外网图片
图片存在默认的宽高(320px * 240px)
小程序中的图片 直接支持 懒加载
lazy-load 会自己判断 当图片出现在视口的上下三屏之内的时候,自己开始加载图片
swiper标签 轮播图
<swiper autoplay interval="1000" circular indicator-dots>
// 图片存在默认宽高 320 * 240
<swiper-item><image model="widthFix" src="" /></image></swiper-item>
</swiper>
rich-text(富文本标签,将字符串解析成对应标签,相当于v-html)
// 1 标签字符串
<rich-text nodes="{{ html }}"></rich-text>
// 2 对象数组
<rich-text nodes="{{ html.model }}"></rich-text>
button 按钮
大小(size:mini/default),颜色(type:default/primary/warn),是否镂空(plain),
是否在文字前有加载loading(loading),开发能力(opentype)
开放能力(opentype):
concat 直接打开 客服对话 功能,需要在小程序的后台配置
(将小程序的appid由测试号改为自己的appid,登录微信小程序官网,添加 客服 - 微信)
share 转发当前小程序到微信朋友中 ,不能把小程序转发到朋友圈中
getPhoneNumber 获取当前用户的手机号码,结合事件来使用,不是企业的小程序账号 没有权限来获取用户的手机号码
getUserInfo获取用户的个人信息
launchApp在 小程序 中直接打开 app
openSetting 打开小程序内置的授权页面,只会出现用户点击过的权限
feedback 打开小程序内置的意见反馈页面
radio 单选框
<radio-group bindchange="handleChange">
<radio color="red" value="male">男</radio>
<radio color="red" value="female">女</radio>
</radio-group>
<view>选中的是: {{ gender }} </view>
data:{
gender: ""
},
handleChange(e) {
// 获取单选框选中的值
let gender = e.detail.value;
// 把值赋值给data中的数据
this.setData({
gender // 相当于 gender:gender
})
}
checkbox 多选框
<checkbox-group bindchange="handleChange">
<checkbox value="{{ item.value }}" wx:for="{{ list }}" wx:key="id">{{ item.name }}</checkbox>
</checkbox-group>
<view>选中的是: {{ checkedList }} </view>
checkedList:[]
handleChange(e) {
let checkedList = e.detail.value;
this.setData({
checkedList
})
}
父组件向子组件传值
通过 标签的属性来传递的:
父组件传递
子组件接收
Component({
// 里面存放的是要从父组件中接收的数据
properties: {
// 要接受的数据的名称
aaa:{
//type 接收数据的类型
type: String,
//value 默认值
value: ""
}
}
});
子组件使用父组件中传递过来的数据
将接收过来的数据当作本身data中的数据来使用
子组件向父组件传值
通过事件来传递的。
eg:tab切换栏,点击切换。
-
绑定点击事件 需要在methods中绑定
-
获取被点击的索引
-
获取原数组
-
对数组循环
-
点击事件触发的时候,触发父组件中的自定义事件同时传递给父组件
this.triggerEvent(“父组件自定义事件的名称”,要传递的参数)
Tabs页面中:
<view
wx:for="{{tabs}}"
wx:key="id"
class="title_item {{item.isActive?\'active\':\'\'}}"
bindtap="hanldeItemTap"
data-index="{{index}}"
>{{ item.name }}</view>
<view class="tabs_content">
// 占位符 传递的参数会替换掉
<slot></slot>
</view>
子组件的js文件中:
methods: {
hanldeItemTap(e) {
// 获取索引
const {index} = e.currentTarget.dataset;
// let {tabs} = this.data;
// tabs.forEach((v,i) => i===index?v.isActive=true:v.isActive=false);
// 修改data中的数据
// this.setData({
// tabs
// })
// 触发父组件中的自定义事件同时传递给父组件
this.triggerEvent("itemChange", {
index
})
}
}
在父组件中的自定义组件中添加自定义事件:
<Tabs binditemChange="handleItemChange">
<block wx:if="{{tabs[0].isActive}}">1</block>
<block wx:if="{{tabs[1].isActive}}">2</block>
<block wx:else>3</block>
</Tabs>
父组件的js中:
data: {
tabs: [
{
id: 1,
name: "首页",
isActive: true
},
{
id: 2,
name: "待发货",
isActive: false
},
{
id: 3,
name: "待付款",
isActive: false
}
]
}
// 自定义事件 接收子组件传递的数据的
handleItemChange(e) {
// 接收传递过来的参数
const {index} = e.detail;
// 拿到原数组
let {tabs} = this.data;
tabs.forEach((v,i) => i===index?v.isActive=true:v.isActive=false);
// 修改data中的数据
this.setData({
tabs
})
}
小程序的第三方框架
-
腾讯 wepy 类似于 vue
-
美团 mpvue 类似于 vue
-
京东 taro 类似于 react
-
滴滴 chameleon
-
uni-app 类似于 vue
-
原生框架 MINA
页面样式的初始化
注意:在小程序中是不支持 通配符(*)的
在app.wxss文件中
page,view,text,swiper,swiper-item,image,navigator {
padding: 0;
margin: 0;
box-sizing: border-box;
}
/*
主题颜色
1. less 中是存在 变量 的
2. 原生的css和wxss 也是支持 css的
*/
page {
--themeColor: #eb4500;
// 设计稿大小为 375px 时,1px = 2rpx,14px = 28rpx
font-size: 28rpx;
}
使用主题颜色:
view {
color: var(--themeColor);
}
解决回调地狱的问题(es6的promise)
在项目的request文件夹中创建index.js文件
通过封装方法,然后调用函数传递参数的方式来使用
// 同时发送异步代码的次数
let ajaxTime=0;
export const request=(params) => {
ajaxTime++;
// 数据加载效果
wx.showLoding({
title: "加载中",
mask: true
});
return new Promise((resolve, reject) => {
wx.request({
// 解构传递的参数
...params,
success: (result) => {
resolve(result);
},
faile: (err) => {
reject(err);
},
// 不管是成功还是失败都会调用这个函数
complete: () => {
ajaxTime--;
if(ajaxTime === 0) {
// 关闭正在等待的图标
wx.hideLoading();
}
}
});
});
}
使用封装好的请求方法:
// 引入封装文件 (注意: 一定要把路径补全)
import { request } from \'../../request/index.js\'; // 这里引入的是封装的request函数
Page({
data: {
swiperList: []
},
// 页面加载事件
onLoad: function() {
/*
1. 发送异步请求 获取使用的数据
*/
/*
wx.request({
url: \'\', // 接口地址
success: (result) => {
// 请求成功 给swiperList数组赋值
this.setData({
swiperList: result.data.message
})
}
});
*/
/*
wx.request异步请求太多了就会产生 回调地狱 的问题
解决方法: es6中的promise
*/
// 调用方法
this.getSwiperList();
},
// 调用封装好的方法
getSwiperList() {
// 这里填充的数据会替换掉request方法中的...params,
request({ url: \'htltps://api/zbtbs/home/swiperList\'});
// 数据获取成功
.then (result => {
this.setData({
swiperList: result.data.message
})
});
}
})
获取本地存储的数据
小程序中:
存储方式:wx.setStorageSync(“key”, “value”);
获取方式:wx.getStorageSync(“key”, “value”);
不存在数据的类型转换
定义公共的url
在request.js文件中,封装请求方法
export const request=(params) => {
// 定义公共的url
const baseUrl = "https://api.zbsb.cn/api/public"
return new Promise((resolve, reject) => {
wx.request({
// 解构传递的参数
...params,
url: baseUrl + params.url;
success: (result) => {
resolve(result);
},
faile: (err) => {
reject(err);
}
});
});
}
小程序url传参
// 传递参数
<navigator wx:for="Cates" wx:for-item="item" wx:for-index="index" wx:key="id" url="/pages/goods/index?cid={{item.cid}}"></navigator>
// 拿取参数
onLoad:function(options) {
consol.log(options); // 打印输出options的值
}
滚动条触底事件(页面上滑事件)
滚动条触底,加载下一页数据
总页数 = Math.ceil(总条数 / 每页显示的数据数)
// 获取商品数据列表
async getGoodsList() {
const res=await request({url:"/goods/search",data:this.QueryParams});
// 获取总条数
const total = res.total;
// 计算总页数
this.totalPage = Math.ceil(total / this.QueryParams.pagesize);
// 拼接数组
this.setData({
goodsList: [...this.data.goodsList,...res.goods]
});
// 关闭下拉刷新的窗口
wx-stopDownRefresh();
}
// 滚动条触底事件
onReachBottom() {
// 判断还有没有下一页数据
if(this.QueryParams.pagenum >= this.totalPage) {
// 当前页码 > 总页数 没有下一页
}
else {
// 还有下一页 当前页码++ 重新发送请求 数据请求回来后要对data中的数组进行拼接
this.QueryParams.pagenum++;
this.getGoodsList();
}
}
下拉刷新页面
-
触发下拉刷新事件(需要在页面的json文件中开启一个配置项)【enablePullDownRefresh: true,backgroundTextStyle: dark】
-
重置 数据 数组
-
重置页码 设置为1
-
重新发送请求
-
数据请求成功,手动关闭等待效果
onPullDownRefresh() {
// 重置 数据 数组
this.setData({
goodsList: []
});
// 重置页码 设置为1
this.QueryParams.pagenum=1;
// 重新发送请求
this.getGoodsList();
}
js中的删除
cart.splice(index, 1); // 删除索引为index的元素
cart.filter(v => v.checked); // 挑选出cart数组中checked为true的值
弹窗的封装
在asyncWX.js文件中
export const showModel=({content}) => {
return new Promise((resolve,reject) => {
wx.showModel({
title: \'提示\',
content: content,
success :(res) > {
resolve(res);
},
fail :(err) => {
reject(err);
}
})
})
}
使用
import {showModel} from \'../../utils/asyncWx.js\';
async showTips() {
const res=await showModel({content: \'您是否要删除?\'})
if(res.confirm) {
cart.splice(index, 1);
this.setData(cart);
}
}
微信支付
1.企业账号
在企业账号的小程序后台中 必须 给 开发者添加上白名单
一个AppID可以绑定多个开发者
2.绑定之后的开发者就拥有了开发者的权限了
3.支付按钮
先判断缓存中有没有token
没有 跳转到授权页面 获取用户的 token 值
有 执行支付操作
流程:创建订单,准备预支付,发起微信支付,查询订单
**一获取token**
handleOrderPay() {
try {
// 1. 判断缓存中有没有token值
const token = wx.getStorageSync("token");
// 2. 判断
if(!token) {
// 跳转到 授权 页面
wx.navigateTo({
url: "/page/auth/index"
})
return;
}
// 3. 创建订单
// 准备创建订单需要的参数
const header = {Authorization:token};
// 准备请求体参数
const order_price = this.data.totalPrice; // 订单总价格
const consignee = this.data.address.all; // 详细地址
let goods = [];
const cart = this.data.cart;
goods.forEach(v => goods.push({
goods_Id: v.goods_Id, // 商品的id
goods_number: v.goods_number, //商品数量
goods_price: v.goods_price // 商品的单价
}))
const orderParams = {order_price,consignee,goods}
// 4. 准备发送请求 创建订单 获取订单编号
const {order_number}=await request({url: "/order/create"},method:"POST",data:orderParams,head:head});
// 5. 发起 预支付接口
const {pay}=await request({url:"/order/req_unifiedorder",method:"POST",head,data:{order_number}});
// 6. 发起微信支付
await requestPayment(pay);
// 7. 查询后台 订单状态是否成功
const res=await request(url:"/orders/chkOrder",method:"POST",head,data:{order_number}});
// 提示支付成功
await showToast({title:"支付成功"});
// 手动删除 缓存中支付成功购物车的数据
let newCart = wx.getStorageSync("cart");
// 过滤出没有被选中的数据
newCart = newCart.filter(v => !v.checked);
wx.setStorageSync("cart",newCart);
// 8.支付成功 跳转到订单页面
wx.navigateTo({
url: \'/page/order/index\'
})
} catch(err) {
await showToast({title:"支付失败"});
}
}
page/autn/index页面中:获取授权
<button open-type="getUserInfo" bindgetUserInfo="handleGetUserInfo">
获取授权
</button>
// 获取用户信息
// encryptedData
// rawData
// iv
// signature
async handleGetUserInfo(e) {
try {
// 获取用户信息
const { encryptedData,rawData,iv,signature } = e.detail;
// 获取小程序登录之后的token值 在asyncWX.js中封装token请求方法
// wx.login({
// timeout: 1000,
// success: (result) => {
// cost { code } = result;
// }
// })
const {code} = await login();
const loginParams = { encryptedData, rawData, iv, signature, code }
// 发送请求 获取用户的token
const {token}=await request(url: \'/user/wxlogin\',data: loginParams,methods: "post");
// 将获取到的token存储到缓存中,同时跳转回上一个界面
wx.getStroageSync("token", token);
wx.navigateBack({
data: 1 // 返回上一层
})
} catch(err) {
console.log(err);
}
}
在asyncWX.js文件中封装支付方法:
export const requestPayment=(pay) => {
return new Promise((resolve,reject){
wx.request({
...pay,
success: (result) => {
resolve(result);
},
fail: (err) => {
reject(err);
}
})
})
}
二,准备预支付(获取参数 pay)
三,发起微信支付(提交pay参数)
四,查询订单
五,删除缓存中已经被选中购买的商品
六,删除后的购物车数据 填充会缓存
七,跳转页面
项目发布
注意:发布之前记得关闭详情界面的 不校验合法域名
上传的每个文件大小不超过2M,总大小不超过10M
上传:
版本号
第一个数字(大版本的更新)
第二个数字(重要功能更新)
第三个数字(最小功能,小bug,小补丁)
less文件是不会被打包上传的
上传成功后的小程序还是一个体验版本的小程序,如果需要将体验版本的小程序变成线上版本的小程序,
就在 微信公众平台将提交的体验本的小程序,提交审核(审核的时间大概是一个小时)。
请发表评论