История мини-программ
Что такое мини-программа WeChat?
Маленькая микроканальная программа, называемая апплетами. английское имяmini program
, это приложение, которое можно использовать напрямую, без загрузки и установки. Он осуществил свою мечту. Пользователи могут сканировать или выполнять поиск, чтобы открыть приложение напрямую.
Почему мини-программы WeChat
- WeChat имеет большое количество пользователей
- Стоимость продвижения приложения или официального аккаунта слишком высока
- Низкая стоимость разработки и адаптации
- Легко пробовать и ошибаться в небольшом масштабе, а затем быстро повторять
- Кроссплатформенность
история
- 11 января 2016 г. Чжан Сяолун, новая форма внутреннего исследования WeChat,
应用号
, позже переименованный小程序
. - 12 августа 2016 года началось внутреннее тестирование
- 9 января 2017 г., онлайн
#экологическая спецификация
-
Зарегистрировать аккаунт
mp.weixin.qq.com/(Информация об учетной записи --- Активация по электронной почте --- Регистрация информации)
-
получить идентификатор
ПРИЛОЖЕНИЕ (Войдите на общедоступную платформу WeChat---> Разработка ---> Настройки разработки)
-
инструменты разработчика
Инструменты разработчика мини-программ
Введение в инструменты разработчика
Ярлыки:
1. ctrl + shift + F (搜索)
2. alt + shift + F (代码格式化---VSCode)
Нативный фреймворк для небольших программ
Нативные рамки апплета, минаДетали кадров
Небольшой конфигурационный файл (в конфигурационный файл напишите письмо, написанное в micro Developer Tools, там есть подсказки)
-
app.json Глобальный файл конфигурации
настроить глобальный файл
-
страницы: добавьте элемент файла, который будет создан, и файл будет автоматически сгенерирован после сохранения
-
windows: установить цвет строки состояния, панели навигации и окна заголовка апплета.
-
* [tabBar](https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html)
2. page.json файл конфигурации страницы 3. sitemap
Шаблон синтаксис апплета
WXML ---> HTML (в сочетании с базовыми компонентами, системой событий и структурой страницы компонентов)
- эквивалентно, встроенная метка, не переносится
- эквивалентно, элемент блочного уровня, будет обернут
привязка данных
{{ данные }}
-
Расчет -> выражение (численный расчет, объединение строк, троичное выражение)
-
Цикл списка (wx:for)
wx:key привязан к единственному атрибуту в массиве, wx:key=*это указывает, что массив
普通数组
,*this
это срок цикла<view wx:for="{{ person }}" wx:for-item="item" wx:for-index="index" wx:key="id" > 索引: {{ index }} 名称: {{ item.name }} </view>
-
Метка ---> метка-заполнитель
-
Условный рендеринг (wx:if) (wx:if, wx:elif, wx:else) (скрытый атрибут отображается путем добавления стилей)
Используйте if, когда метка не часто переключается, и используйте hidden, если часто переключаете
привязка события
Ключевое слово: bind (bindinput, bindtap [событие клика])
Получите значение объекта источника события:
e.detail.value
Получить значение данных в data:
this.data.属性名
Установите значение объекта источника события обратно в данные:
this.setData({
num: this.data.num + operation
});
Привязка события не может передавать параметры напрямую, но передает параметры через настраиваемые свойства ( {{ переданные параметры}} ):
<button bindtap="bandletap" data-operation="{{ 1 }}">+</button>
bandletap(e) {
// console.log(e);
const operation = e.currentTarget.dataset.operation;
this.setData({
num: this.data.num + operation
});
},
стиль
измерительное устройство
Когда ширина экрана равна 750px, 1px = 1rpx
Когда ширина экрана равна 375px, 1px = 0.5rpx
Импорт стилей поддерживает только относительные пути
Селектор (апплет WeChat не поддерживает подстановочные знаки)
Встроенные компоненты мини-программы
Обычно используемые компоненты макета в апплете:
view,text,rich-text,button,image,icon,swiper,radio,checkbox等。
-
тег просмотра эквивалентен тегу div
-
текстовый тег Вложенными могут быть только текстовые теги Длительное нажатие на текст для копирования [выбирается] (эта функция есть только у этого тега) Можно кодировать возврат каретки и пробелы (декодировать)
-
тег изображения (размер упакованного онлайн не может превышать 2М, а при использовании изображений равномерно используются изображения из внешней сети)
-
Изображение имеет ширину и высоту по умолчанию (320 пикселей * 240 пикселей).
-
режим определяет содержимое изображения и теги изображения для адаптации
Значение по умолчанию для scaleToFill не поддерживает соотношение сторон, растягивается до ширины и высоты, определенных меткой.
аспектфит поддерживает соотношение сторон, чтобы длинная сторона изображения отображалась полностью (обычно используется для карусельных изображений).
Короткая кромка аспекта Fill отображается полностью
widthFix Ширина не меняется, высота изменяется автоматически, сохраняя исходное соотношение сторон неизменным
верхнее, левое, нижнее, правое расположение фонового изображения
-
Изображения в апплете напрямую поддерживают ленивую загрузку.
Ленивая загрузка будет судить сама по себе Когда изображение появится в пределах трех верхних и нижних экранов области просмотра, оно начнет загружаться само по себе.
-
-
swiper label ---> Карусель
Высота Swiper = ширина Swiper * высота изображения / исходная ширина изображения
<swiper autoplay interval="1000" circular indicator-dots> // 图片存在默认宽高 320 * 240 <swiper-item><image model="widthFix" src="" /></image></swiper-item> </swiper>
-
компонент навигации навигатора (элемент уровня блока, упаковка по умолчанию)
<navigator url="/pages/homepage/index" open-type="navigate"></navigator>
-
форматированный текст (теги форматированного текста, анализ строк в соответствующие теги, эквивалентные v-html)
// 1 标签字符串 <rich-text nodes="{{ html }}"></rich-text> // 2 对象数组 <rich-text nodes="{{ html.model }}"></rich-text>
-
кнопка кнопка
Размер (размер: мини/по умолчанию), цвет (тип: по умолчанию/основной/предупреждающий), является ли он пустым (обычным), есть ли загрузка перед текстом (загрузка), возможность разработки (открытый тип)
Открытая возможность (открытый тип):
-
concat напрямую открывает диалоговую функцию обслуживания клиентов, которую необходимо настроить в фоновом режиме апплета.
- Измените AppID апплета из номера теста на свой собственный AppID
- Войдите на официальный сайт апплета WeChat и добавьте службу поддержки — WeChat
-
поделиться пересылает текущий апплет друзьям WeChat, но не может переслать апплет в круг друзей
-
getPhoneNumber Получить номер мобильного телефона текущего пользователя и использовать его совместно с событиями. Это не маленькая учетная запись программы предприятия. Нет разрешения на получение номера мобильного телефона пользователя.
-
getUserInfo получает личную информацию пользователя
-
launchApp напрямую открывает приложение в апплете
-
openSetting Открывает встроенную в апплет страницу авторизации
Появятся только те разрешения, на которые нажал пользователь.
-
обратная связь Открыть встроенную страницу обратной связи апплета
-
-
icon
тип: введите успех, success_no_circle, информация, предупреждение, wating.success_no_circle, информация, предупреждение, ожидание, отмена, загрузка, поиск, очистка
size: номер размера/строка
цвет: цвет
-
радио кнопка радио
<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-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 }) }
жизненный цикл апплета
жизненный цикл приложения
Триггерный процесс:
при запуске -> при показе
App({
// 1 应用 第一次启用的时候触发
onLaunch() {
// 在应用第一次启动的时候 获取用户信息
}
// 2 应用 被用户看到的时候触发
onShow() {
// 常用于小程序界面之间的切换
// 对应用的数据或者页面的效果进行重置
}
// 3 应用 被隐藏的时候触发
onHide() {
// 暂停或者清楚定时器
}
// 4 应用 代码发生报错的时候 执行
onError() {
// 在应用发生代码报错的时候,收集用户的错误信息,通过异步请求,将错误信息发送到后台去
}
// 5 页面找不到的时候就会触发
// 应用第一次启动的时候,如果找不到第一个入口页面,才会触发
onPageNotFound() {
// 如果页面不存在了 通过js的方式来重新跳转页面 重新跳转到第二个首页
// 不能跳转到tabbar页面 导航组件类似
wx.navigateTo({
url: "/pages/demo02/index"
})
}
})
жизненный цикл страницы
onLoad -> onShow -> onReady
Page({
data: {
},
onLoad: function(options) {
// onload发送异步请求来初始化页面数据
},
onShow: function() {
// 页面显示加载
},
onReady: function() {
// 页面初次渲染完成
},
onHide: function() {
// 页面隐藏时加载 一个页面跳转到另外一个页面也会触发onHide事件
},
onUnload: function() {
// 页面卸载 也可以通过超链接 关闭当前页面就会触发onUnload事件
// <navigator url="/pages/demo01/demo01" open-typr-redirect>demo01</navigator>
// 关闭当前页面就代表着卸载页面
},
onPullDownRefresh: function() {
// 监听用户下拉事件 "enablePullDownRefresh":true
// 页面效果的重新加载
},
onReachBotton: function() {
// 监听用户上拉触底事件 【需要让页面出现上下的滚动才行】
// 常用于 上拉加载下一页操作
},
onShareAppMessage: function() {
// 用户点击右上角转发
},
onPageScroll: function() {
// 页面滚动就触发
},
onResize: function() {
// 页面尺寸发生变化的时候触发
// 常指 手机横屏竖屏的时候 触发
// app.json中添加 "pageOrientation":"auto"
},
onTabItemTap: function() {
// 1. 当前页面必须为tabbar页面
// 2. 点击的是自己的tab item的时候才触发
}
})
Пользовательские компоненты мини-программы
шаг:
-
Создайте
-
Объявление (эта страница хочет использовать пользовательский компонент, просто объявите его в файле json этой страницы)
{ "usingComponents": { "Tabs": "../../components/Tabs/Tabs" } }
-
использовать
<Tabs></Tabs>
Уведомление:
-
В файле страницы .js сохраните функцию обратного вызова события, сохраните тот же уровень в DATA
-
В файле .js компонента при сохранении callback-функции времени она хранится в методах
-
Не передавать напрямую в апплет
this.data.x.
Чтобы изменить значение массива (рекомендуется сначала скопировать массив, а затем изменить скопированный массив)let tabs = JSON.parse(JSON.stringify(this.data.tabs)); let tabs = this.data;
Передача значений между компонентами
родительский компонент передает значение дочернему компоненту
пройти через标签的属性
пройти:
-
доставка родительского компонента
<Tabs aaa="123"></Tabs>
-
Подкомпоненты получают
Component({ // 里面存放的是要从父组件中接收的数据 properties: { // 要接受的数据的名称 aaa:{ //type 接收数据的类型 type: String, //value 默认值 value: "" } } });
-
Дочерний компонент использует данные, переданные от родительского компонента.
Использовать полученные данные как данные в своих собственных данных
<view>{{ aaa }}</view>
дочерний компонент передает значение родительскому компоненту
пройти через事件
передавать.
панель переключения вкладок, щелкните переключатель.
- Привязка событий щелчка должна быть привязана к методам
- Получить кликнутый индекс
- получить исходный массив
- цикл по массиву
- Для каждого элемента цикла выбранное свойство изменяется на false
- Добавляет активный выбранный эффект к элементу с текущим индексом
- Когда событие щелчка запускается, пользовательское событие в родительском компоненте запускается и одновременно передается родительскому компоненту.
- this.triggerEvent("Имя пользовательского события родительского компонента", передаваемый параметр)
На странице вкладок:
<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
})
}
другие свойства
Раздел определения | Типы | описывать | |
---|---|---|---|
properties | Object Map | Внешним свойством компонента является имя свойства и таблица сопоставления настроек свойств. | |
data | Object | Обычно используется для родительских компонентов для передачи значений дочерним компонентам и для дочерних компонентов для получения значений от родительских компонентов. | |
observers | Object | Мониторинг данных изменения свойств и данных | |
methods | Object | компонентный метод | |
created | Function | Функция жизненного цикла компонента (выполняется, когда экземпляр компонента только что создан) не может вызывать setData в это время. | |
attached | Function | Выполняется, когда экземпляр компонента входит в дерево узлов страницы | |
ready | Function | Выполняется, когда компоновка компонента завершена | |
moved | Function | мобильное исполнение | |
detached | Function | снять казнь | |
проект
- титульная страница
- Список продуктов
- корзина
- Страница авторизации
- поиск продукта
- Товарная коллекция
- Категории
- информация о продукте
- поселок
- Список заказов
- персональный центр
- Обратная связь
Сторонние фреймворки для небольших программ
- Wepy от Tencent похож на vue
- Meituan mpvue похож на vue
- Jingdong таро похож на реагировать
- Диди хамелеон
- uni-приложение похоже на vue
- Родной фреймворк MINA
Используйте библиотеку значков шрифтов Ali
-
На официальном сайте Ali Icon добавьте значок, который будет использоваться, в корзину.
-
Добавляем иконку в проект
-
Небольшая программа pyg ---> Класс шрифта (с использованием значков через классы) ---> Посмотреть онлайн-ссылку
-
В папке стилей вашего проекта создайте
iconfont.wxss
документ -
Откройте ссылку, скопируйте содержимое ссылки в
iconfont.wxss
в файле -
Используйте шрифты из библиотеки значков шрифтов
-
В глобальном файле wxss импортируйте файл wxss
@import "./styles/iconfont.wxss"
-
использовать
<text class="iconfont icon-shoucang"></text>
-
tabBar
Настроить в app.json
tbaBar: {
"color": "", //未选中的字体的颜色
"selectedColor": "", //选中后的字体的颜色
"backgroundColor": "", // 背景色
"position": "", //定位
"borderStyle": "", //边框样式
"list": [
{
"pagePath": "", // 页面的路径
"text": "", // 标题的名称
"iconPath": "", // 未选中的图标路径
"selectedIconPath": "" // 选中后的图标的路径
}
]
}
Инициализация стилей страницы
Примечание. Подстановочные знаки (*) не поддерживаются в апплетах.
существует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);
}
голова
Установить цвет темы:
"window": {
"backgroundTextStyle": "light", // 字体颜色
"navigatorBarBackgroundColor": "#2b4500", // 背景色
"navigatorBarText": "唯品会", // 字体提示
"navigatorBarTextStyle": "white", // 字体样式
}
Использование данных интерфейса
Page({
data: {
swiperList: []
},
// 页面加载事件
onLoad: function() {
/*
1. 发送异步请求 获取使用的数据
*/
wx.request({
url: '', // 接口地址
success: (result) => {
// 请求成功 给swiperList数组赋值
this.setData({
swiperList: result.data.message
})
}
});
/*
wx.request异步请求太多了就会产生 回调地狱 的问题
解决方法: es6中的promise
*/
}
})
Ошибка запроса (два решения):
- в апплете
详情
проверка интерфейса不校验合法域名,web-view(业务域名),TLS版本以及HTTPS证书
- интерфейс запроса конфигурации см.8.7 Добавьте доменное имя, запрошенное апплетом, в фоновом режиме
Решить проблему ада обратных вызовов (обещания es6)
Создается в папке запроса проекта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
})
});
}
})
Добавить доменное имя, запрошенное апплетом, в фоновом режиме
- Войти
微信公众平台
- развивать
- Настройки разработки
- доменное имя сервера
- Добавить легальное доменное имя запроса
Получить локально сохраненные данные
Разница между локальным хранилищем в сети и локальным хранилищем в апплете:
- Способ написания кода отличается
- В сети:
- Метод хранения: localStorage.setItem("ключ", "значение");
- Как его получить: localStorage.getItem("key");
- В апплете:
- Способ хранения: wx.setStorageSync("ключ", "значение");
- Метод получения: wx.getStorageSync("ключ", "значение");
- В сети:
- Есть ли преобразование типов при сохранении?
- web: независимо от того, какой тип данных хранится, в конечном итоге он будет преобразован в данные строкового типа с помощью метода toString().
- апплет: преобразование типов данных, которых не существует
// 接口返回的数据
Cates: [],
onLoad: function(options) {
// 获取本地存储中有没有旧数据
const Cates = wx.getStorageSync("cate");
// 判断本地是否存在
if(!Case) {
// 不存在 发送请求数据
this.setCates();
}else {
// 有旧的数据
// 定义数据过期的时间
if(Date.now() - Cates.time > 1000 * 10) {
// 重新发送请求
this.getCates();
} else {
this.Cates = Cates.data;
// 渲染数据
}
}
}
// 获取请求的数据
getCates() {
// 把接口的数据存储到本地存储中
wx.setStorageSync("cates", {time:Date.now(),data: this.Cates});
}
определить общедоступный 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);
}
});
});
}
Апплет поддерживает асинхронный синтаксис es7.
-
Проверьте в инструментах разработчика WeChat
es6转es5语法
-
Скачиваем runtime.js в библиотеке регенератора на github
-
Создайте новую папку /lib/runtime/runtime.js в файле каталога апплета и скопируйте в нее код.
-
В каждом js-файле страницы, который должен использовать асинхронный синтаксис, импортируйте файл
import regeneratorRuntime from '../lib/runtime/runtime';
Используйте асинхронный синтаксис:
async getCates() { // 1 使用es7的async await来发送请求 const res=await request({url:"/categories"}); }
параметр 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的值
}
Комплект переключателей TAB
В упакованном компоненте Tab:
properties: {
tabs: Array,
value: []
}
<style>
.tabs-title {
display: flex;
padding: 15rpx 0;
}
.title-item {
display: flex;
justify-content: center;
align-item: center;
flex: 1;
}
.active {
color: red;
border-bottom: 1rpx solid red;
}
</style>
<view class="tabs">
<view class="tabs-title">
<view wx:for="{{ tabs }}" wx:key="id"
class="title-item {{item.isActive?'active':''}}"
bindtap="handleItemTap" data-index="{{ index }}"
>
{{ item.value }}
</view>
</view>
// 切换内容
<view class="tabs-content">
<slot></slot>
</view>
</view>
methods: {
// 点击事件
handleItemTap(e) {
// 获取点击的索引
const {index} = e.currentTarget.dataset;
// 触发父组件中的事件
this.triggerEvent("tabsItemChange", {index});
}
}
Используйте инкапсулированный компонент Tab:
//bindtabsItemChange 监听自定义事件
<Tab tabs="{{ tabs }}" bindtabsItemChange="handelTabsItemChange">
<block wx:if="{{tabs[0].isActive}}">1</block>
<block wx:if="{{tabs[1].isActive}}">2</block>
<block wx:if="{{tabs[2].isActive}}">3</block>
</Tab>
// 标题的点击事件
bindtabsItemChange(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
});
}
Событие нижней полосы прокрутки (событие прокрутки страницы)
Полоса прокрутки опускается, загружая следующую страницу данных
Общее количество страниц = 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();
}
wx.showModel изменяет это, чтобы указать на проблему
wx.showModel({
title: '提示',
content: '您是否要删除?',
success :(res) => {
...
}
})
удалить в 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);
}
}
Получить данные из кеша
wx.getStorageSync("address");
WeChat Pay
- Корпоративный аккаунт
- Разработчики должны добавить белые списки в небольшую программу корпоративного аккаунта.
- Один AppID может быть привязан к нескольким разработчикам
- После привязки разработчик имеет разрешение разработчика.
- кнопка оплаты
- Сначала определите, есть ли токен в кеше
- Нет Перейти на страницу авторизации для получения значения токена пользователя
- Да Выполнять платежные операции
Процесс: создайте заказ, подготовьтесь к предоплате, инициируйте платеж WeChat и запросите заказ.
Один, получить жетон
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);
}
})
})
}
Во-вторых, подготовьтесь к предоплате (получите параметр оплаты)
3. Инициировать платеж WeChat (отправить параметры платежа)
В-четвертых, запросите заказ
В-пятых, удалите предметы, которые были выбраны для покупки в кеше
В-шестых, данные удаленной корзины будут кэшированы.
Семь, перейти на страницу
Загрузка изображения (wx.uploadFile)
При загрузке картинки, при сохранении загруженной картинки, нужно сначала сшить предыдущую картинку.
выбратьИзображение: [],
this.setData({
ChooseImage: [Загрузить предыдущую группу изображений, Группа загруженных изображений]
ChooseImage: [...this.data.chooseImage, ...chooseImage]
})
API для загрузки файлов не поддерживает загрузку нескольких файлов одновременно.
Решение: пройтись по массиву и загрузить по одному
wx.uploadFile({
url: '', // 图片要上传到哪里
filePath: '', // 被上传文件的路径
name: '', // 上传的文件的名称 后台通过定义的上传的名称来获取名称
formData: {}, // 顺带的文本信息
})
Релиз проекта
**Примечание. Не забудьте закрыть интерфейс сведений перед публикацией.Не проверяйте законные доменные имена **
Размер каждого загружаемого файла не должен превышать 2М, а общий размер не должен превышать 10М.
Загрузить:
- номер версии
- Первый номер (большое обновление версии)
- Второй номер (важное обновление функции)
- Третий номер (минимум фич, мелкие баги, небольшие патчи)
- меньше файлов не будет упаковано и загружено
- После успешной загрузки апплет по-прежнему остается экспериментальной версией апплета. Если вам нужно превратить экспериментальную версию апплета в онлайн-версию, вы можетеПубличная платформа микроканалаМини-программа книги опыта, которую необходимо представить,Добавить отзыв(Время рассмотрения около часа).
плагин апплета
- помощник по разработке апплетов
- Установите плагин easy less
Настройте в vscode (ctrl + shift + p, затем введите настройки, затем добавьте следующую конфигурацию):
"less.compile": {
"outExit": ".wxss"
}