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