Note source: Hook Education – big front end employment Training camp

Content: Notes, thoughts and experiences in the process of learning

Payment, packaging optimization

Payment function

Component to prepare

The payment component is set as a separate component

Process routing, realize click, jump payment page, using path parameters, need to log in to access

Check whether you have logged in. If you have logged in, skip to the course ID and then return to the course details page

// SRC /router/index.js add the payment route

{ // Pay for the purchase
  name: 'pay'.path: '/pay/:courseId'.component: () = > import(/* webpackChunkName: 'pay' */'@/views/pay'),
  // Set path parameters
  props: true.meta: { login: true}},Copy the code
SRC /views/pay/index.vue Create a directory and file. <template> <div class="pay"> </div> </template> <script> export default {name: 'pay'} </script>Copy the code
SRC /views/course-info/index.vue Add click event to buy now button, check whether to log in, check whether to jump to login page <! <van-button type="primary" @click="goPay"> </van-button> // goPay () {if $router.push(' /pay/${this.courseId} ')} else {// If this.$store.state.user) {// If this.$router.push(' /pay/${this.courseId} ')} else {// If this. $route. push({name: 'login', query: {path: this.$route.fullPath}})}}Copy the code

Layout processing

You can still use cell components

Set up the basic structure, processing style, and finally payment method to fill the remaining height

SRC /views/pay/index.vue calls the interface to get the data, set the top and middle structure and style <template> <! -- Cell container --> <van-cell-group> <! -- Top course information --> <van-cell> <! <img: SRC =" courseinfo.courseimgURL "/> <div> <! - course name - > < p v - text = "courseInfo. CourseName" > < / p > <! - price - > < p > selections {{courseInfo. Discounts}} < / p > < / div > < / van - cell > <! -- Intermediate user information --> <van-cell> <p> Purchase information </p> <p> - the current user phone number -- -- > < p > current account: {{phone}} < / p > < / van - cell > <! </van-cell> </van-cell> </van-cell> </template> <script> Import {getCourseById} from '@/ API /course' export default {name: 'pay', // parameter: {// Path parameter courseId: {type: [Number, String], Required: true}}, data () {return {// courseInfo: {}}}, // create () {this.getCourse()}, methods: Async getCourse () {// Call the interface const {data} = await getCourseById(this.courseid) // Pass the obtained information to data if (data.state === 1) this.courseInfo = data.content}}, // Calculate attributes computed: {// Process the user's phone number phone () {// Replace the middle bits with * return using the replace regular this.$store.state.user.organization.replace(/^(\d{3})\d{4}(\d{4})$/, '$1****$2')}}} </script> <style lang=" SCSS "scoped> // whole container. Van-cell-group {display: flex; flex-direction: column; height: 100vh; background: #f8f9fa; } // Remove the bottom line of all cells. Van-cell ::after {display: none; } van-cell:nth-child(1) {padding: 40px 20px 0; margin-bottom: 10px; .van-cell__value { display: flex; height: 130px; img { width: 80px; height: 107px; border-radius: 10px } div { display: flex; height: 107px; box-sizing: border-box; flex-direction: column; justify-content: space-between; padding: 5px 20px; p { margin: 0; } p:nth-child(1) { font-size: 16px; } p:nth-child(2) { font-size: 22px; color: #ff7452; font-weight: 700; }}}} // Middle user info. Van-cell :nth-child(2) {padding: 10px 16px; margin-bottom: 10px; p { margin: 0; } p:nth-child(2) { font-size: 12px; color: #999; } p:nth-child(3) { margin: 20px 0 10px; font-size: 16px; Flex: 1; flex: 1; flex: 1; flex: 1; flex: 1; } </style>Copy the code

Data binding

Initializing the acquisition of course information and user information for data binding

The mobile phone number can be directly used by vuex, which is processed by calculating the attributes

It’s already bound

Payment structure processing

Using the Vant box component, on the basis of the style structure processing, using the cell slot

Data binding

Wechat icon address

Alipay icon address

Changing radio button colors may require style traversal (I’m using component properties directly here)

SRC /views/pay/index.vue add payment info and button <! --> <van-cell class="pay"> <p> Payment method </p> <! <van-radio-group v-model="radio"> <! <van-cell group> <van-cell title=" clickable @click="radio = '1'"> <! - slot - > < # template title > < img SRC = "http://www.lgstatic.com/lg-app-fed/pay/images/wechat_b787e2f4.png" Alt = "" > < span </span> </template> <! -- slot --> <template #right-icon> <van-radio name="1" checked-color="#fbc547" /> </template> </van-cell> <van-cell Clickable @click="radio = '2'"> <template #title> <img SRC = "http://www.lgstatic.com/lg-app-fed/pay/images/ali_ed78fdae.png" Alt = "" > < span class =" custom - the title "> < / span > pays treasure </template> <template #right-icon> <van-radio name="2" checked-color="#fbc547" /> </template> </van-cell> </van-cell-group> </van-radio-group> <! <van-button>¥{{courseInfo. Discounts}} </van-button> </van-cell> <style lang=" SCSS "scoped> . Flex: 1; flex: 1; van-cell_value { padding: 40px; } .van-cell-group::after { display: none; } .van-cell--clickable { padding: 20px 10px; .van-cell__title { display: flex; align-items: center; img { width: 28px; height: 28px; } span { margin-left: 10px; font-size: 16px; Van-button {position: absolute; bottom: 10px; width: 100%; border-radius: 22px; background-image: linear-gradient(to right, #fbc547, #faad4a); font-size: 18px; } } </style>Copy the code

Interface encapsulation

The order is generated using the Create item Order interface, and the userID does not need to be passed

Payment is made using create order (initiate payment)

Use the query order (payment result) to get the payment result (polling), which can pass data in JSON format instead, but axios can’t recognize it, but the back end can parse it

Try using the Get Payment Method interface

Currently, the payment function of this course is not blocked (orders cannot be generated). You can create a new course (in the background project), and you can pay by searching in the foreground. You can directly find the courses generated by students before

Get the order number => get the allowed payment method

// SRC/API /pay.js creates a file that encapsulates the four interfaces required for payment

/ / introduce axios
import axios from './axios'

// Create an order
export const saveOrder = data= > {
  return axios({
    method: 'post'.url: '/front/order/saveOrder',
    data
  })
}

// Get the payment method
export const getPayInfo = shopOrderNo= > {
  return axios({
    method: 'get'.url: `/front/pay/getPayInfo? shopOrderNo=${shopOrderNo}`})}// Initiate payment
export const saveOrderBuy = data= > {
  return axios({
    method: 'post'.url: '/front/pay/saveOrder',
    data
  })
}

// Get the payment result
export const getPayResult = params= > {
  return axios({
    method: 'get'.url: '/front/pay/getPayResult'.headers: { 'content-type': 'application/json' },
    params
  })
}

Copy the code
SRC /views/pay/index.vue Add payment function <template> <! -- Cell container --> <van-cell-group> <! <van-cell class="course"> <! <img: SRC =" courseinfo.courseimgURL "/> <div> <! - course name - > < p v - text = "courseInfo. CourseName" > < / p > <! - price - > < p > selections {{courseInfo. Discounts}} < / p > < / div > < / van - cell > <! -- Intermediate user information --> <van-cell class="user"> <p> Purchase information </p> <p> After purchasing the course, use this account to log in to [check education] to learn the course </p> <! - the current user phone number -- -- > < p > current account: {{phone}} < / p > < / van - cell > <! --> <van-cell class="pay"> <p> Payment method </p> <! <van-radio-group v-model="radio"> <! <van-cell group> <van-cell title=" clickable @click="radio = '1'"> <! - slot - > < # template title > < img SRC = "http://www.lgstatic.com/lg-app-fed/pay/images/wechat_b787e2f4.png" Alt = "" > < span </span> </template> <! -- slot --> <template #right-icon> <van-radio name="1" checked-color="#fbc547" /> </template> </van-cell> <van-cell Clickable @click="radio = '2'"> <template #title> <img SRC = "http://www.lgstatic.com/lg-app-fed/pay/images/ali_ed78fdae.png" Alt = "" > < span class =" custom - the title "> < / span > pays treasure </template> <template #right-icon> <van-radio name="2" checked-color="#fbc547" /> </template> </van-cell> </van-cell-group> </van-radio-group> <! <van-button @click="buyCourse">¥{{courseInfo. Discounts}} </van-button> </van-cell> </van-cell> Import {getCourseById} from '@/ API /course' import {getCourseById} from '@/ API /course' Create order, obtain payment method, initiate payment, Import {saveOrder, getPayInfo, saveOrderBuy, getPayResult} from '@/ API /pay' export default {name: 'pay', // Parameter props: {// Path Parameter courseId: {type: [Number, String], required: True}}, data () {return {// Course information courseInfo: {}, // The currently selected payment method Radio: null, // The order number created (not the order number that initiated the payment) orderNo: }, // hook function created () {// getCourse info this.getcourse ()}, methods: {// pay now button click event !!!!!!!!!!!!!!!!!!!!!!!!!!!! Async buyCourse () {// call interface create order const {data} = await saveOrder({goodsId: If (data.state === = 1) this.orderNo = data.content.orderNo // call the interface to get the payment method. Const {data: const {data: const {data: const {data: Data2} = await getPayInfo(data.content.orderNo) console.log(data2) Const {data: data3} = await saveOrderBuy({goodsOrderNo: data.content.orderNo, channel: this.radio === 1 ? 'weChat' : 'aliPay', returnUrl: "Http://edufront.lagou.com/"}) / / if a successful jump payments (here use pay treasure, If (data.state === 1) window.location.href = data3.content.payurl // create timer polling const timer = SetInterval (async () => {// Call interface to query payment status const {data: data4} = await getPayResult({orderNo: Data3.content.orderno}) // If (datA4.content.status === 2) {// Stop timer clearInterval(timer) / / jump this study page. $router. Push ('/study)}}, 1000)}. Async getCourse () {// Call interface const {data} = await getCourseById(this.courseid) // Pass the obtained information to data if (data.state === 1) this.courseInfo = data.content}}, // Calculate attributes computed: {// Process the user's phone number phone () {// Replace the middle bits with * return using the replace regular this.$store.state.user.organization.replace(/^(\d{3})\d{4}(\d{4})$/, '$1****$2')}}} </script> <style lang=" SCSS "scoped>. Van-cell-group {display: flex; flex-direction: column; height: 100vh; background: #f8f9fa; } // Remove the bottom line of all cells. Van-cell ::after {display: none; } // top course info. Course {padding: 40px 20px 0; margin-bottom: 10px; .van-cell__value { display: flex; height: 130px; img { width: 80px; height: 107px; border-radius: 10px } div { display: flex; height: 107px; box-sizing: border-box; flex-direction: column; justify-content: space-between; padding: 5px 20px; p { margin: 0; } p:nth-child(1) { font-size: 16px; } p:nth-child(2) { font-size: 22px; color: #ff7452; font-weight: 700; }}}} // Middle user information. user {padding: 10px 16px; margin-bottom: 10px; p { margin: 0; } p:nth-child(2) { font-size: 12px; color: #999; } p:nth-child(3) { margin: 20px 0 10px; font-size: 16px; Flex: 1; flex: 1; flex: 1; van-cell_value { padding: 40px; } .van-cell-group::after { display: none; } .van-cell--clickable { padding: 20px 10px; .van-cell__title { display: flex; align-items: center; img { width: 28px; height: 28px; } span { margin-left: 10px; font-size: 16px; Van-button {position: absolute; bottom: 10px; width: 100%; border-radius: 22px; background-image: linear-gradient(to right, #fbc547, #faad4a); font-size: 18px; } } </style>Copy the code

Payment requests

Click the payment button to judge the payment method and initiate the payment. After the payment, you will get an order number. After that, you will get the payment result through continuous rotation training

Note that weChat or aliPay should be used as the payment method. WeChat cannot arouse weChat (background setting problem), so aliPay is recommended

If you get the returned data and jump directly to the address in the data, it will automatically jump to Alipay payment

After the jump, keep polling to get the payment result. Once the payment is successful (status = 2), jump to the payment success page, or jump to the master failure page if the payment fails (status = 2)

Add a prompt for both successful and failed payments

It’s already written up there

Packaging optimization

Optimize the packaging speed and the size of the packaged files. If you use more static files, a project may be very large

The configuration file

Use the vue-CLI configuration file vue.config.js to package the configuration. If there is no such file, the default configuration items will be used

Recommended configuration items:

  • ProductionSourceMap: Production environment projects do not require map files
  • Css.extract: When each CSS file size is small, we can pack these files into a single file to reduce the number of requests

Image compression

Compress only if it is necessary to be compressed, not if high definition is required

Install image loader: NPM I image-webpack-loader -d, some packages may use github address, you can set hosts, after the installation will be much faster

If the loader installation fails, delete the old dependent files and reinstall the loader. Otherwise, an error may occur

Add the configuration in the vue.config.js configuration file

May be network reasons, the use of image compression has been installed problems, not to do

Vant imports components on demand

Vue.config. jsant provides a method to automatically import components on demand, which will automatically convert global import to import on demand during compilation, reducing the packaging size

Note that you need to modify the way vant components are used in components. First introduce the components that you need to use again, and then register them as sub-components. Note that Toast is special (it is used directly without registration).

Delete global import after import on demand

The above steps are necessary to ensure that the Vant will render properly

Reference vantThe official documentation=> Install NPM package => modify Babel file contents => change all vant component import mode (of course, it is better to directly import vant components as required, don’t ask me how to know) => remove the previous global import => find that each small module js file slightly increased, The largest JS size is significantly smaller, which makes for a faster first load

Introduced the CDN

Content distribution network – stable, fast, will speed up the response of certain large packages using CND introduction

BootCdn provides many CDN services, which ali Cloud can purchase

Vant provides CDN import mode. This project can introduce BOTH VUE and Vant using CDN

CDN import is also not done, because the above is too much to modify, the future code directly use automatic import on demand can be

You can go back and watch the video later when you need to