Introduction to the history of applets

What is wechat applets?

Wechat small program, short for small program. English name mini Program, is a kind of application that can be used directly without downloading and installing. He realized his dream within reach. Users can open the app directly by scanning or searching.

Why wechat small program

  1. Wechat has a huge number of users
  2. The cost of promoting app or public account is too high
  3. Development adaptation cost is low
  4. Easy to small trial and error, then quickly iterate
  5. cross-platform

history

  1. January 11, 2016, Zhang Xiaolong, wechat internal research new form,The application no., later renamedSmall program.
  2. On August 12, 2016, private testing began
  3. On January 9, 2017, it went online

# Environmental specifications

  1. Registered account

    Mp.weixin.qq.com/ (Account information — mailbox activation — information registration)

  2. Get the id

    APPID (Login wechat public platform –> Development –> Development Settings)

  1. Developer tools

    Wechat developer tools download

Applets developer tools

Introduction to Developer Tools

Shortcut:

1. CTRL + Shift + F (search) 2. Alt + Shift + F (format code --VSCode)Copy the code

Applets native framework

Mini program native framework, mina framework details

Small program configuration file (write configuration file in wechat developer tools tools to write, there are hints)

  1. Json global configuration file

    Configuring global Files

    • Pages: Add file items to be created, save, and the file will be generated automatically

    • Windows: Set the status bar, navigation bar, title window color of the applet

* [tabBar](https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html)
Copy the code

2. page.json Page configuration file 3. sitemap

Template syntax for applets

WXML –> HTML (combined with basic components, event system, component out of the page structure)

  1. Equivalent to inline tags, no line breaks
  2. The equivalent of

    , block level elements, newline

Data binding

Data {{}}

  1. Operations –> Expressions (numeric computation, string concatenation, ternary expressions)

  2. List loop (WX :for)

    Wx :key=*this indicates that the array is a normal array, and *this is a loop item

    <view wx:for="{{ person }}" 
    wx:for-item="item" 
    wx:for-index="index"
    wx:key="id"
    >Index: {{index}} Name: {{item.name}}</view>
    Copy the code
  3. Tag –> placeholder tag

  4. Conditional render (Wx :if) (Wx :if, Wx: elIf, wx:else) (Hidden attribute is rendered by adding styles)

    Use if when tabs are not frequently toggled, and hidden when tabs are frequently toggled

event

Key words: bind (bindinput, bindtap)

Get the value of the event source object:

 e.detail.value
Copy the code

Get the value of the data in data:

This. The data. The property nameCopy the code

Set the value of the event source object back to data:

 this.setData({
        num: this.data.num + operation
});
Copy the code

{{passable parameters}} : {{passable parameters}} : {{passable parameters}} : {{passable parameters}}

 <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
    });
  },
Copy the code

style

Size of the unit

1px = 1rpx when the screen width is 750px

When the screen width equals 375px, 1px =0.5rpx

Style imports support only relative paths

Selector (wechat applet does not support wildcards)

Built-in components of applets

Layout components commonly used in applets:

View, text, rich text, button, image, icon, swiper, radio, the checkbox, etc.Copy the code
  1. The View tag is equivalent to the DIV tag

  2. Text tags can only be nested text tags. Holding down text can replicate selectable. Carriage returns and Spaces can be decode Ed.

  3. Image label (the size of the package line cannot exceed 2M, and external images are used when using images)

    1. Image has default width and height (320px by 240px)

    2. Mode Determines the image content and image label

      ScaleToFill default values do not maintain aspect ratio and stretch to the width and height defined by the label

      AspectFit maintains an aspect ratio to ensure that the long side of the image is fully displayed (commonly used in rotation)

      AspectFill short edges are fully displayed

      WidthFix keeps the width unchanged and the height automatically changes, leaving the original aspect ratio unchanged

      Top, left, bottom, right background positioning

    3. Small program in the picture directly support lazy loading

      Lazy-load determines when an image is within three screens of the viewport and starts loading it

  4. Swiper TAB — “Rotation map

    Swiper height = swiper width * Height of image/width of original image

    <swiper autoplay interval="1000" circular indicator-dots>// The image has a default width and height of 320 * 240<swiper-item><image model="widthFix" src="" /></image></swiper-item>
    </swiper>
    Copy the code
  5. Navigator navigation component (block-level element, newline by default)

    <navigator url="/pages/homepage/index" open-type="navigate"></navigator>
    Copy the code
  6. Rich-text (rich text tag, parsing string into corresponding tag, equivalent to V-HTML)

    // 1 Label string<rich-text nodes="{{ html }}"></rich-text>// 2 object array<rich-text nodes="{{ html.model }}"></rich-text>
    Copy the code
  7. The button button

    Size (size: mini/default), color (type: the default/primary/warn), whether the hollow out (plain), whether are there any additional loading before the text (loading), development capability (opentype)

    Open capability (Opentype) :

    1. Concat directly opens the customer service dialogue function, which needs to be configured in the background of the small program

      1. Change the appID of the applet from the test number to its own appID
      2. Log in to the official website of wechat mini program and add customer service – wechat
    2. Share forwards the current mini program to your wechat friends, but cannot forward the mini program to your moments

    3. GetPhoneNumber Obtains the mobile phone number of the current user. This parameter is used in combination with events

    4. GetUserInfo Gets the user’s personal information

    5. LaunchApp opens the app directly in the applet

    6. OpenSetting opens the authorization page built into the applet

      Only the permissions that the user has clicked will appear

    7. Feedback opens the built-in feedback page of the mini-program

  8. icon

    Type: type success, success_no_circle, info, warn, wating. Success_no_circle, info, warn, waiting, cancel, downkload, search, and clear

    Size: indicates the size number/string

    Color: color

  9. Radio radio buttons

    <radio-group bindchange="handleChange">
    	<radio color="red" value="male">male</radio>
        <radio color="red" value="female">female</radio>
    </radio-group>
    <view>{{gender}}</view>Data: {gender: ""}, handleChange(e) {// Let gender = e.daile.value; This.setdata ({gender // equivalent to gender: gender})}Copy the code
  10. The checkbox boxes,

    <checkbox-group bindchange="handleChange">
    	<checkbox value="{{ item.value }}" wx:for="{{ list }}" wx:key="id">{{ item.name }}		     </checkbox>
    </checkbox-group>
    <view>Check: {{checkedList}}</view>
    
    checkedList:[]
    handleChange(e) {
    	let checkedList = e.detail.value;
    	this.setData({
    		checkedList
    	})
    }
    Copy the code

The life cycle of a small program

Application life cycle

Trigger process:

OnShow onLaunch -“

App({
    // 1 Triggered when the application is enabled for the first time
    onLaunch() {
        // Get user information when the application is first started
    }
    
    // 2 The application is triggered when the user sees it
    onShow() {
    	// Used to switch between small program interfaces
    	// Resets the effect of application data or pages
	}

	// 3 Triggered when the application is hidden
	onHide() {
        // Pause or clear the timer
    }

	// 4 The application code is executed when an error occurs
	onError() {
        // Collect user error information when application code error occurs, and send the error information to the background through asynchronous request
    }

	// 5 is triggered when the page cannot be found
	// When the application is first started, it will only be triggered if the first entry page cannot be found
	onPageNotFound() {
        // If the page does not exist, redirect to the second page by using javascript
        // Cannot jump to tabbar page navigation component similar
        wx.navigateTo({
            url: "/pages/demo02/index"})}})Copy the code

Page life cycle

onLoad -> onShow -> onReady

Page({
    data: {},onLoad: function(options) {
        // onLoad sends an asynchronous request to initialize page data
    },
    onShow: function() {
        // Page display loads
    },
    onReady: function() {
        // The page is rendered for the first time
    },
    onHide: function() {
        // The onHide event is also triggered when a page is loaded and jumps to another page
    },
    onUnload: function() {
        // Page unload can also be hyperlinked to close the current page triggering an onUnload event
        // <navigator url="/pages/demo01/demo01" open-typr-redirect>demo01</navigator>
        
        // Close the current page to uninstall the page
    },
    onPullDownRefresh: function() {
        // Listen to the user drop-down event "enablePullDownRefresh":true
        // Page effect reloads
    },
    onReachBotton: function() {
        // Monitor the user's pull-up and bottom-down events
        // Usually used to pull up the next page
    },
    onShareAppMessage: function() {
        // The user clicks on the upper right corner to forward
    },
    onPageScroll: function() {
        // The page scrolls
    },
    onResize: function() {
        // Triggered when the page size changes
        // This is usually triggered when the phone is horizontal or vertical
        // add "pageOrientation":"auto" to app.json
    },
    onTabItemTap: function() {
        // 1. The current page must be tabbar
        // 2. Trigger when you click on your own TAB item}})Copy the code

Applets custom components

Steps:

  1. create

  2. Declare (which page uses a custom component, in the JSON file for that page)

    {
        "usingComponents": {
            "Tabs": ".. /.. /components/Tabs/Tabs"}}Copy the code
  3. use

    <Tabs></Tabs>
    Copy the code

Note:

  • The.js file of the page, which stores the event callback function, is stored at the same level as data

  • The.js file of the component, which stores the time callback function, is stored in the methods file

  • Do not modify the value of an array directly in a small program using this.data.x. (it is recommended to copy the array first and then modify the copied array)

    let tabs = JSON.parse(JSON.stringify(this.data.tabs));
    
    let tabs = this.data;
    Copy the code

Passing values between components

Parent component passes value to child component

Passed by the attribute of the tag:

  1. Parent component passing

    <Tabs aaa="123"></Tabs>
    Copy the code
  2. Subcomponent reception

    Component({
        // This contains the data to be received from the parent component
        properties: {
            // The name of the data to accept
            aaa: {//type Indicates the type of the received data
                type: String./ / the value the default values
                value: ""}}});Copy the code
  3. The child component uses data passed in from the parent component

    The received data is used as data in its own data

    <view>{{ aaa }}</view>
    Copy the code

Child components pass values to parent components

By way of an event.

TAB switch bar, click switch.

  1. Bind click events need to be bound in Methods
  2. Gets the index that was clicked
  3. Get the original array
  4. Loop over an array
    1. Change the selected property to false for each loop item
    2. Adds an active selection effect to the item in the current index
  5. When a click event is triggered, the custom event in the trigger parent component is also passed to the parent component
    1. This.triggerevent (” Parent component custom event name “, parameter to pass)

In the Tabs page:

<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">// Arguments passed by placeholders are replaced<slot></slot>
</view>
Copy the code

In the js file of the child component :(this does not change the internal data of the component, just based on style changes, not based on functionality)

methods: {
    hanldeItemTap(e) {
        // Get the index
        const {index} = e.currentTarget.dataset;
        // let {tabs} = this.data;
        // tabs.forEach((v,i) => i===index? v.isActive=true:v.isActive=false);
        // Modify the data in data
        // this.setData({
        // tabs
        // })
        
        // Triggers custom events in the parent component to be passed to the parent component
        this.triggerEvent("itemChange", {
            index
        })
    }
}
Copy the code

Add a custom event to a custom component in the parent component:

<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>
Copy the code

In the parent component’s js:

data: {
    tabs: [{id: 1.name: "Home page".isActive: true
        },
        {
            id: 2.name: "To be shipped".isActive: false
        },
        {
            id: 3.name: "To be paid".isActive: false}}]// The custom event receives data passed by the child component
handleItemChange(e) {
    // Receive the parameters passed
    const {index} = e.detail;
    // Get the original array
    let {tabs} = this.data;
    tabs.forEach((v,i) = >i===index? v.isActive=true:v.isActive=false);
    // Modify the data in data
    this.setData({
        tabs
    })
}
Copy the code

Other attributes

Definition section type describe
properties Object Map The external property of the component is the property name and the mapping table for the property Settings
data Object Often used when a parent passes a value to a child that receives the value from the parent
observers Object Listen for data changes to properties and data
methods Object Component methods
created Function Component lifecycle functions (executed when the component instance has just been created) cannot call setData at this time
attached Function Executed when the component instance enters the page node tree
ready Function Execute when the component layout is complete
moved Function Mobile execution
detached Function Remove to perform

project

  1. Home page
  2. List of goods
  3. The shopping cart
  4. Authorization page
  5. Commodity search
  6. Goods collection
  7. Classification of goods
  8. Goods details
  9. settlement
  10. The order list
  11. Personal center
  12. feedback

Third party framework for applets

  1. Tencent Wepy is similar to Vue
  2. Meituan MPvue is similar to VUE
  3. Jd.com Taro is similar to React
  4. Drops chameleon
  5. Uni-app is similar to VUE
  6. Native framework MINA

Use ali font icon library

  1. In ali icon official website, the icon to be used, add to the shopping cart

  2. Add icon to project

  3. Pyg — “Font class (using ICONS in a class way) –” view online links

  4. In the styles folder of the project create the iconFont. WXSS file

  5. Open the link and copy the contents of the link to the iconfont. WXSS file

  6. Use fonts from the Font icon library

    1. In the global WXSS file, import the WXSS file

      @import "./styles/iconfont.wxss"
      Copy the code
    2. use

      <text class="iconfont icon-shoucang"></text>
      Copy the code

tabBar

Configure it in app.json

tbaBar: {
    "color": "".// The color of the unselected font
    "selectedColor": "".// The color of the selected font
    "backgroundColor": ""./ / the background color
    "position": ""./ / position
    "borderStyle": "".// Border style
    "list": [{"pagePath": "".// The path to the page
            "text": "".// The name of the title
            "iconPath": "".// Unselected icon path
            "selectedIconPath": ""   // The path of the selected icon}}]Copy the code

Initialization of the page style

Note: Wildcard characters (*) are not supported in applets

In the app.wxss file

page,view,text,swiper,swiper-item,image,navigator { padding: 0; margin: 0; box-sizing: border-box; } /* Theme color 1. Less is a variable 2. Native CSS and WXSS also support CSS */ page {--themeColor: #eb4500; Font: 28rpx; color: RGB (50, 50, 50); font-size: 28rpx; }Copy the code

Use theme colors:

view {
	color: var(--themeColor);
}
Copy the code

The head

Set the theme color:

"window": {
    "backgroundTextStyle": "light".// Font color
    "navigatorBarBackgroundColor": "#2b4500"./ / the background color
    "navigatorBarText": Vipshop.// Font prompt
    "navigatorBarTextStyle": "white".// Font style
}
Copy the code

Using interface data

Page({
    data: {
        swiperList: []},// Page loading event
    onLoad: function() {
        /* 1. Send an asynchronous request to obtain the used data */
        wx.request({
        	url: ' '.// Interface address
        	success: (result) = > {
        		// The swiperList array was successfully assigned
        		this.setData({
        			swiperList: result.data.message
        		})
        	}
        	
        });
        /* wx.request Too many asynchronous requests can create callback hell: PROMISE */ in ES6}})Copy the code

Request error (two solutions):

  1. In a small programdetailsClick on the interfaceVerify valid domain names, Web-view (business domain names),TLS versions, and HTTPS certificates
  2. For configuring the request interface, see 8.7. Add the domain name requested by the applet to the background

Fix callback hell (PROMISE of ES6)

Create the index.js file in the request folder of your project

It is used by encapsulating methods and then calling functions to pass parameters

// The number of times asynchronous code was sent simultaneously
let ajaxTime=0;
export const request=(params) = > {
    ajaxTime++;
    // Data loading effect
    wx.showLoding({
       title: "Loading".mask: true
    });
    return new Promise((resolve, reject) = > {
        wx.request({
            // Deconstruct the parameters passed. params,success: (result) = > {
                resolve(result);
            },
            faile: (err) = > {
            	reject(err);
        	},
            // This function is called on success or failure
            complete: () = > {
                ajaxTime--;
                if(ajaxTime === 0) {
                   // Close the waiting iconwx.hideLoading(); }}}); }); }Copy the code

Use the encapsulated request method:

// Import the encapsulated file (note: be sure to complete the path)
import { request } from '.. /.. /request/index.js';  // This is a wrapped request function

Page({
    data: {
        swiperList: []},// Page loading event
    onLoad: function() {
        /* 1. Send an asynchronous request to obtain the used data */
        /* wx.request({url: ", // interface address SUCCESS: (result) => {// Request succeeded in assigning values to the swiperList array this.setData({swiperList: result.data.message }) } }); * /
        /* wx.request Too many asynchronous requests can create callback hell: PROMISE */ in ES6
        
        // Call the method
        this.getSwiperList();
        
    },
    // Call the wrapped method
    getSwiperList() {
        // The data filled here will replace the request method... params,
        request({ url: 'htltps://api/zbtbs/home/swiperList'}); 
        // Data is successfully obtained
        .then (result= > {
            this.setData({
                swiperList: result.data.message }) }); }})Copy the code

Adds the domain name requested by the applet to the background

  1. Enter theWechat public platform
  2. The development of
  3. The development set
  4. Server domain name
  5. Add a valid request domain name

Get data stored locally

The difference between local storage on the Web and local storage in applets:

  1. The way you write code is different
    1. The web:
      1. Storage mode: localstorage. setItem(“key”, “value”);
      2. GetItem (“key”);
    2. In the applets:
      1. Storage mode: wx.setStoragesync (“key”, “value”);
      2. Wx. getStorageSync(“key”, “value”);
  2. Is there any type conversion when saving
    1. Web: no matter what type of data is stored, it will eventually be converted toString data through the toString () method
    2. Applets: There is no data type conversion
// Data returned by the interface
Cates: [].onLoad: function(options) {
    // Get old data in local storage
    const Cates = wx.getStorageSync("cate");

    // Check whether the local exists
    if(! Case) {// There is no send request data
        this.setCates();
    }else {
        // There is old data
        // Define when data expires
        if(Date.now() - Cates.time > 1000 * 10) {
           // Resend the request
            this.getCates();
        } else {
            this.Cates = Cates.data;
            // Render data}}}// Get the requested data
getCates() {
    // Store interface data to local storage
	wx.setStorageSync("cates", {time:Date.now(),data: this.Cates});
}
Copy the code

Define the public URL

In the request.js file, encapsulate the request method

export const request=(params) = > {
    // Define the public URL
    const baseUrl = "https://api.zbsb.cn/api/public"
    return new Promise((resolve, reject) = > {
        wx.request({
            // Deconstruct the parameters passed. params,url: baseUrl + params.url;
            success: (result) = > {
                resolve(result);
            },
            faile: (err) = >{ reject(err); }}); }); }Copy the code

Applets support ES7 async syntax

  1. Select ES6 to ES5 syntax in wechat developer tools

  2. Download runtime.js from reGenerator on Github

  3. Create a folder called /lib/runtime/runtime.js under the applet directory and copy the code into it

  4. Import files in every page JS file that needs to use async syntax

    import regeneratorRuntime from '.. /lib/runtime/runtime';
    Copy the code

    Using asYN syntax:

    async getCates() {
        // 1 uses es7 async await to send the request
        const res=await request({url:"/categories"});
    }
    Copy the code

Applets URL parameter passing

// Pass parameters<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) {sol.log(options); // Print out the value of options}Copy the code

Encapsulates TAB switching components

Encapsulated Tab components:

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>// Switch the content<view class="tabs-content">
    	<slot></slot>
    </view>
</view>


methods: {
    // Click the event
    handleItemTap(e) {
        // Get the index of clicks
        const {index} = e.currentTarget.dataset;
        // Triggers events in the parent component
        this.triggerEvent("tabsItemChange", {index}); }}Copy the code

Using the packaged Tab component:

//bindtabsItemChange listens for custom events<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>// Title click event bindtabsItemChange(e) {// get the index of the clicked title const {index} = e.dot; Let {tabs} = this.data; tabs.forEach((v,i)=>i===index? v.isActive=true:v.isActive=false); // Assign a value to data this.setData({tabs}); }Copy the code

Scroll bar bottom event (page slide event)

The scroll bar hits bottom and loads the next page of data

Total pages = Math.ceil(Total pages/number of data displayed per page)

// Get the item data list
async getGoodsList() {
    const res=await request({url:"/goods/search".data:this.QueryParams});
    // Get the total number of entries
    const total = res.total;
    // Count the total pages
    this.totalPage = Math.ceil(total / this.QueryParams.pagesize);
    // Concatenate an array
    this.setData({
        goodsList: [...this.data.goodsList,...res.goods]
    });
    // Close the drop-down refresh window
    wx-stopDownRefresh();
}
// Scroll bar bottom event
onReachBottom() {
    // Determine if there is any data on the next page
    if(this.QueryParams.pagenum >= this.totalPage) {
        // Current page number > Total pages No next page
        
    }
    else {
        When the data request comes back, the array in data is concatenated
        this. The QueryParams. Pagenum++;this.getGoodsList(); }}Copy the code

Drop down to refresh the page

  1. Trigger the drop-down refresh event (json file to the page open a configuration items) [enablePullDownRefresh: true, backgroundTextStyle: dark 】
  2. Resetting the data array
  3. Reset the page number set to 1
  4. Resend the request
  5. Data request success, manually disable wait effect
onPullDownRefresh() {
    // Reset the data array
    this.setData({
        goodsList: []});// Reset the page number to 1
     this.QueryParams.pagenum=1;
    // Resend the request
    this.getGoodsList();
}
Copy the code

Wx. showModel changes the orientation of this

wx.showModel({
    title: 'tip'.content: 'Do you want to delete it? '.success :(res) = >{... }})Copy the code

Delete from js

cart.splice(index, 1);  // Drop the index element

cart.filter(v= > v.checked);  // Select the cart array whose checked is true
Copy the code

Popover encapsulation

In the asyncwx.js file

export const showModel=({content}) = > {
    return new Promise((resolve,reject) = > {
        wx.showModel({
            title: 'tip'.content: content,
            success :(res) > {
                resolve(res);
            },
            fail :(err) = >{ reject(err); }})})}Copy the code

use

import {showModel} from '.. /.. /utils/asyncWx.js';

async showTips() {
    const res=await showModel({content: 'Do you want to delete it? '})
    if(res.confirm) {
       cart.splice(index, 1);
        this.setData(cart); }}Copy the code

Get the data in the cache

wx.getStorageSync("address");
Copy the code

WeChat pay

  1. Corporate account
  2. Whitelists must be added to developers in the applet background of enterprise accounts
    1. An AppID can bind to multiple developers
    2. After binding, the developer has developer privileges
  3. Payment button
    1. Check whether there is a token in the cache
    2. The authorization page is not displayed to obtain the user token value
    3. The payment operation has been performed

Process: create order, prepare pre-payment, initiate wechat payment, query order

First, obtain the token

handleOrderPay() {
   try {
        // 1. Check whether there is a token value in the cache
        const token = wx.getStorageSync("token");
        / / 2. The judgment
        if(! token) {// Go to the authorization page
            wx.navigateTo({
                url: "/page/auth/index"
            })
            return;
        }
        // 3. Create order
        // Prepare the parameters needed to create the order
        const header = {Authorization:token};
        // Prepare the request body parameters
        const order_price = this.data.totalPrice;   // Total order price
        const consignee = this.data.address.all;  // Full address
        let goods = [];
        const cart = this.data.cart;
        goods.forEach(v= > goods.push({
            goods_Id: v.goods_Id, // Product id
            goods_number: v.goods_number, // Quantity of goods
            goods_price: v.goods_price  // The unit price of the goods
        }))
        const orderParams = {order_price,consignee,goods}
        // 4. Prepare to send request create order obtain order number
        const {order_number}=await request({url: 				     "/order/create"},method:"POST".data:orderParams,head:head});
        // 5. Initiate prepayment interface
        const {pay}=await request({url:"/order/req_unifiedorder".method:"POST",head,data:{order_number}});
        // 6. Initiate wechat Pay
        await requestPayment(pay);
        // 7. Check whether the background order status is displayed successfully
        const res=await request(url:"/orders/chkOrder".method:"POST",head,data:{order_number}});
		// The payment is successful
		await showToast({title:"Payment successful"});
		// Manually delete the data from the cache for the successful cart payment
		let newCart = wx.getStorageSync("cart");
		// Filter out unselected data
		newCart = newCart.filter(v= >! v.checked); wx.setStorageSync("cart",newCart);
		// 8. The payment is successful and the order page is displayed
		wx.navigateTo({
            url: '/page/order/index'})}catch(err) {
       await showToast({title:"Payment failure"}); }}Copy the code

Autn /index page:

<button open-type="getUserInfo" bindgetUserInfo="handleGetUserInfo">To obtain authorization</button>
Copy the code
// Get user information
// encryptedData  
// rawData
// iv
// signature
async handleGetUserInfo(e) {
    try {
        // Get user information
        const { encryptedData,rawData,iv,signature } = e.detail;
        // Get token value after applet login encapsulates token request method in asyncwx.js
        // wx.login({
        // timeout: 1000,
        // success: (result) => {
        // cost { code } = result;
        / /}
        // })
        const {code} = await login();
        const loginParams = { encryptedData, rawData, iv, signature, code }
        // Send a request to obtain the user's token
        const {token}=await request(url: '/user/wxlogin'.data: loginParams,methods: 		"post");
        // Store the obtained token in the cache and go back to the previous page
        wx.getStroageSync("token", token);
        wx.navigateBack({
            data: 1 // return to the previous layer})}catch(err) {
    	console.log(err); }}Copy the code

Encapsulate the payment method in asyncwx.js:

export const requestPayment=(pay) = > {
    return new Promise((resolve,reject){ wx.request({ ... pay,success: (result) = > {
        		resolve(result);
    	   },
           fail: (err) = >{ reject(err); }})})}Copy the code

2. Prepare for pre-payment (obtain the parameter pay)

Iii. Initiate wechat Payment (submit pay parameters)

Fourth, check the order

Delete items that have been selected to purchase from the cache

Sixth, the deleted shopping cart data will be cached

Seven, jump page

Image upload (wx.uploadFile)

When uploading a picture, when storing the uploaded picture, you should first splice the previous picture.

ChooseImage: [].

this.setData({

ChooseImage: [Group of images before uploading, group of images uploaded]

​ chooseImage: […this.data.chooseImage, …chooseImage]

})

The API for uploading files does not support simultaneous uploading of multiple files

Solution: Go through the number of groups one by one to upload

wx.uploadFile({
    url: ' '.// Where do I upload the image
    filePath: ' '.// The path of the uploaded file
    name: ' '.// Name of the uploaded file The background obtains the name of the uploaded file defined by the background
    formData: {}, // Accompanying text message
})
Copy the code

Project released

** Note: Before publishing, please remember to turn off the details screen without verifying the valid domain name **

The size of each file to be uploaded does not exceed 2 MB, and the total size does not exceed 10 MB.

Upload:

  1. The version number
    1. First number (big version update)
    2. Second number (Important feature updates)
    3. Third number (minimal features, minor bugs, minor patches)
  2. Less files will not be packaged and uploaded
  3. The successful upload of the applets is still an experience version of the applets, if the experience version of the applets into the online version of the applets, the wechat public platform will be submitted to the experience of the applets, submitted for review (the review time is about one hour).

Applets plug-in

  1. Applets development assistant

  1. Install the Easy Less plug-in

Set in vscode (CTRL + shift + p then enter setting and add the following configuration) :

"less.compile": {
    "outExit": ".wxss"
}
Copy the code