Шок! Маленькие программы могут быть такими простыми!

Апплет WeChat

Рука об руку для реализации апплета WeChat для электронной коммерции (часть 1)

предисловие

Основанная на собственной структуре апплета WeChat, небольшая программная версия электронной коммерции, реализованная с помощью широко используемых собственных компонентов и официальных API-интерфейсов, поможет вам шаг за шагом перейти от 0 к 1, чтобы по-настоящему реализовать апплет WeChat.Исходный код: https://github.com/panzekun/wx_procedure

1. Создайте небольшой программный проект

Откройте инструмент разработчика WeChat, нажмите «Новый проект», выберите апплет, AppId использует тестовый идентификатор при разработке и должен быть зарегистрирован при публикации и производстве.

2, проект инициализации

3. Реализовать заголовок и нижнюю навигацию TabBar

app.json

{
  "pages": [
    "pages/home/index",
    "pages/category/index",
    "pages/cart/index",
    "pages/user/index",
    "pages/search/index"
  ],
  "window": {
    "navigationBarTitleText": "从0到1实战微信小程序",
    "navigationBarBackgroundColor": "#eb4450",
    "navigationBarTextStyle": "black",
    "backgroundColorTop": "#ffffff",
    "backgroundColorBottom": "#ffffff",
    "backgroundColor": "#ffffff"
  },
  "tabBar": {
    "color": "#333333",
    "selectedColor": "#f06c7a",
    "borderStyle": "black",
    "backgroundColor": "#ffffff",
    "list": [{
        "pagePath": "pages/home/index",
        "iconPath": "static/tabBar/home.png",
        "selectedIconPath": "static/tabBar/home-on.png",
        "text": "首页"
      },
      {
        "pagePath": "pages/category/index",
        "iconPath": "static/tabBar/category.png",
        "selectedIconPath": "static/tabBar/category-on.png",
        "text": "分类"
      },
      {
        "pagePath": "pages/cart/index",
        "iconPath": "static/tabBar/cart.png",
        "selectedIconPath": "static/tabBar/cart-on.png",
        "text": "购物车"
      },
      {
        "pagePath": "pages/user/index",
        "iconPath": "static/tabBar/user.png",
        "selectedIconPath": "static/tabBar/user-on.png",
        "text": "我的"
      }
    ]
  },
  "style": "v2",
  "sitemapLocation": "sitemap.json"
}

Удобное управление

Сохраните его в пути записи страницы и автоматически создайте соответствующую папку и соответствующий js json wxml wxss.

4. Создайте домашнюю страницу

Сначала эффект изображения

4.1 Анализ функций главной страницы

код

<!--pages/home/index.wxml-->
<page class="home">
  <!-- 搜索 -->
  <view class="shop-input">
    <search-input></search-input>
  </view>

  <!-- 轮播图 -->
  <view class="shop-swiper">
    <swiper class="" indicator-dots autoplay interval="5000">
      <block wx:for="{{swiperList}}" wx:key="{{item}}">
        <swiper-item class="" item-id="">
          <image class="" src="{{item.url}}" mode="widthFix" />
        </swiper-item>
      </block>
    </swiper>
  </view>
  <!-- 分类数据 -->
  <view class="category-list">
    <block wx:for="{{categoryList}}" wx:key="{{item.name}}">
      <view class="category" bindtap="hancleClickItem" data-itemList="{{item}}">
        <view class="img">
          <image src="{{item.image_src}}" mode="widthFix" />
        </view>
        <view>
          <view class="text">{{item.name}}</view>
        </view>
      </view>
    </block>
  </view>

  <!-- 广告图 -->
  <view class="banner">
    <MarqueeUp />
    <view class="img-box">
      <image src="https://ae01.alicdn.com/kf/H5470c644e6454719a610620f1e6f67d9y.jpg" />
    </view>
  </view>

  <!-- 楼层数据 -->
  <view class="goods-list">
    <view class="title">
      <image src="https://ae01.alicdn.com/kf/H551edcdd154a4936a5762971504fb3e2r.jpg"></image>
      猜你喜欢
      <image src="https://ae01.alicdn.com/kf/H551edcdd154a4936a5762971504fb3e2r.jpg"></image>
    </view>
    <view class="product-list">
      <block wx:for="{{productList}}" wx:key="{{item}}">
        <view class="product">
          <image src="{{item.img_url}}" />
          <view class="name ellipsis">{{ item.name }}</view>
          <view class="info">
            <view class="price">{{ item.price }}</view>
            <view class="slogan">{{ item.slogan }}</view>
          </view>
        </view>
      </block>
    </view>
  </view>
</page>

4.2. Внедрение пользовательских компонентов поиска

1. Инструменты разработчика WeChat для создания пользовательских компонентов

создание корневого каталогаcomponents/SearchInputдокумент,SearchInputЩелкните правой кнопкой мыши и выберите «Новый компонент», чтобы сгенерировать js json wxss wxml самостоятельно.

2. Реализация кода

SearchInput.wxml

<view class="search_row">
  <navigator class="search_input" target="" url="../search/index" hover-class="navigator-hover" open-type="navigate">
    搜索
  </navigator>
</view>

SearchInput.wxss

.search_row {
  height: 90rpx;
  padding: 15rpx;
  background-color: #eb4450;
}
.search_row .search_input {
  border-radius: 10rpx;
  background-color: #fff;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

Внедрение пользовательских компонентов

первый на страницеjsonСправочная выписка делается в файле. Также укажите соответствующее имя компонента и путь к компоненту.

{
  "usingComponents": {
    "search-input":"/components/SearchInput/SearchInput"
  }
}
  • Объявление ссылки usingComponents
  • имя компонента поискового ввода (SearchInput)
  • Путь компонента "/components/SearchInput/SearchInput"

используется на странице

<!--pages/home/index.wxml-->
<page class="home">
  <!-- 搜索 -->
  <view class="shop-input">
    <search-input></search-input>
  </view>
</page>

navigator

Компоненты навигации, похожие на метки гиперссылок

Имя свойства Типы По умолчанию иллюстрировать
target String self На какую цель происходит переход, текущий апплет по умолчанию, необязательное значение self (текущий апплет)/miniProgram (другой апплет)
url String Перейти по ссылкам в текущем апплете
open-type String navigate Метод прыжка

Допустимые значения для открытого типа:

стоимость иллюстрировать
navigate Сохранить текущую страницу и перейти на страницу в приложении, но не может перейти на страницу панели вкладок
redirect Закройте текущую страницу и перейдите на страницу в приложении, но переход на страницу панели вкладок невозможен.
switchTab Перейдите на страницу панели вкладок и закройте все остальные страницы без панели вкладок.
reLaunch Закрыть все страницы, открыть страницу в приложении
navigateBack Закрыть текущую страницу и вернуться на предыдущую страницу или многоуровневую страницу. доступныйgetCurrentPagesПолучите текущий стек страниц и решите, сколько слоев нужно вернуть
exit Выйдите из мини-программы, она вступит в силу, когда target="miniProgram"

4.3. Внедрить карусель (swiper)

Используйте встроенный WeChatswiperРеализация компонента

swiper

  • Слайдер просмотра контейнера,
  • Ширина по умолчанию 100%, высота 150 пикселей;

Общие свойства

Имя свойства Типы По умолчанию иллюстрировать
indicator-dots Boolean false Отображать ли точки индикатора панели
indicator-color Color rgba(0, 0, 0, .3) Цвет точки индикации
indicator-active-color Color #000000 Цвет текущей выбранной точки индикатора
autoplay Boolean false Переключаться ли автоматически
interval Number 5000 Интервал времени автоматического переключения
circular Boolean false Вращается ли s в цикле

swiper-item

  • можно разместить только вswiperВ компоненте ширина и высота автоматически устанавливаются на 100%.

image

Встроенный компонент изображения WeChat, ширина по умолчанию 320 пикселей, высота 240 пикселей, поддержка отложенной загрузки

Общие свойства:

Имя свойства Типы По умолчанию иллюстрировать
src String Адрес ресурса изображения
mode String 'scaleToFill' Обрезка изображения и режим масштабирования
lazy-load Boolean false Ленивая загрузка изображения

допустимые значения для режима

Всего 13 режимов, 9 режимов обрезки, 4 режима масштабирования, часто используемые.widthFix

стоимость иллюстрировать
scaleToFill Режим масштабирования, который масштабирует изображение без сохранения соотношения сторон, так что ширина и высота изображения полностью растягиваются, чтобы заполнить элемент изображения.
aspectFit Режим масштабирования, в котором сохраняется соотношение сторон и масштабируется изображение таким образом, что длинная сторона изображения отображается полностью. То есть картинка может отображаться полностью.
aspectFill Режим масштабирования, который поддерживает соотношение сторон и масштабирует изображение, гарантируя, что короткая сторона изображения может быть полностью отображена. То есть картинка обычно полная только в горизонтальном или вертикальном направлении, в другом направлении будет кадрирование.
widthFix В режиме масштабирования ширина остается неизменной, высота изменяется автоматически, а соотношение сторон исходного изображения остается неизменным
heightFix Режим масштабирования, высота не меняется, ширина меняется автоматически, а соотношение сторон исходного изображения остается неизменным
top Режим обрезки, не масштабировать изображение, показывать только верхнюю часть изображения.
bottom Режим обрезки, не масштабировать изображение, показывать только нижнюю часть изображения
center Режим обрезки, не масштабировать изображение, показывать только среднюю часть изображения.
left Режим обрезки, не масштабировать картинку, отображать только левую часть картинки
right Режим обрезки, не масштабировать изображение, отображать только правую часть изображения
top left Режим обрезки, не масштабировать изображение, отображать только верхнюю левую часть изображения.
top right Режим обрезки, не масштабировать изображение, отображать только верхнюю правую часть изображения.
bottom left Режим кадрирования, не масштабировать изображение, отображать только нижнюю левую часть изображения.
bottom right Режим обрезки, не масштабировать изображение, отображать только нижнюю правую часть изображения

Код

  <!-- 轮播图 -->
  <view class="shop-swiper">
    <swiper class="" indicator-dots autoplay interval="5000">
      <block wx:for="{{swiperList}}" wx:key="{{item}}">
        <swiper-item class="" item-id="">
          <image  src="{{item.url}}" mode="widthFix" />
        </swiper-item>
      </block>
    </swiper>
  </view>

4.4. Реализовать классификацию/рекламную карту/реализовать пол

Внедрение кода вручную, вставьте код напрямую, в основном об использовании запроса на получение данных на нижнем этаже.

<!--pages/home/index.wxml-->
<page class="home">
  <!-- 搜索 -->
  <view class="shop-input">
    <search-input></search-input>
  </view>

  <!-- 轮播图 -->
  <view class="shop-swiper">
    <swiper class="" indicator-dots autoplay interval="5000">
      <block wx:for="{{swiperList}}" wx:key="{{item}}">
        <swiper-item  item-id="">
          <image class="" src="{{item.url}}" mode="widthFix" />
        </swiper-item>
      </block>
    </swiper>
  </view>
  <!-- 分类数据 -->
  <view class="category-list">
    <block wx:for="{{categoryList}}" wx:key="{{item.name}}">
      <view class="category" bindtap="hancleClickItem" data-itemList="{{item}}">
        <view class="img">
          <image src="{{item.image_src}}" mode="widthFix" />
        </view>
        <view>
          <view class="text">{{item.name}}</view>
        </view>
      </view>
    </block>
  </view>

  <!-- 广告图 -->
  <view class="banner">
    <MarqueeUp />
    <view class="img-box">
      <image src="https://ae01.alicdn.com/kf/H5470c644e6454719a610620f1e6f67d9y.jpg" />
    </view>
  </view>

  <!-- 楼层数据 -->
  <view class="goods-list">
    <view class="title">
      <image src="https://ae01.alicdn.com/kf/H551edcdd154a4936a5762971504fb3e2r.jpg"></image>
      猜你喜欢
      <image src="https://ae01.alicdn.com/kf/H551edcdd154a4936a5762971504fb3e2r.jpg"></image>
    </view>
    <view class="product-list">
      <block wx:for="{{productList}}" wx:key="{{item}}">
        <view class="product">
          <image src="{{item.img_url}}" />
          <view class="name ellipsis">{{ item.name }}</view>
          <view class="info">
            <view class="price">{{ item.price }}</view>
            <view class="slogan">{{ item.slogan }}</view>
          </view>
        </view>
      </block>
    </view>
  </view>
</page>
/* pages/home/index.wxss */
swiper {
  height: 260rpx;
}

/* 分类 */
.category-list {
  width: 92%;
  margin: 0 4%;
  padding: 0 0 30rpx 0;
  border-bottom: solid 2rpx #f6f6f6;
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;

}

.category-list .category {
  width: 25%;
  margin-top: 50rpx;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.category-list .category .img {
  width: 100%;
  display: flex;
  justify-content: center;
}

.category-list .category .img image {
  width: 9vw;
  height: 9vw;
}


.category-list .category .text {
  margin-top: 16rpx;
  width: 100%;
  display: flex;
  justify-content: center;
  font-size: 24rpx;
  color: #3c3c3c;
}

/* 广告图 */
.banner {
  width: 92%;
  margin: 40rpx 4%;
}

.banner .img-box {
  position: relative;
  width: 100%;
  height: 150rpx;
  margin-top: 20rpx;
  border-radius: 80rpx;
}

.banner .img-box::before {
  content: "";
  position: absolute;
  width: calc(100% + 6%);
  height: 180rpx;
  border-radius: 100rpx;
  top: -15rpx;
  left: -3%;
  z-index: -1;
  background-image: linear-gradient(60deg, red, cornflowerblue, yellow, hotpink, salmon, lightgreen, sandybrown, violet);
  background-size: 300%;
  animation: animate_bg 5s infinite;
}

@keyframes animate_bg {

  0%,
  100% {
    background-position: 0%, 50%;
  }

  50% {
    background-position: 100%, 50%;
  }
}

.banner image {
  width: 100%;
  height: 20vw;
  border-radius: 10vw;
  box-shadow: 0rpx 5rpx 25rpx rgba(0, 0, 0, 0.3);
}

/* 楼层 */
.goods-list{
  width: 100%;
}
.goods-list .title {
  width: 100%;
  margin-top: 10rpx;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 80rpx;
  color: #f47825;
  font-size: 30rpx;
}

.goods-list .title image {
  width: 30rpx;
  height: 30rpx;
}

.goods-list .product-list {
  width: 100%;
  padding: 0 4% 3vw 4%;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;

}

.product {
  width: 48%;
  border-radius: 20rpx;
  background-color: #fff;
  margin: 0 0 15rpx 0;
  box-shadow: 0rpx 5rpx 25rpx rgba(0, 0, 0, 0.1);

}

.product image {
  width: 100%;
  height: 332rpx;
  border-radius: 20rpx 20rpx 0 0;
}

.product .name {
  width: 92%;
  padding: 10rpx 4%;
  font-size: 30rpx;
}

.product .info {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  width: 92%;
  padding: 10rpx 4% 10rpx 4%;
}

.product .info .price {
  color: #e65339;
  font-size: 30rpx;
  font-weight: 600;
}

.product .info .slogan {
  color: #807c87;
  font-size: 24rpx;
}

wx.request для получения внутренних данных

Инициируйте сетевой запрос HTTPS, подробности см. в документации WeChat.

запрос + обещание инкапсуляции
class request {
  constructor() {
    this._baseUrl = 'https://www.fastmock.site/mock/31875da47f27128e357e3d3e6ac0cc37/api/';
    this._token = wx.getStorageSync('token');
    // this._header = {'Authorization': 'Bearer ' + token}
  }

  /**
   * GET类型的网络请求
   */
  getRequest(url, data, header = this._header) {
    return this.requestAll(url, data, header, 'GET')
  }

  /**
   * DELETE类型的网络请求
   */
  deleteRequest(url, data, header = this._header) {
    return this.requestAll(url, data, header, 'DELETE')
  }

  /**
   * PUT类型的网络请求
   */
  putRequest(url, data, header = this._header) {
    return this.requestAll(url, data, header, 'PUT')
  }

  /**
   * POST类型的网络请求
   */
  postRequest(url, data, header = this._header) {
    return this.requestAll(url, data, header, 'POST')
  }

  /**
   * 网络请求
   */
  requestAll(url, data, header, method) {
    return new Promise((resolve, reject) => {
      // 显示正在等待
      wx.showLoading({
        title: "正在加载中",
        mask: false
      });
      wx.request({
        url: this._baseUrl + url,
        data: data,
        header: header,
        method: method,
        success: (res => {
          let {
            data
          } = res;
          // console.log(res);
          if (data.success && data.code == 200) {
            //200: 服务端业务处理正常结束
            resolve(data.data)
          } else {
            //其它错误,提示用户错误信息
            reject(data.data)
          }
        }),
        fail: (res => {
          reject(res)
        }),
        complete: () => {
          // 隐藏正在等待图标
          wx.hideLoading();
        }
      })
    })
  }
}

export default request
Страница использует запрос
import request from '../../utils/request';  //引入
const api = new request(); //创建实例
инструкции
  • Получить запрос ------------------ api.getRequest(接口路径,入参(对象))
  • Почтовый запрос ---------------- api.postRequest( 'home/getProductList',this.QueryParams )
  • .....

Уведомление:Необходимо проверить во время разработки不校验合法域名、web-view业务域名Подождите, официальная конфигурация соответствующего доменного имени для апплета входа в производственную линию, иначе запрос не может быть инициирован.

4.5 Динамический сбор данных пола


import request from '../../utils/request';
const api = new request();
Page({

  /**
   * 页面的初始数据
   */
  data: {
    swiperList: [{
        id: 1,
        url: 'https://ae01.alicdn.com/kf/H9450011bbd2e480882aa986c8ceaa312i.jpg'
      },
      {
        id: 2,
        url: 'https://ae01.alicdn.com/kf/H1eeb66ae770b44ad9147c1123fb63a32P.jpg'
      },
      {
        id: 3,
        url: 'https://ae01.alicdn.com/kf/H0fdf0f299c2a49d5995582f085d24522G.jpg'
      },
    ],
    // 分类菜单
    categoryList: [{
        id: 1,
        "name": "办公",
        image_src: 'https://ae01.alicdn.com/kf/H974e4de8124b4783b7768d06a2b847ab0.jpg'
      },
      {
        id: 2,
        "name": "家电",
        image_src: 'https://ae01.alicdn.com/kf/H53dede49e8bd4037b702eeb1f83f1b55M.jpg'
      },
      {
        id: 3,
        "name": "服饰",
        image_src: 'https://ae01.alicdn.com/kf/H575960420d6b4990960160fba79f443bw.jpg'
      },
      {
        id: 4,
        "name": "日用",
        image_src: 'https://ae01.alicdn.com/kf/H30b911d8668d46deb9cfed0fd68da1fex.jpg'
      },
      {
        id: 5,
        "name": "蔬果",
        image_src: 'https://ae01.alicdn.com/kf/Hd3edad8b6c834a23aa214fa83ecca4ddm.jpg'
      },
      {
        id: 6,
        "name": "运动",
        image_src: 'https://ae01.alicdn.com/kf/Hdb7bb002f13c4b79bc876c28555ca7ceV.jpg'
      },
      {
        id: 7,
        "name": "书籍",
        image_src: 'https://ae01.alicdn.com/kf/Hc1a477b73bc147728ef29ab6c74af0f0O.jpg'
      },
      {
        id: 8,
        "name": "文具",
        image_src: 'https://ae01.alicdn.com/kf/H23940f3a1f3145418b439c32521e263b4.jpg'
      }
    ],
    //猜你喜欢列表
    productList: [],
  },
  // 定义接口参数对象 
  QueryParams: {
    // 页码
    pagenum: 1,
    // 页容量
    pagesize: 10
  },
  // 总页码
  totalPage: 1,

  // 获取商品列表
  getProductList() {
    // 使用微信小程序内置发送请求的代码来获取数据
    api.postRequest(
      'home/getProductList',
      this.QueryParams
    ).then(res => {
      console.log(res);
      // 执行加载下一页的时候 productList 应该是 叠加 
      // 拼接数组 
      let productList = [...this.data.productList, ...res.productList];
      this.setData({
        productList
      });

      // 计算总页码
      this.totalPage = Math.ceil(res.total / this.QueryParams.pagesize);
    })
  },
  // 点击分类事件
  hancleClickItem(e) {
    let data = e.currentTarget.dataset.itemlist;
    wx.showToast({
      title: '点击了' + data.name,
      icon: 'none'
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

    this.getProductList()
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
    // wx.showNavigationBarLoading() //在标题栏中显示加载
    this.QueryParams.pagenum = 1;
    this.setData({
      productList: []
    });
    this.getProductList();
    //  结束下拉刷新组件的显示
    wx.stopPullDownRefresh();
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
    // 判断有没有下一页数据
    if (this.QueryParams.pagenum >= this.totalPage) {
      // 没有数据
      wx.showToast({
        title: '没有更多数据了',
        icon: 'none',
        duration: 1500,
        // 蒙版  遮罩层 
        mask: false
      });

    } else {
      this.QueryParams.pagenum++;
      this.getProductList();
    }
  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

4.6 Реализуйте выпадающее обновление и загрузите больше

Включите раскрывающееся обновление на главной странице

(1) В Index.json вытяните новое обновление, вам нужно установить backgroundColor или BackgroundTextStyle, потому что загруженная анимация может быть белым фоном, это будет ясно.

{
  "enablePullDownRefresh": true,
  "onReachBottomDistance": 50,
  "usingComponents": {
    "search-input":"/components/SearchInput/SearchInput"
  }
}

(2), вonPullDownRefreshФункция прослушивает событие раскрывающегося списка и выполняет метод обновления.

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
    // wx.showNavigationBarLoading() //在标题栏中显示加载
    this.QueryParams.pagenum = 1;
    this.setData({
      productList: []
    });
    this.getProductList();
    //  结束下拉刷新组件的显示
    wx.stopPullDownRefresh();
  },

Включите подтягивание, чтобы загрузить больше

прямой мониторингonReachBottomсобытие, чтобы загрузить больше

/**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
    // 判断有没有下一页数据
    if (this.QueryParams.pagenum >= this.totalPage) {
      // 没有数据
      wx.showToast({
        title: '没有更多数据了',
        icon: 'none',
        duration: 1500,
        // 蒙版  遮罩层 
        mask: false
      });

    } else {
      this.QueryParams.pagenum++;
      this.getProductList();
    }
  },

На сегодня это все, а следующая статья будет по-прежнему включать классификацию продуктов и подробные сведения о них. Спасибо за ваше прочтение и поддержку. Пожалуйста, оставьте сообщение ниже, чтобы учиться и совершенствоваться вместе!

💕 После прочтения трех вещей:

  • Нравится | Вы можете нажать --> Избранное --> Выйти за один раз, но не забудьте поставить лайк 🤭
  • Подписывайтесь | Нажмите, чтобы подписаться, не теряйтесь в следующий раз😘
самый простой! Боевая малая программа (средняя)