предисловие
С момента выпуска мини-программы она становится все более и более популярной благодаря своим многочисленным преимуществам, таким как отсутствие установки, уход после использования, легкий доступ, отсутствие регистрации, входа в систему и социального деления. мобильного приложения Стоимость разработки также соответствует привычке пользователя использовать приложение. Мини-программы так привлекательны, как программист, почему бы мне не сделать их самому? Без лишних слов, давайте засучим рукава и просто сделаем это.
Готов к работе
- Инструменты фронтенд-разработки:VSCode
- отладка:Инструменты разработчика WeChat
- Некоторые данные собственного Mock
- Документация по разработке WeChat
Введение в проект: реальный бой в торговом центре Xiaomi
Структура каталогов проекта
├── assets 用到的一些图标文件
├── lib
├── weui.wxss 引用了weui
├── modules
├── showDetail.js 跳转展示商品详情的公共js文件
├── showcDetail.js
├── pages 项目的各个页面
├── index 商城首页
├── categories 商品分类页
├── discovery 发现页
├── channel 商品频道目录
├── phone 手机频道
├── tv 电视频道
├── computer 电脑频道
├── cart 购物车
├── mine 个人信息页
├── goods 商品详情页
├── selectGoods 商品属性选择页
├── search 商品搜索页
├── addr 收货地址页
├── template 使用到的模版文件
├── slide 轮播图模版
├── goods_list 商品展示模版
├── cover 商品展示模版
├── util 使用到的工具类
├── mock.js 项目中使用到的一些数据
├── app.js 项目逻辑
├── app.wxss 项目公共样式表
└── app.json 项目公共设置
Отображение и реализация функций
1. Домашняя страница торгового центра
Анализ структуры страницы:
-
верхняя панель поиска Здесь это выглядит как окно поиска, но на самом деле то, чего он хочет добиться, — это просто функция перехода на страницу, если ее
disabledУстановить какtrueВот и все. Кроме того, если вы хотите, чтобы заполнитель-заполнитель отображался в центре, апплет WeChat предоставляетplaceholder-classсвойство, с помощью которого вы можете изменить стиль заполнителя. -
Карусельная зона Здесь апплет WeChat предоставляет нам компонент swiper, который можно использовать напрямую. Тем не менее, карусельное изображение может существовать на каждой странице, но изображения, отображаемые в нем, разные, поэтому используйте идею компонентизации и запишите его в виде шаблона, где бы вы ни захотели его использовать, вы можете импортировать этот шаблон.
<template name="slide">
<view class="section section-swiper">
<swiper class="slide" indicator-dots="{{true}}" autoplay="{{true}}" interval="2000" duration="1000">
<block wx:for="{{slides}}" wx:key="{{index}}">
<swiper-item>
<image src="{{item.slide_url}}" mode="widthFix" class="slide-image" data-id="{{item.id}}" />
</swiper-item>
</block>
</swiper>
</view>
</template>
При использовании импортируйте так
<import src="../../../templates/slide/slide.wxml" />
<view class="container">
<template is="slide" data="{{slides}}"></template>
</view>
- Зона навигации торгового центра, зона активности Это просто макет, поэтому я не буду вдаваться в подробности. Но следует отметить, что в апплете WeChat настоятельно рекомендуется использоватьГибкая компоновка
- Главная Зона отображения продуктов
Продукты здесь отображаются в блоках, которые очень регулярны, поэтому всю витрину продукта можно использовать напрямую.
wx:forТраверс. wxml:
<!-- 首页商品版块 -->
<view class="section block">
<block wx:for="{{index_block}}" wx:key="{{item.id}}">
<view class="section cover">
<image class="cover-img" src="{{item.img_url}}" data-cid="{{item.id}}" bindtap="showcDetail"/>
</view>
<view class="section goods-list">
<block wx:for="{{item.section}}" wx:key="index" wx:for-item="product">
<view class="goods-item">
<image class="goods-img {{product.is_new?'new':''}} {{product.on_sale?'on-sale':''}}" src="{{product.goods_cover}}" data-pid="{{product.id}}" mode="aspectFill" bindtap="showDetail"/>
<text class="title">{{product.header}}</text>
<text class="desp">{{product.description}}</text>
<text class="meta">{{product.meta}}</text>
<text class="discount">{{product.discount}}</text>
</view>
</block>
</view>
</block>
</view><!-- end-section block -->
Вот такая деталь: товары в каждом разделе будут разделены на три категории: «новинки», «моментальные скидки» (то есть со скидками) и «без скидок». Как это сделать? Здесь я использую хитрый метод: дать каждому продуктуclassпривязать логическое значениеis_newиon_saleИспользуйте тернарный оператор, чтобы определить, нужно ли прикреплять имя класса к продукту, а затем используйтепсевдоэлементПометьте этот товар как «Новинка» или «Мгновенная скидка» следующим образом:
wxml:
<image class="goods-img {{product.is_new?'new':''}} {{product.on_sale?'on-sale':''}}" src="{{product.goods_cover}}" data-pid="{{product.id}}" mode="aspectFill" bindtap="showDetail"/>
wxss
.goods-img.new:before{ /*新品标签样式*/
position: absolute;
left: 0;
top: 0;
width: 100rpx;
height: 40rpx;
line-height: 40rpx;
content: "新品";
color: #fff;
font-size: 9pt;
text-align: center;
background: #8CC64A;
}
.goods-img.on-sale:before{ /*立减标签样式*/
position: absolute;
left: 0;
top: 0;
width: 100rpx;
height: 40rpx;
line-height: 40rpx;
content: "立减";
font-size: 9pt;
color: #fff;
text-align: center;
background: #ec6055;
}
логический анализ:
Домашняя страница — это всего лишь некоторые товары, поэтому логический слой должен основываться только наidПросто перейдите на страницу сведений о соответствующем продукте. Очевидно, что этот метод необходимо использовать на нескольких страницах, поэтому используйте модульную идею для созданияmodulesпапку, напишите метод в отдельном файле js иисходящий
const showDetail=(e)=>{
const id=e.currentTarget.dataset.pid; //获取每个商品的id
wx.navigateTo({
url: `/pages/goods/show?id=${id}`
})
};
export default showDetail;
Где использовать, используйте импорт для импорта
import showDetail from "../../modules/showDetail";
2. Страница классификации продуктов
scroll-viewВот и все, ставим и влево и вправоscroll-yзаставить их прокручиваться вертикально, кроме того,scroll-viewесть еще одинscroll-into-viewсвойства позволяют нам добиться чего-то вродеaЯкорная функция тега,scroll-into-viewЗначением является идентификатор некоторого дочернего элемента, ноЗдесь есть небольшая дырочка,Идентификатор не может начинаться с цифры
Тоже так некрасиво выглядит. .
**Решение. Добавьте следующий стиль в глобальный стиль.
//隐藏滚动条
::-webkit-scrollbar{
height: 0;
width: 0;
color: transparent;
}
Мммм, красиво! !
Функция классификации продуктов
Логический анализ: зарегистрируйте curIndex (индекс текущего выбранного меню) для страницы.Если текущий индекс совпадает с выбранным индексом меню, он активен Часть кода: wxml:
<view class="main">
<scroll-view scroll-y class="category-left">
<view class="cate-nav-list" wx:for="{{cate_nav_list}}" wx:key="{{item.id}}" data-id="{{item.id}}" data-index="{{index}}"
bindtap="switchCategory">
<text class="cate-name {{curIndex===index?'on':''}}">{{item.name}}</text>
</view>
</scroll-view>
<scroll-view class="category-right" scroll-y="{{true}}" scroll-into-view="{{toView}}" scroll-with-animation="true">
<view class="cate-content">
<view class="cate-list-content" wx:for="{{detail}}" wx:key="{{item.id}}" id="{{item.id}}">
<view class="banner">
<image src="{{item.banner}}"/>
</view>
<view class="header">{{item.cate_name}}</view>
<view class="cate-list">
<view class="cate-item" wx:for="{{item.cate_list}}" wx:key="{{index}}" wx:for-item="cateList">
<image src="{{cateList.item_img}}" />
<text>{{cateList.item_name}}</text>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
js:
const app=getApp();
Page({
/**
* 页面的初始数据
*/
data: {
cate_nav_list:[
{name:"新品",id:"new"},
{name:"手机",id:"phone"},
{name:"电视",id:"tv"},
{name:"电脑",id:"laptop"},
{name:"家电",id:"appliance"},
{name:"路由",id:"router"},
{name:"智能",id:"smart"},
{name:"儿童",id:"kids"},
{name:"灯具",id:"lignts"},
{name:"电源",id:"adapter"},
{name:"耳机",id:"headset"},
{name:"音箱",id:"voicebox"},
{name:"生活",id:"life"},
{name:"服务",id:"service"},
{name:"米粉卡",id:"card"}
],
curIndex:0, //初始化当前下标为0
toView:"new", //默认显示“新品展示”
detail:[]
},
switchCategory(e){
const curIndex=e.currentTarget.dataset.index?e.currentTarget.dataset.index:0; //获取每个菜单的id
//更新数据
this.setData({
toView:e.currentTarget.dataset.id,
curIndex
});
},
onLoad: function (options) {
const detail=app.globalData.category; //获取分类展示数据
this.setData({
detail
});
}
})
3. Страница обнаружения
Анализ структуры страницы:
4. Страница сведений о продукте
Конечно, чтобы использовать weui, мы должны импортировать его файл стилей, мы импортируем его в app.wxss, и тогда его можно будет использовать глобально.
@import "./lib/weui.wxss";
Ну, официальный сайт weui и адрес на github естественно незаменимы.официальный сайт вуи,официальная документация weui github, чтение кода на github — очень эффективный способ обучения, но найти файл непросто, если папка слишком глубоко вложена, вотАртефакт чтения GitHub
Веуи использовал: Пожалуйста, позвольте мне вставить структуру, скопированную с weui
<view class="weui-cells">
<view class="weui-cell">
<view class="weui-cell__bd">
<view class="title">{{goods.header}}</view>
<view class="desp">{{goods.description}}</view>
<view class="meta">{{goods.meta}}</view>
</view>
</view>
</view>
Отображение страницы сведений о продукте
логический анализ: Каждый товар переходит на соответствующую страницу сведений через id, но где будет id?Потому что страница сведений открывается одна за другой, поэтому при загрузке страницы сведений о товаре можно получить текущее открытие в onLoad.Параметр запроса вызывается страницей (это часть данных json), потому что для перехода в showDetail используется только идентификатор, поэтому параметры имеют только атрибут id
onLoad: function (options) {
console.log(options); //{id:"4"}
const id=options.id; //获取options里的id
const goods=app.globalData.goodsDetail.filter(item=>{
return item.id==id; //通过id来筛选显示对应的商品
});
this.setData({
goods:goods[0] //因为id是唯一的,所以上面筛选出来的数组只有一条数据,这条数据就是要显示的商品数据
});
}
Реализация предварительного просмотра изображения продукта
Апплет WeChat предоставляет намwx.previewImage()метод реализации предварительного просмотра изображения, метод реализации выглядит следующим образом:
previewImage(e){
const index=e.currentTarget.dataset.index; //获取swiper里的图片的下标
const slide=this.data.goods.goods_slides; //获取商品轮播图
const imgList=[]; //定义一个数组来存放轮播图的url
slide.map(item=>{
imgList.push(item.slide_url); //用js的map方法把图片的url地址取出来放到数组里
});
wx.previewImage({
current: imgList[index], // 当前显示图片的链接,不填则默认为 urls 的第一张
urls: imgList
})
}
Пять, выбор атрибута продукта
bindsubmitС этим можно справиться, но с помощью bindsubmit в weui значение радио не получить.После долгого метания его все равно не получить, но можно получить заменой на родное радио! !radiogroupвнутреннийbindchangeЭто немного сложнее, но все же может решить проблему. .
Нечего сказать, посмотрите на код (я чувствую, что написал очень громоздкий код..)
selectVersion(e) {
const version = e.detail.value;
const memory = version.split(",")[0];
const price = version.split(",")[1];
wx.setStorageSync('memory', memory);
wx.setStorageSync('price', price);
this.setData({
memory,
price
});
},
selectColor(e) {
let color = e.detail.value;
let cover_img=this.data.goods_attrSelect[0].goods_slides[0].slide_url;
wx.setStorageSync('color', color);
wx.setStorageSync('cover', cover_img);
this.setData({
color,
cover_img
});
},
colorHasSelected(e) {
const curcIndex = e.currentTarget.dataset.index ? e.currentTarget.dataset.index : 0;
console.log(curcIndex);
this.setData({
curcIndex
});
},
versionHasSelected(e) {
const curvIndex = e.currentTarget.dataset.index ? e.currentTarget.dataset.index : 0;
console.log(curvIndex);
this.setData({
curvIndex
});
}
Перейти на страницу свойств соответствующего продукта
Логический анализ: на странице сведений о продукте перейдите по идентификатору текущего продукта.
toSelect(e){
const id=e.currentTarget.dataset.id;
wx.navigateTo({
url:`../selectGoods/selectGoods?id=${id}`
});
}
На странице выбора атрибутов продукта информация о выборе атрибутов различных продуктов также отображается с помощью фильтрации идентификаторов.
onLoad: function (options) {
const id = options.id;
console.log(id);
const goods_attrSelect = app.globalData.goodsDetail.filter(item => {
return item.id == id;
});
}
Связывание выбора атрибутов продукта
Поскольку это товар, как это можно сделать без выбора атрибута? Заинтересованы в том, чтобы писать, не говоря ни слова. Но здесь есть трудность: из-за разнообразия выбора пользователей, перечислите ли вы все варианты выбора, которые могут сделать пользователи? Боже, с таким количеством продуктов, неужели это меня утомит 😱? нет, нет, нет, этот метод не рекомендуется. Где еще есть решение? В то время я думал об использовании кеша данных.Ну, этот метод реализуем, но если вы используете кеш для доступа к выбранным пользователем значениям, здесь возникает большая проблема:Кэш данных в апплете WeChat хранит данные в ключе, указанном в локальном кеше, который перезапишет исходное содержимое, соответствующее ключу, будь то wx.setStorage (асинхронный интерфейс) или wx.setStorageSync (синхронный интерфейс)., в этом случае независимо от того, сколько элементов выберет пользователь, пока значение ключа одинаково, всегда будут только одни кэшированные данные! ! ! Мое сердце сейчас болит.
submit(e) {
const pre_item = wx.getStorageSync('attr_item');
const temp = {
'goods_name': wx.getStorageSync('goods_name'),
'memory': wx.getStorageSync('memory'),
'price': wx.getStorageSync('price'),
'color': wx.getStorageSync('color'),
'select_num': wx.getStorageSync('select_num'),
'cover': wx.getStorageSync('cover'),
'selected': false,
'isTouchMove': false
}
wx.setStorageSync('attr_item', [temp, ...pre_item]); //把获取到的pre_item和temp的数据缓存存入attr_item
wx.showToast({
title: '已加入购物车',
icon: 'success',
duration: 3000,
success() {
setTimeout(() => {
wx.navigateBack({
url: "../goods/show"
});
}, 1000)
}
});
}
Операции сложения и вычитания количества товара
Идея реализации: привязать событие для управления сложением и вычитанием количества товаров и, наконец, установить число, выбранное пользователем, в кэш данных. Код реализации:
data: {
select_num: 1 //默认选择为数量为1
},
minusCount(e) { //用户减操作
let select_num = this.data.select_num;
select_num--;
if (select_num < 1) {
return;
}
this.setData({
select_num
});
wx.setStorageSync('select_num', select_num);
},
addCount(e) { //用户加操作
let select_num = this.data.select_num;
select_num++;
if (select_num > 5) {
return;
}
this.setData({
select_num
});
wx.setStorageSync('select_num', select_num);
}
6. Работа с корзиной
<view wx:if="{{cart_list==''}}">
<view class="empty-cart">
<view class="cart-icon">
<image src="../../assets/icons/cart_empty.png" mode="aspectFill" />
</view>
<view class="prompt">购物车还是空的</view>
<button type="warn" class="btn-warn" style="background: #ff6700;" bindtap="goIndex">到小米商城逛逛</button>
</view>
</view>
<view wx:else>
<view class="cart-box">
<view class="cart-list" wx:for="{{cart_list}}" wx:key="{{index}}">
<view class="cart-item {{item.isTouchMove? 'touch-move-active': ''}}" bindtouchstart="touchstart" bindtouchmove="touchmove" data-index="{{index}}">
<view class="cart-content">
<icon type="{{item.selected?'success':'circle'}}" class="" color="#ff6700" size="20" bindtap="selectList" data-index="{{index}}"
/>
<image src="{{item.cover}}"
mode="aspectFill" />
<text class="item-title">{{item.goods_name}} {{item.memory}}</text>
<text class="item-num">{{item.color}}</text>
<text class="item-price">{{item.select_num}}×</text>
<text class="item-price">{{item.price}}</text>
<view class="del-cart-item" catchtap="delCartItem">删除</view>
</view>
</view>
</view>
</view>
<view class="user-operation">
<view class="select-all">
<icon wx:if="{{selectAllStatus}}" type="success" class="total-select" color="#ff6700" bindtap="selectAll" />
<icon wx:else type="circle" class="total-select" color="#ff6700" size="20" bindtap="selectAll" />
<text>全选</text>
</view>
<view class="total-price">合计:
<text>{{totalPrice}}元</text>
</view>
<view class="btn-primary pay" bindtap="checkOut">结算</view>
</view>
</view>
Стиль нижней панели действий
.user-operation{
width: 100%;
height: 100rpx;
line-height: 100rpx;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
position: fixed;
left: 0;
bottom: 0;
}
.select-all,.total-price,.btn-primary.pay{
flex: 1; //三个盒子等分所有设备宽度
font-size: 12pt;
text-align: center;
}
добавить в корзину действие
Логический анализ: предыдущее решение проблемы кэширования данных — проложить путь для функции добавления в корзину. При каскадном выборе атрибутов товара все данные для добавления в корзину пользователя получены, теперь данные можно извлечь и привязать к странице корзины.
Код реализации:
data: {
cart_list: [], //初始化一个空数组用来存放购物车列表
},
goIndex() { //如果购物车为空,则让用户去首页
wx.switchTab({
url: "../index/index"
})
},
onShow: function () {
const attr_item = wx.getStorageSync('attr_item'); //获取数据缓存里将要加入购物车的数据
let cart_list = this.data.cart_list;
cart_list = [...attr_item]; //把缓存里的数据加到购物车列表里
const select_num = cart_list.map(item => { //获取用户每次选择的数量
return item.select_num;
})
let goods_sum=select_num.reduce(function(prev,cur){
return prev+cur; //用es6的reduce()方法把用户每次选择的数量相加
});
wx.setStorageSync('goods_sum', goods_sum); //再次存入缓存
this.setData({ //更新购物车列表
cart_list
});
}
Корзина выбрать все, обратный выбор, вычислить функцию общей цены
Это очень классическая задача, все связано с работой корзины, и эта функция незаменима.
data: {
cart_list: [],
totalPrice: 0,
},
selectList(e) {
let selectAllStatus = this.data.selectAllStatus;
const index = e.currentTarget.dataset.index;
let cart_list = this.data.cart_list;
// console.log(cart_list[index].selected);
const selected = cart_list[index].selected;
cart_list[index].selected = !selected;
console.log(selected);
//购物车列表里的条目只要有一个取消,全选就取消
const symbol = cart_list.some(cart => { //这里用es6的some()函数
return cart.selected === false;
});
if (symbol) { //如果找到false,全选就取消
this.data.selectAllStatus = false;
} else {
this.data.selectAllStatus = true;
}
this.setData({ //更新数据
cart_list,
selectAllStatus: this.data.selectAllStatus
});
this.getTotalPrice();
},
getTotalPrice() { //定义一个计算总价的方法
let cart_list = this.data.cart_list;
let totalPrice = 0;
for (let i = 0; i < cart_list.length; i++) {
if (cart_list[i].selected) {
totalPrice += parseInt(cart_list[i].select_num) * parseInt(cart_list[i].price); //注意这里要用parseInt()把数量和价格取出来
}
}
//更新总价
this.setData({
totalPrice
});
},
selectAll(e) {
let selectAllStatus = this.data.selectAllStatus;
selectAllStatus = !selectAllStatus;
let cart_list = this.data.cart_list;
for (let i = 0; i < cart_list.length; i++) {
cart_list[i].selected = selectAllStatus; //全选为true,则所有购物车列表为true,全选为false,则所有购物车列表为false
}
//更新数据
this.setData({
cart_list,
selectAllStatus
});
this.getTotalPrice();
}
удалить действие корзины
data: {
startX: 0, //开始坐标
startY: 0,
},
//滑动事件处理
touchmove(e) {
let
index = e.currentTarget.dataset.index, //获取当前索引
startX = this.data.startX, //获取开始X坐标
startY = this.data.startY, //获取开始Y坐标
touchMoveX = e.changedTouches[0].clientX, //滑动变化坐标
touchMoveY = e.changedTouches[0].clientY, //滑动变化坐标
//获取滑动角度
angle = this.getAngle({
X: startX,
Y: startY
}, {
X: touchMoveX,
Y: touchMoveY
});
this.data.cart_list.forEach(function (v, i) {
v.isTouchMove = false
if (Math.abs(angle) > 30) return;//用户滑动超过30度,删除按钮就不出来
if (i == index) {
if (touchMoveX > startX) //右滑
v.isTouchMove = false
else //左滑
v.isTouchMove = true
}
})
//更新数据
this.setData({
cart_list: this.data.cart_list
})
},
getAngle(start, end) {
let X = end.X - start.X,
Y = end.Y - start.Y
//返回角度 /Math.atan()返回数字的反正切值
return 360 * Math.atan(Y / X) / (2 * Math.PI);
},
delCartItem(e) {
const index=e.currentTarget.dataset.index; //获取购物车要删除商品的下标
this.data.cart_list.splice(index, 1);
wx.clearStorageSync("select_num");
this.setData({
cart_list: this.data.cart_list
});
}
7. Сопоставление товаров и реализация функции поиска
<import src="../../templates/goods_list/goods_list.wxml" />
<view class="weui-search-bar">
<view class="weui-search-bar__form">
<view class="weui-search-bar__box">
<icon class="weui-icon-search_in-box" type="search" size="14"></icon>
<input type="text" class="weui-search-bar__input" placeholder="搜索" placeholder-class="plac" bindinput="searchInput" />
</view>
</view>
<view class="weui-search-bar__cancel-btn" bindtap="search">搜索</view>
</view>
<view class="search-list {{is_hidden?'hidden':''}}">
<block wx:for="{{search_list}}" wx:key="{{item.id}}">
<text class="search-item" bindtap="showItemDetail" data-header="{{item.header}}">{{item.header}}</text>
</block>
</view>
<template is="goods_list" data="{{goods_list}}"></template>
логический анализ: Моя идея реализации такова:
- Если продукт соответствует, окно поиска должно отображаться под окном поиска;
- Когда содержимое поиска, введенное пользователем, пусто, окно запроса поиска скрыто.
- Когда пользователь нажимает кнопку поиска, отображается список всех подходящих продуктов.нечеткий поиск,нечувствительный к регистру, чтобы улучшить пользовательский опыт;
- Когда пользователь нажимает на соответствующую запись продукта, продукт ищется
Выполнение:
-
filter()+indexOf()+toLowerCase();
код показывает, как показано ниже:
import showDetail from "../../modules/showDetail";
const app=getApp();
Page({
/**
* 页面的初始数据
*/
data: {
goods_list:[],
search_list:[],
is_hidden:true
},
searchInput(e){
let search_list=this.getList(e.detail.value); //获取用户的输入值
if(e.detail.value==""){ //如果用户没输入,搜索提示列表置空,并且让搜索提示框隐藏
search_list=[];
this.data.is_hidden=true;
}else{
this.data.is_hidden=false;
}
//更新数据
this.setData({
search_list,
is_hidden:this.data.is_hidden
});
},
search(e){
//按关键字筛选商品,如果关键字匹配到商品名称,则返回该商品列表
const keywords=wx.getStorageSync('keywords');
wx.showLoading({
title: '请稍等',
});
setTimeout(()=>{
this.setData({
goods_list:this.getList(keywords),
is_hidden:true //如果搜索到了商品,就让搜索框隐藏
});
wx.hideLoading();
},500);
},
showDetail,
showItemDetail(e){
//按关键字筛选商品,如果关键字匹配到商品名称,则返回该商品列表
const header=e.currentTarget.dataset.header.toLowerCase();
console.log(header);
wx.showLoading({
title: '请稍等',
})
setTimeout(()=>{
wx.hideLoading()
this.setData({
goods_list:this.getList(header),
is_hidden:true
});
},500)
},
/**
* attr:需要匹配筛选的数据
*/
getList(attr){ //定义一个获取商品标题的方法
return app.globalData.phone.goods_list.filter(item=>{
return item.header.toString().toLowerCase().indexOf(attr)>-1;
});
}
})
8. Страница адреса доставки
// pages/address/address.js
Page({
data: {
receiverName: "",
mobile: "",
addressDetail: "",
postCode: "",
isDisabled: false,
isComplete: false,
buttonTitle: "保存"
},
formSubmit(e) {
const addrInfo = e.detail.value;
let {receiverName,mobile,addressDetail,postCode}=addrInfo; //把data里的数据结构出来
if(receiverName==""||mobile==""||addressDetail==""||postCode==""){
this.data.isComplete=false;
wx.showModal({
title:"提示",
content:"请完善信息",
showCancel:false
});
}else if(!/^[1][3,4,5,7,8]\d{9}$/.test(mobile)){ //判断手机号格式
wx.showModal({
title:"提示",
content:"手机号格式不规范",
showCancel:false
});
}else if(!/^[0-9]{6}$/.test(postCode)){
wx.showModal({
title:"提示",
content:"邮政编码不规范",
showCancel:false
});
}else{
this.data.isComplete=true;
wx.setStorageSync('addrInfo', addrInfo);
}
this.setData({
isDisabled: true,
isComplete: this.data.isComplete
});
},
updateAddr(e){
this.setData({
isDisabled:false,
isComplete:false,
buttonTitle: "保存"
});
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let addrInfo=wx.getStorageSync("addrInfo");
console.log(addrInfo);
let {receiverName,mobile,addressDetail,postCode}=addrInfo;
this.setData({
receiverName,
mobile,
addressDetail,
postCode,
isDisabled: true,
isComplete:true,
buttonTitle: "修改"
});
}
})
Суммировать:
Когда я работал над этим проектом, я столкнулся с множеством проблем, и я долго застрял из-за проблемы в середине, но теперь я думаю об этом, я определенно могу чему-то научиться, пройдя через это. не смейте думать о некоторых вещах раньше, но это не имеет значения, если вы хотите это сделать, тогда сделайте это, зайдите в Интернет, чтобы проверить информацию, зайдите в сообщество и спросите у больших коров , всегда можно чему-то научиться. Для этого проекта многие функции не доведены до совершенства, такие как обзоры товаров, генерация заказов и т.д., но я буду обновлять время от времени😊, если будет время, то перепишу на mpvue или wepy, и изучу новые технологии 😄
Наконец:
Кодить непросто, если вам это нравится, простоstarНу давай же,адрес проекта, буду обновлять время от времени. В проекте еще много недочетов, надеюсь каждый сможет внести ценные предложения 🐵