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

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

Project construction and course selection function

Project preparation

Mobile project: Use the debug tool to debug mobile

It is divided into three parts: course selection (no login required), Learning and ME (login required to view).

Project Construction:

  • Create a new project:Vue create name– Manually select configuration presets – Create projects
  • Delete Delete a project: Delete unnecessary files and modify file contents
  • Initialize project: Add interface encapsulation folder (added utils and Services in video)
  • Git setup: INSTEAD of using the command line in the course, I use Sourcetree to manage the project, and can view the previous project if necessary

Vant component library

Like Element,Vant component libraryVue is a Vue component library for mobile terminal, still under maintenance, and supports VUe3 and wechat applets

Using Vant

  • Install Vant – using vuE-CLI scaffolding toolvue uiThe GUI is displayed for installing dependencies
  • Import all components here because we need to use many Vant components
// SRC /main.js imports and registers the Vant

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

/ / into the Vant
import Vant from 'vant'
import 'vant/lib/index.css'
// Register Vant as a vue plug-in
Vue.use(Vant)

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h= > h(App)
}).$mount('#app')

Copy the code

Browser adaptation

Use REM layout – Set REM for different viewport widths

You need to use two plug-ins

  • Amfe-flexible: Dynamic setting rem reference value – install and import
  • ** PostCSs-pxtoREM: ** Automatically converts written PX to REM, is a plug-in for vue-CLI integrated PostCSS functionality

Configured to use

  • Write the postCSS configuration file – in the project root directory.postcssrc.js
  • Write the browser configuration information in dot browserslistrc
  • Notice You need to restart the serve server to modify the configuration file
// SRC /main.js install amfe-flexible and import it.// Introduce amFE-flexible to automatically set the root element REM
import 'amfe-flexible'.Copy the code
// create a configuration file in the root directory of.postcsrc

// Configure the fixed writing method
module.exports = {
  // Plug-in configuration
  plugins: {
    // Automatically add the browser prefix
    'autoprefixer': {
      // Vue does not recommend these here, so put them in.browserslistrc
      // browsers: ['Android >= 4.0, 'iOS >= 8']
    },
    / / postcss - pxtorem configuration
    'postcss-pxtorem': {
      / / the default rem
      rootValue: 37.5.// Attributes that need to be converted to REM, * represents all
      propList: [The '*']}}}Copy the code
Browserslistrc root directory add browser configuration > 1% last 2 versions not dead Android >= 4.0 iOS >= 8Copy the code
<template> <div> <van-button> <div class="box"></div> </div> </div> <! -- <router-view/> --> </template> <style lang="scss" scoped> .box { width: 100px; height: 100px; background: #ccc; } </style>Copy the code

Pay attention to

  • Postcss-pxtorem cannot convert the px property inside the line
  • The postCSS-pxtorem version is 5.1.1

The routing process

Page analysis

  • The landing page is a separate page
  • Course selection, study, I three pages
  • The error page is a separate page
  • Other page functions will be added later

Create files and routing rule Settings

  • The course selection component is the root directory, because the course selection can be viewed without logging in and this page is opened by default
  • Because the course selection component is the default home page, you can use the traditional method instead of routing lazy loading
  • I don’t write inclusion anymore because it’s mobile
Create five page folders under the Views folder and create index. Here is an example of login's index.vue Other pages are roughly the same SRC/views/login/index. The vue < template > < div > landing page < / div > < / template > < script > export default {name: 'login' } </script>Copy the code
// SRC /router/index.js creates a route for five pages

import Vue from 'vue'
import VueRouter from 'vue-router'
// The course selection page does not use lazy loading
import Course from '@/views/course'

Vue.use(VueRouter)

const routes = [
  { / / landing page
    name: 'login'.path: '/login'.// Use route lazy load, load on demand, use magic name
    component: () = > import(/* webpackChunkName: 'login' */'@/views/login')}, {// Select the course page, the root page
    name: 'course'.path: '/'.component: Course
  },
  { // Learning page
    name: 'study'.path: '/study'.component: () = > import(/* webpackChunkName: 'study' */'@/views/study')}, {// User page
    name: 'user'.path: '/user'.component: () = > import(/* webpackChunkName: 'user' */'@/views/user')}, {// Error page
    name: 'error'.path: The '*'.component: () = > import(/* webpackChunkName: 'error' */'@/views/error')}]const router = new VueRouter({
  routes
})

export default router

Copy the code

Encapsulate request module -Interface documentation

Use AXIOS for interface AJAX requests

  • Install the AXIos plug-in,npm install axios
  • Create a js file that uses AXIos to create examples, set the URL prefix, and export the AXIos instance
// SRC/API /axios.js create a new file to encapsulate the request module. From now on, all interface related functions will be encapsulated in the API folder

// Introduce the AXIos plugin
import axiosPlug from 'axios'

// Create an axios instance
const axios = axiosPlug.create({
  // Set the URL prefix
  baseURL: 'http://edufront.lagou.com'
})

// Export the instance
export default axios

Copy the code
SRC/app.vue tests if our encapsulated interface works, <template> <router-view/> </template> <script> import axios from Axios ({method: 'get', // this interface can request url: '/front/ AD /getAdList'}) </script>Copy the code

Common Components – Bottom bar

Using the TAB bar component in Vant, the component provides routing modes for route hops

Common components are wrapped separately, introducing three of the three components that need to be used

ICONS can be replaced using the ICONS component in Vant

Directly modify the to attribute in the TAB bar component can be realized by clicking to jump to the specified component

SRC /common/foot-bar.vue separately wraps the bottom TAB bar component as a public component. The public component is all placed in the common directory <template> <! <van-tabbar route> <! -- to set forward routes, <van-tabbar-item replace to="/" icon="cart-o"> select courses </van-tabbar-item> <van-tabbar-item replace to="/study" Icon ="records"> learn </van-tabbar-item> <van-tabbar-item replace to="/user" icon="user-o"> I </van-tabbar-item> </van-tabbar> </template> <script> export default { name: 'footBar' } </script>Copy the code
SRC/views/course/index. Vue course selection page to introduce and use the tabs common components < template > < div class = "course" > <! <footBar/> </div> </template> <script> import footBar from '@/common/foot-bar' export Default {name: 'Course', // register component components: {footBar}} </script>Copy the code

Course selection function

The course selection function area is divided into two parts

  • Top display area
  • Bottom display area for all course lists

Create two components and introduce them into index.vue

Head mounted assembly

There is only one logo display area in the header and you can use the Vant image component

Images can be imported using static resources: SRC = require (image path)

Some style adjustments may be required, and Vant can set properties directly using the component name as the class name

Note: I write the top component directly inside the index instead of writing the child component separately

SRC/views/course/index. Vue use image components set at the top of the logo "template > < div class =" course "> <! <van-image width="180" : SRC ="require('@/assets/logo.png')" /> <! - create a TAB bar component instance - > < footBar / > < / div > < / template >... <style lang=" SCSS "scoped> // top logo. Van-image {margin-left: -20px; } </style>Copy the code

Advertising rotation diagram

Use the multicast component in Vant

The data that needs to be used in the broadcast graph uses the advertising interface

  • Get all the AD space, this will not encapsulate, directly open the page to look up the home page rotation id can be – spaceKey
  • Encapsulation to obtain advertising space and its corresponding advertising interface, pass the spaceKey parameter to obtain the advertising list

After the component is created, get the AD list, store the AD list, and use V-for to create the rotation structure

Note: The advertisement has status. If the status is 0, it indicates that the advertisement is removed from the shelves and will not be displayed. Therefore, it is necessary to judge whether the advertisement needs to be displayed when saving the list

The video uses computational attribute filtering, and I think the easiest thing to do is to filter directly when you get the data

Finally, you need to make some style adjustments

SRC/views/course/index. Vue add them by figure < template > < div class = "course" > <! <van-image width="180" : SRC ="require('@/assets/logo.png')" /> <! <van swipe class="my swipe" :autoplay="3000" indicator color="white"> <van swipe class="my swipe" :autoplay="3000" indicator color="white"> <van-swipe-item v-for="item in swipeListDate" :key="item.id"> <img: SRC ="item.img" :alt="item.name"> </van-swipe-item> </van-swipe> <! <footBar/> </div> </template> <script> Import {getAllAds} from '@/ API /course' import footBar from '@/common/foot-bar' export default {import footBar from '@/common/foot-bar' export default { Name: 'Course', data () {return {swipeList: []}}, // Register component components: {footBar}, // Hook function created () {this.getads ()}, methods: Async getAds () {// Call interface const {data} = await getAllAds(999) // Pass data to data this.swipelist = Data.content [0].addtolist}}, // Calculates attributes computed: SwipeListDate () {return this.swipelist.filter (item => item.status === 1)}} </script> <style Lang =" SCSS "scoped> // top logo. van-image {margin-left: -20px; } // van swipe. Van -swipe-item img {width: 100%; height: 200px; } </style>Copy the code
// SRC/API /course

// Introduce encapsulated axios
import axios from './axios'

// Get AD space and corresponding ads according to id
export const getAllAds = spaceKeys= > {
  return axios({
    method: 'get'.url: `/front/ad/getAllAds? spaceKeys=${spaceKeys}`})}Copy the code

Course list basic layout

The course list requires a separate package of components

Use the list component in Vant

SRC/views/course/index. Vue - the introduction of register and use the list component < script > / / introduction course list components import courseList from '/ son/course - list' / / registered components components: { footBar, courseList }</script> <! - to create course list component instance - > < courseList > < / courseList > SRC/views/course/son/course - list. Vue file writing new course list component < template > <! <van-list v-model="loading" :finished="finished" finished-text=" no more "@load="onLoad" > <! -- List item --> <van-cell v-for="item in listData" :key="item" :title="item" /> </van-list> </template> <script> export Default {name: 'courseList', data () {return {finished: false, // False, // listData: [1, 2, 3, 3, 3, 1, 2, 3, 3, 3]}}, methods: {// list bottom refresh event onLoad () {}}} </script>Copy the code

Fixed list processing

List scrolling should not allow the rest of the list to scroll: Set the list to be fixed and vertical to allow scrolling

Because lists may be reused, some style properties may need to be set in the imported component

SRC/views/course/son/course - list. Vue list component set public style < style lang = "SCSS scoped" > / / list positioning. The van - list {position: fixed; left: 0; right: 0; Overflow-y: auto; } </style>Copy the code
SRC/views/course/index. Vue component using the component's father set up private style, so as not to affect the components in the other parent component style < style lang = "SCSS scoped" >... Van-list {top: 260px; bottom: 50px; } </style>Copy the code

Interface encapsulation

Use paging query course information interface (front interface has some problems, use background interface)

The request is made directly in the list component onLoad and the corresponding properties are processed

// SRC/API /course.js encapsulates the course paging query interface

// Query course information in separate pages
export const getQueryCourses = data= > {
  return axios({
    method: 'post'.url: '/boss/course/getQueryCourses',
    data
  })
}
Copy the code

Single course structure layout with data binding

Add the retrieved data to the data in the list

A single list sets structure and style and data binding

SRC/views/course/son/course - list. Writing vue and bind the data structure, adjust the style < template > <! <van-list v-model="loading" :finished="finished" finished-text=" no more "@load="onLoad" > <! <van-cell v-for="item in listData" :key="item.id"> <! - on the left side of the picture - > < img: SRC = "item. CourseImgUrl" Alt = "" > <! - the right information - > < div class = "r" > < h3 > {{item. CourseName}} < / h3 > < p class = "FirstField" > {{item. PreviewFirstField}} < / p > < p > < span Class = "discounts" > selections {{item. Discounts}} < / span > <! - directly using the strikethrough - > < s > selections {{item. Price}} < / s > < / p > < / div > < / van - cell > < / van - list > < / template > < script > / / incoming interface: Import {getQueryCourses} from '@/ API /course' export default {name: 'courseList', data () {return {finished: false, // [], currentPage: 1}}, methods: {// async onLoad () {const {data} = await getQueryCourses({currentPage: this.currentPage, pageSize: 10, status: 1}) console.log(data) if (data.code === '000000') {this.listData.push(... CurrentPage++} this.loading = false if (this.listdata.length >= Data.data.total) {this.finished = true}}}} </script> <style lang=" SCSS "scoped> fixed; left: 0; right: 0; overflow-y: auto; Van-cell. van-cell__value {display: flex; // clear the default effect h3, p {margin: 0; } img { height: 100px; width: 75px; border-radius: 5px; } .r { display: flex; flex-direction: column; margin-left: 10px; .FirstField { flex-grow: 1; } p .discounts { margin-right: 10px; color: #ff7452; } p s { color: #ccc; } } } } </style>Copy the code

The drop-down refresh

The list component provides drop-down refresh cases

Reset parameters and replace data on refresh

Adding a Prompt message

Add judgment information to determine whether data is obtained and not empty before setting data

SRC/views/course/son/course - list. Add drop-down vue refresh function < template > < van - pull - refresh v - model = "refreshing" @ refresh = "onRefresh" > <! <van-list v-model="loading" :finished="finished" finished-text=" no more "@load="onLoad" > <! <van-cell v-for="item in listData" :key="item.id"> <! - on the left side of the picture - > < img: SRC = "item. CourseImgUrl" Alt = "" > <! - the right information - > < div class = "r" > < h3 > {{item. CourseName}} < / h3 > < p class = "FirstField" > {{item. PreviewFirstField}} < / p > < p > < span Class = "discounts" > selections {{item. Discounts}} < / span > <! - directly using the strikethrough - > < s > selections {{item. Price}} < / s > < / p > < / div > < / van - cell > < / van - list > < / van - pull - refresh > < / template > < script > / / Import {getQueryCourses} from '@/ API /course' export default {name: 'courseList', data () {return {finished: false, // [], // listData: [], // listData: [], // listData: 1, // {// Async onRefresh () {// Reset page to 1 this.currentPage = 1 // Change bottom to false this.finished = false // Call interface to get data const { data } = await getQueryCourses({ currentPage: this.currentPage, pageSize: 10, status: If (data.code === '000000' && data.data.records! == 0) {this.listData = data.data.records // page count +1 this.currentPage+ // This $this.$toast(' refresh successfully ')}} Async onLoad () {const {data} = await getQueryCourses({currentPage: this.currentPage, pageSize: 10, status: 1 }) if (data.code === '000000' && data.data.records ! This.listdata.push (...) {this.listdata.push (... CurrentPage++} this.loading = false if (this.listdata.length >= Data.data.total) {this.finished = true}}}} </script> <style lang=" SCSS "scoped> position: fixed; left: 0; right: 0; overflow-y: auto; Van-cell. van-cell__value {display: flex; // clear the default effect h3, p {margin: 0; } img { height: 100px; width: 75px; border-radius: 5px; } .r { display: flex; flex-direction: column; margin-left: 10px; .FirstField { flex-grow: 1; } p .discounts { margin-right: 10px; color: #ff7452; } p s { color: #ccc; } } } } </style>Copy the code