– introduction

This article is about building an 8080 Apple Theater with vue3.0 framework from scratch. From the front end, relatively basic back-end, simple performance optimization and the project in the server deployment online four aspects.

– Preparation

We need the following tools and component libraries:

  1. [vscode](Visual Studio Code – Code Editing. Redefined)
  2. [navcat] (Navicat | support MySQL and MariaDB, directing, SQL Server, SQLite, Oracle, and database management of PostgreSQL)
  3. [Vant component Library](Vant – Lightweight, reliable mobile Component Library (Giee.io))
  4. [Element-plus] install – Element Plus Help document
  5. Alibaba Vector icon library
  6. express

– Project directory structure

1. The front end

The following describes the directory structure of the project. The main interface contains the following 10 items.

2. The back end

The back-end data acquisition is 14 fast modules respectively

– Concrete implementation

First, front-end implementation

Now on to the front end, we need to know how to achieve the best results with the least amount of code. Consider components reuse, CSS preprocessor selection, and logic code reuse. Especially important is the reuse of components, VUE framework itself is component responsive development, reasonable use of components is king. Second, THE CSS preprocessor I use is less.

1. Component analysis

From the recurring components in the renderings above, it is clear that the following components are being reused

The following is an analysis of the more difficult components:

  1. 1 head header. Vue

The logo part is generated by [calcium network](free online production of logo- font LOGO – LOGO design -U calcium network (uugai.com)) for free. The ICONS on the right part refer to the ICONS of Alibaba Vector library. Introduction method: in the public directory under the index. HTML online to introduce their own Alibaba vector library online address

The next navigation bar is a simple flex layout, with a router-link tag by default and a router-link-Active on the first click. Let’s set the following styles and let’s do it

.router-link-active {
    color: #FDC81F;
    text-decoration: none;
}
.router-link-active::after{
    content: "Low";
    color: #FDC81F;
    position: absolute;
    top: 14px;
    left: 12px;
}
Copy the code

1.2 Video picture List list.vue

This component has the highest reuse, movies, anime, variety, home page, series, video details and video playback page have this component, we just need to distinguish the difference between them.

We just need to accept the following parameters

props:{
        isDetial: {// Click on the List of details page to jump or details page, so you need to distinguish details data
            type:Boolean.default:false
        },
        isHome: {// The home page has a title and more, so you need this field
            type:Boolean.default:true
        },
        title: {// Home page title field
            type:String.default:' '
        },
        Data: {Vue3 = vue3 = vue3 = vue3 = vue3 = vue3
            type:Array.default:() = >{ return[]}},link: {// More > the route path to the jump page
            type:String.default:' '}},Copy the code

1.3 Classification menu Meun. Vue and pagination. Vue

Implementation function: there is a click classification list will appear different video picture data and paging statistics, click paging can see different video picture data.

First of all, the category menu is scrolled by using the Vant component’s Tab Tab (Tab Tab – vant (Giee.io)) Tab bar. You’ll be curious how the Vant component looks like this, which is a little different from mine.

Yes, the styles of Vant components can be changed in vUE, but remember that you can only change them once, because Vue CSS styles are scoped, and changing one will affect the other, so we usually only use them once, and reusability is preferred.

Here is how to modify the style of vUE UI framework:

  • Change the style according to the document’s add properties

  • Use your browser to open and examine the element to find its own class to change its style

Note: you cannot add the scoped attribute to the CSS section, and it will not apply to the Vant component.

Second, paging is done using the Element-Plus UI framework. Style is also through the above method two magic change. You may wonder why you need to use both frameworks, instead of using the Vant component library directly, or using Element-UI instead. Element-ui is really not bug-compatible with VUE3. Using vant library directly requires too few style components, and Pagination of Vant library is really not suitable for this site. At this point, you’re probably wondering how to reference both components.

The following code needs to be copied in babel.config.js

module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset',]."plugins": [["import", {
      "libraryName": "vant"."libraryDirectory": "es"."style": true
    }],
      [
        "component",
        {
          "libraryName": "element-plus"."styleLibraryName": "theme-chalk"}}]]Copy the code

1.4 History History.vue

Just click Play to save the local cache in the browser. Click the history icon to retrieve the local cache of watched movie information.

  • Click Play to put it into browser local storage
const  history = async() = > {// This is a click-play video event
            let href = router.currentRoute.value.params.id

            let data = await localStorage.getItem('movietitle')// Get the local store as movieTitle
            if(data! = =null) {
                //console.log(JSON.parse(data));
                state.historyData = JSON.parse(data)// If it is not empty, just fetch it first
            }
            if (state.historyData.find(v= > v.title === state.title)===undefined) {// If the click does not exist, push it and store it again with localstorage.setitem ()
                let MovieData = {
                    href:href,
                    title:state.title
                }
                state.historyData.push(MovieData)
                await localStorage.setItem('movietitle'.JSON.stringify(state.historyData))
            }
        }
Copy the code
  • Click the History icon to get local storage
const getHistory = async() = > {let data = await localStorage.getItem('movietitle')// Get local storage
      if(data! = =null) {// Fetch the browser local store if it is not empty
        state.history = JSON.parse(data)
      }
    }
Copy the code
2. Page logic analysis
  1. 1 Child and parent components Pass values and call methods of components
// In Vue3.0 // parent component<template>
    <v-child @refesh="refesh"></v-child>< span style = "max-width: 100%; clear: both;</template>
<script>
import child from '@/components/child.vue'
export default {
    components: {"v-child":child
    }
    setup(){
        const refesh = () = >{// Method of the parent component
            axios.get('url').then(res= >{
                / /... Requests for data alter the data on the page})}return{
            refesh
        }
    }
}
</script>// Child component child.vue<template>
    <button @click="update"></button>
</template>
<script>
import child from '@/components/child.vue'
emits: ['refesh'].// Notice that the method calling the parent component needs to be received with emits, otherwise an error is reported
export default {
    setup(props,context){//setup the second argument is context
        const update = (parms) = >{// Subcomponent methods
            context.emit('refesh',params)
        }
        return{
            update
        }
    }
}
</script>

Copy the code

The example above is a simple example of a child component passing a value to its parent, which is exactly what the child component does in this project. Vue for detail page and Pagination. Vue for Pagination. Vue is related to the above value transfer mode.

2.2 Interaction between main pages

When the main page component interacts, the route must jump. We should know the way of route parameter transmission. Next, we will explain the method of interaction of this project in the way of code example.

The first uses the useRouter method of vue-Router

/ / A page
import { useRouter } from 'vue-router'
export default {
    setup(){
        const router = useRouter()
        const toB = () = >{
            router.push(name:'B'.params: {})/ / params refs
            / / router. Push (path: '/' B, query: {}) / / query parameter
            //router.push(path: '/B${parameter}')// Route parameters
        }
        return {
            toB
        }
    }
}
B / / page
import { useRouter } from 'vue-router'
export default {
    setup(){
        const router = useRouter()
        const getData = () = >{// Use the useRouter method to get data
            let href = router.currentRoute.value.params.id
            //let href = router.currentRoute.value.query.id
            axios.get(`url/${href}`).then(res= >{
                // Get data by passing different values to the back end})}return {
            getData
        }
    }
}
Copy the code

The second route guard, onBeforeRouteUpdate, listens for route changes

import {onBeforeRouteUpdate} from 'vue-router'
export default {
    const refesh = () = >{
        axios.get('url').then(res= >{
            // Change the page data
        })
    }
    onBeforeRouteUpdate( to= >{

          refesh()// Call the method to refresh data when the route changes

          console.log(to.params, to.query)

       })
	return {
        refesh
    }
}
Copy the code

Second, back-end implementation

Finally came to the back end, the back end of this site uses express engine template and Node crawler to get data, connect to the local mysql database. This part is very important for the front end, not only stay in the cut page, but write their own logic, write their own interface. Of course, this project deals with the basics of the back-end, so let’s get to the topic.

1. Express template format

Back-end entry file code

var express = require('express');
var app = express();

app.all(The '*'.function (req, res, next) {// make a cross-domain request
    res.header('Access-Control-Allow-Origin'.The '*');
    res.header('Access-Control-Allow-Headers'.'Content-Type');
    res.header('Access-Control-Allow-Methods'.The '*');
    res.header('Content-Type'.'application/json; charset=utf-8');
    next();
});

app.get('route', method)/ / case
app.get('/lunbo',lunbo);



app.listen(4000.function () {
    console.log('app is listenling at port 4000');
});
Copy the code

Method to manipulate code examples

/ / the node crawler
var superagent = require('superagent');
var cheerio = require('cheerio');// Operation page

exports.lunbo = function (req, res, next) {
    console.log(req.url);
    superagent.get(`url`)
        .end(function (err, sres) {
            if (err) {
                return next(err);
            }
        	// sres.text stores the HTML content of the web page and passes it to cheerio.load
            // You get a variable that implements the jquery interface, which we habitually call '$'
            // The rest is jquery
        	var $ = cheerio.load(sres.text);// Operation page
        	// The following is the jQuery syntax to extract page data
            $('.carousel-inner .item img').each(function (index, element) {
                var $element = $(element);
                items.push({
                    title:$element.attr('alt'),
                    src: $element.attr('src')}); }); res.send(items); }}Copy the code

Results show

The front end can get data through AXIos in two ways

The first, Axios, requests directly

axios.get('http://localhost:4000/lunbo').then(res= >{
// Get the above data
})
Copy the code

The second proxy request

axios.get('api/lunbo').then(res= >{
// Get the above data
})
Copy the code
// Create vue.config.js in the root directory of the project
module.exports = {
    / /...
    devServer: {
      proxy: {
        '/api': {
            target: 'http://localhost:4000/'.changeOrigin: true.ws: true.pathRewrite: {
                '^/api': ' '}}}}};Copy the code

The above two ways depend on personal preferences, the first must need to do cross-domain processing of back-end entry files.

2. Mysql database module analysis

Config file config.js

//config.js
module.exports = {
    port: 4000.// Express service startup port
    /* Database configuration */
    db: {
      host: 'localhost'./ / host name
      port: 3306.// The default MySQL port is 3306
      user: 'root'.// Log in to MySQL as user root
      password: '123'.// MySQL password, use your own
      database: 'message' // Use your own database}}Copy the code

Database instance module db.js

const mysql = require('mysql')

const config = require('./config').db // Get database configuration information

module.exports = mysql.createConnection(config) The mysql.createconnection method creates a connection instance

Copy the code

Database operation module

const connection = require('./db') // Get the connection instance

exports.message = function (req, res, next) {
    console.log(req.query);
    var insertsql = 'INSERT INTO comments(content,time) VALUES(? ,?) '
    connection.query(insertsql, [req.query.content,req.query.time],(err, result, fields) = > {// Insert data operation
        if (err) { 
            console.log('INSERT ERROR - ', err.message);
            throw err
        }
        console.log("INSERT SUCCESS");
    })
    connection.query('select * from comments'.(err, comments) = > {// Query operation
        if (err) {
          res.send('query error')}else {
          // use MySQL query result as route return value
          res.send(comments)
        }
    })
}

Copy the code

We can see the following result under the Message route

3. Create table with navcat

Visual tools, foolproof operation. There is no visual tool on the server, this is a mysql command line operation OK. Do not remember to check online ~

Now this talk about the back end seems not very difficult, easy to write interface, operation database, in fact, the front end is able to complete some of these. So here we have the 8080 Apple Theater.

– Performance optimization

1. Lazy route loading

We usually use the first method. In this way, all interfaces are loaded back at the beginning of the home interface. If the server responds slowly, the rendering of the first screen will be slow and take too long, which will lead to poor user experience.

import Home  from '@/views/Home.vue'
import B  from '@/views/B.vue'
/ /...
const routes = [
    {
        path: '/home'.name: 'home'.component: Home
    },
    {
        path: '/b'.name: 'b'.component: B
    },
    / /...
]
Copy the code

This is where we should use route lazy loading to speed up the first screen rendering.

const routes = [
    {
        path: '/a',
        name: 'a',
        component: () => import('../views/A')
    },
    {
        path: '/b',
        name: 'b',
        component: () => import('../views/B')
    },
]

Copy the code
2. Comment the console print code

We wrote a lot of consle.log() prints during the course of the project, which was fine during development, but when going live, printing these useless data back to the console would undoubtedly strain the server and browser, which would consume performance. So, print code comments on all consoles when you go live.

– Server deployment

Come to this stage, first we need to rent a server in Tencent cloud or Ali cloud, I recommend the use of pagoda remote control server, see [installation tutorial](jianshu.com pagoda panel installation tutorial), and some operation tutorials. Pretend your friends have already installed the pagoda and see the following screen

Enter the terminal installation node environment, take a look at the server Installation Node tutorial (coder_zyz – cnblogs.com), and now enter the topic of server deployment.

1. Back-end deployment

Open the firewall first

  1. Install the PM2 project Manager
npm i pm2 -g
Copy the code
  1. Drag the written back end into the server

  1. Go to the backend folder to run the backend
Pm2 start server.js// import fileCopy the code

Two, front-end deployment

First, connect the back end. If the proxy is used, that is, configure vue.config.js and change the API proxy in the code into the public address of the server. Otherwise, dist won’t recognize the configuration of vue.config.js after packaging and can’t connect to the back end.

  1. Install express under global installation
npm i express -g
Copy the code
  1. Create a project with Express
express myApp
Copy the code

Open the Express project and you can see the following directory structure

  1. Enter the front-end project folder to pack and you will find an additional dist folder.
npm run build
Copy the code

  1. Place the contents of the packaged Dist folder in public under the myApp folder created by server Express

  1. Enter the myApp file to run the packaged front end
pm2 start app.js
Copy the code
  1. View project running status from the command line
pm2 list
Copy the code

The above figure indicates that status is online and the front and back ends are running.

Enter your public IP address 3000. The following information is displayed: The project is online successfully.

– summary

Vue3 project front-end parent component interaction props value, emits call method of the parent component, component reuse can write a good front-end interface. This project back-end superagent and Cheerion package node crawler write interface plus a little database. Writing the back end depends on which language you’re using and which framework provides better convenience, whether you’re writing big projects or database operations, something deeper. Performance optimization is often referred to as the problem of writing code, and the performance of removing useless code items can vary greatly depending on how you choose to introduce them. Server deployment only needs to be learned once, and with the foundation of the previous three parts, your project will go live quickly.

Ps: This project [warehouse address](Xiaofeng -movie-server: Gitee.com)