Vue e e-commerce practice project

Posted by cornercuttinjoe on Thu, 24 Feb 2022 10:40:08 +0100

Today's goal

1. Be able to say what is routing 2. Be able to tell the implementation principle of front-end routing 3. Be able to use Vue router to realize front-end routing 4. Be able to realize nested routing and dynamic routing 5. Be able to realize named routing and programmed navigation 6. Understand and implement background management cases

1. Concept of routing

The essence of routing is a correspondence. For example, after we enter the url address we want to visit in the url address, the browser needs to request the resource corresponding to the url address. Then there is a corresponding relationship between the url address and the real resource, that is, routing.

Routing is divided into front-end routing and back-end routing 1). The back-end routing is implemented by the server and completes the distribution of resources 2). Front end routing depends on the change of hash value (anchor link)

The performance of back-end routing is lower than that of front-end routing. Therefore, we mainly study front-end routing next The basic concept of front-end Routing: display different page contents according to different events, that is, the corresponding relationship between events and event handling functions The main task of front-end routing is to listen to events and distribute and execute event handling functions

2. Initial experience of front-end routing

Front end routing is implemented based on the change of hash value (for example, click the menu or button in the page to change the hash value of URL, and control the switching of components according to the change of hash value) The core implementation relies on one event, that is, the event that monitors the change of hash value

window.onhashchange = function(){
    //location.hash can get the latest hash value
    location.hash
}

Front end routing enables tab bar switching:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Document</title>
        <!-- Import vue file -->
        <script src="./lib/vue_2.5.22.js"></script>
    </head>
    <body>
        <!-- cover vue Instance controlled div region -->
        <div id="app">
        <!-- Toggle component hyperlinks -->
        <a href="#/Zhuye "> Home Page</a> 
        <a href="#/Keji "> Technology</a> 
        <a href="#/Caijing "> Finance</a>
        <a href="#/Yule "> Entertainment</a>

        <!-- according to :is Property to render the corresponding component to component Location of the label -->
        <!-- Can put component The label is used as a placeholder for the component -->
        <component :is="comName"></component>
        </div>

        <script>
        // #region defines the four components that need to be switched
        // Home page component
        const zhuye = {
            template: '<h1>Home page information</h1>'
        }

        // Technology components
        const keji = {
            template: '<h1>Scientific and technological information</h1>'
        }

        // Financial components
        const caijing = {
            template: '<h1>Financial information</h1>'
        }

        // Entertainment components
        const yule = {
            template: '<h1>Entertainment information</h1>'
        }
        // #endregion

        // #region vue instance object
        const vm = new Vue({
            el: '#app',
            data: {
            comName: 'zhuye'
            },
            // Register private components
            components: {
            zhuye,
            keji,
            caijing,
            yule
            }
        })
        // #endregion

        // Listen to the onhashchange event of window and switch the name of the component to be displayed according to the latest hash value obtained
        window.onhashchange = function() {
            // Via location Hash get the latest hash value
            console.log(location.hash);
            switch(location.hash.slice(1)){
            case '/zhuye':
                vm.comName = 'zhuye'
            break
            case '/keji':
                vm.comName = 'keji'
            break
            case '/caijing':
                vm.comName = 'caijing'
            break
            case '/yule':
                vm.comName = 'yule'
            break
            }
        }
        </script>
    </body>
    </html>

Case rendering:

[the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-vvzqooooa-1582445784482) (images / 01 front-end routing. png)]

After clicking each hyperlink, the corresponding content will be switched as follows:

[the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-sVZNjd7o-1582445784482)(images/01 front-end routing effect picture. png)]

Core idea: There is a vue instance object in the page. There are four components in the vue instance object, which are the components to be displayed in the tab bar There are four hyperlinks in the page, as follows:

<a href="#/Zhuye "> Home Page</a> 
<a href="#/Keji "> Technology</a> 
<a href="#/Caijing "> Finance</a>
<a href="#/Yule "> Entertainment</a>

When we click these hyperlinks, the hash value in the url address will be changed. When the hash value is changed, the onhashchange event will be triggered When the onhashchange event is triggered, we make different components display according to the hash value:

window.onhashchange = function() {
    // Via location Hash get the latest hash value
    console.log(location.hash);
    switch(location.hash.slice(1)){
        case '/zhuye':
        //Specify the displayed components by changing the data comName
        //Because < component: is = "comName" > < / component >, the component has been bound with comName
        vm.comName = 'zhuye'
        break
        case '/keji':
        vm.comName = 'keji'
        break
        case '/caijing':
        vm.comName = 'caijing'
        break
        case '/yule':
        vm.comName = 'yule'
        break
    }
}

###3. Introduction to Vue router It is a Vue JS official route manager. It is a more powerful front-end router, which is recommended. Vue Router and Vue JS fits very well and can easily realize the development of SPA(single page web application) application together. Vue Router depends on Vue, so you need to import Vue first and then Vue Router

Characteristics of Vue Router: Support H5 history mode or hash mode Support nested routing Support routing parameters Support programmatic routing Support named routing Support routing navigation guard Support routing transition animation effects Support lazy loading of routes Support routing scrolling behavior

4. Use steps of Vue router (★★★)

A. Import js file

B. Add route link: it is the label provided in the route. It will be rendered as a label by default, and the to attribute will be rendered as href attribute by default, The value of the to attribute is rendered as a # starting hash address User Login C. Add route padding bit (route placeholder) D. Define routing components var User = { template:"

This is User

" }

var Login = { template:"

This is Login

" }

E. Configure routing rules and create routing instances

var myRouter = new VueRouter({

//routes is an array of routing rules

routes:[

//Each routing rule is an object, which contains at least two attributes: path and component

//path indicates the hash address matched by the route, and component indicates the component object corresponding to the route rule to be displayed

{path:"/user",component:User},

{path:"/login",component:Login}

]

})

F. Mount routes to Vue instances

new Vue({

el:"#app",

//Mount the routing object through the router property

router:myRouter

})

Summary: The use steps of Vue Router are relatively clear. You can complete the routing operation step by step A. Import js file B. Add routing link C. Add a route placeholder (the components shown in the last route will be displayed in the placeholder) D. Define routing components E. Configure routing rules and create routing instances F. Mount routes to Vue instances

Supplement: Route redirection: you can set the default displayed components for the page through route redirection Add a routing rule to the routing rule, as follows: var myRouter = new VueRouter({ //routes is an array of routing rules routes: [ //Set path to / to indicate the initial address of the page /, and redirect to indicate the new address to be redirected. Set it as a route { path:"/",redirect:"/user"}, { path: "/user", component: User }, { path: "/login", component: Login } ] })

5. Nested routing, implementation of dynamic routing

A. Concept of nested routing (★★★)

When we route, there are new child routing links and contents in the displayed components.

The key code of nested routing is to understand the concept of child Routing: For example, we have a / login route You can also add child routes under / login, such as: /login/account /login/phone

Reference codes are as follows:

var User = { template: "<div>This is User</div>" }
//The template code in the Login component contains child route links and placeholders for child routes
    var Login = { template: `<div>
        <h1>This is Login</h1>
        <hr>
        <router-link to="/login/account">Account password login</router-link>
        <router-link to="/login/phone">Code scanning login</router-link>
        <!-- The sub routing component will router-view Display in -->
        <router-view></router-view>
        </div>` }

    //Define two child routing components
    var account = { template:"<div>account number:<input><br>password:<input></div>"};
    var phone = { template:"<h1>Scan my QR code</h1>"};
    var myRouter = new VueRouter({
        //routes is an array of routing rules
        routes: [
            { path:"/",redirect:"/user"},
            { path: "/user", component: User },
            { 
                path: "/login", 
                component: Login,
                //Add a sub routing rule for / login through the children attribute
                children:[
                    { path: "/login/account", component: account },
                    { path: "/login/phone", component: phone },
                ]
            }
        ]
    })

    var vm = new Vue({
        el: '#app',
        data: {},
        methods: {},
        router:myRouter
    });

The page effect is roughly as follows:

[the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-jET0XBWO-1582445784483)(images/03 nested routing. png)]

B. Dynamic route matching (★★★)

var User = { template:"

User:

"}

var myRouter = new VueRouter({ //routes is an array of routing rules routes: [ //Pass the parameter in the form of /: parameter name { path: "/user/:id", component: User },

]

})

Supplement: If you use $route params. ID to obtain the data of path parameters is not flexible enough. 1. We can receive parameters through props var User = { props:["id"], template:"

User: {{id}}

"

}

var myRouter = new VueRouter({ //routes is an array of routing rules routes: [ //Pass the parameter in the form of /: parameter name //If props is set to true, route Params will be set as the component property { path: "/user/:id", component: User,props:true },

]

})

2. In another case, we can set props as an object, and then directly transfer the object's data to Components for use var User = { props:["username","pwd"], template:"

User: --

"

}

var myRouter = new VueRouter({ //routes is an array of routing rules routes: [ //Pass the parameter in the form of /: parameter name //If props is set as an object, the data in the object is passed to the component { path: "/user/:id", component: User,props:{username:"jack",pwd:123} },

]

})

3. If you want to get the passed parameter value and the passed object data, props should be set to Function form. var User = { props:["username","pwd","id"], template:"

User: {ID}} - > {username}} - {{pwd}}

"

}

var myRouter = new VueRouter({ //routes is an array of routing rules routes: [ //Pass the parameter in the form of /: parameter name //If props is set as a function, the routing object is obtained through the first parameter of the function //The parameters passed can be obtained through the params attribute of the routing object // { path: "/user/:id", component: User,props:(route)=>{ return {username:"jack",pwd:123,id:route.params.id} } },

]

})

7. Named routing and programmed navigation

A. Named route: alias the route

Case:

var myRouter = new VueRouter({ //routes is an array of routing rules routes: [ //Add an alias for the route through the name attribute { path: "/user/:id", component: User, name:"user"},

]

})

//After adding an alias, you can use the alias to jump User User

//Programmable navigation is also possible myRouter.push( { name:'user' , params: {id:123} } )

B. Programming navigation (★★★)

There are two ways of page navigation: A. Declarative navigation: navigation by clicking on links B. Programming navigation: call the api method of js to realize navigation

Common navigation mode in Vue Router: this router. Push ("hash address"); this.router.push(“/login”); this.router.push({ name:’user’ , params: {id:123} });this.router.push({ path:”/login” }); this.

this.router.go( n );//n is a number, refer to history gothis. router. go( -1 );

8. Implementation of background management cases (★★★)

Case effect:

[the external chain image transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-X4HJNENz-1582445784483)(images/02 background management system. png)]

Click "user management", "permission management", "commodity management", "order management" and "system setting" on the left to display the corresponding components and contents

The effect of the "user management" component is shown in the figure above. The details link in the user management area can also be clicked. After clicking, the user details will be displayed.

Case ideas: 1). First put 11. 0 in the material folder Case based on Vue router Copy html to our own folder. Take a look at what the code in this file has written, This page has realized the basic layout of the background management page 2). Introduce vue and vue router into the page 3). Create the Vue instance object and prepare to write code to realize the function 4). It is hoped that the main content of the page is displayed in the form of components rather than dead page structure, so we can define a root component:

//Just set the html code in the original page as the template content in the component
const app = {
    template:`<div>
        <!-- Head area -->
        <header class="header">Intelligent background management system</header>
        <!-- Middle main area -->
        <div class="main">
          <!-- Left menu bar -->
          <div class="content left">
            <ul>
              <li>user management </li>
              <li>Authority management</li>
              <li>Commodity management</li>
              <li>Order management</li>
              <li>System settings</li>
            </ul>
          </div>
          <!-- Right content area -->
          <div class="content right">
            <div class="main-content">Add user form</div>
          </div>
        </div>
        <!-- tail area  -->
        <footer class="footer">Copyright information</footer>
      </div>`
  }

5). When we need to create an app, we can access it by default Create a routing object to do this, and then mount the route into the Vue instance object

const myRouter = new VueRouter({
    routes:[
        {path:"/",component:app}
    ]
})

const vm = new Vue({
    el:"#app",
    data:{},
    methods:{},
    router:myRouter
})

Add: so far, the basic js code has been processed, and we need to set a route placeholder

<body>
  <div id="app">
    <router-view></router-view>
  </div>
</body>

6). At this point, when we open the page, we should get a root component routed by vueroter We need to continue routing in this root component to implement other functional subcomponents First, let's change the template in the root component: change the li on the left to a child routing link, and add a child component placeholder in the content area on the right

const app = {
    template:`<div>
        ........
        <div class="main">
          <!-- Left menu bar -->
          <div class="content left">
            <ul>
              <!-- Note: we put all li Are modified to route links -->
              <li><router-link to="/users">user management </router-link></li>
              <li><router-link to="/accesses">Authority management</router-link></li>
              <li><router-link to="/goods">Commodity management</router-link></li>
              <li><router-link to="/orders">Order management</router-link></li>
              <li><router-link to="/systems">System settings</router-link></li>
            </ul>
          </div>
          <!-- Right content area -->
          <div class="content right">
            <div class="main-content">
                <!-- stay -->
                <router-view></router-view> 
            </div>
          </div>
        </div>
        .......
      </div>`
  }

Then, we will create and set up the child components to be displayed for the child route

//It is recommended to create components that are capitalized to distinguish them from other contents
const Users = {template:`<div>
    <h3>user management </h3>
</div>`}
const Access = {template:`<div>
    <h3>Authority management</h3>
</div>`}
const Goods = {template:`<div>
    <h3>Commodity management</h3>
</div>`}
const Orders = {template:`<div>
    <h3>Order management</h3>
</div>`}
const Systems = {template:`<div>
    <h3>system management</h3>
</div>`}

//Add routing rules for subcomponents
const myRouter = new VueRouter({
    routes:[
        {path:"/",component:app , children:[
            { path:"/users",component:Users },
            { path:"/accesses",component:Access },
            { path:"/goods",component:Goods },
            { path:"/orders",component:Orders },
            { path:"/systems",component:Systems },
        ]}
    ]
})

const vm = new Vue({
    el:"#app",
    data:{},
    methods:{},
    router:myRouter
})

7). Display user information list: A. Add private data for the Users component and display the private data in a circular way in the template ​const Users = { data(){ return { userList:[ {id:1,name:"zs",age:18}, {id:2,name:"ls",age:19}, {id:3,name:"wang",age:20}, {id:4,name:"jack",age:21}, ] } }, Template: ` < div > < H3 > user management < / H3 > < Table > < thead > < tr > < th > number < / th > < th > name < / th > < th > age < / th > < th > operation < / th > < / TR > < / thead > < tbody > < tr: key = "item. ID" V-for = "item in userlist" > < td > < / td > < td > < td > < td > < td > < a href = "javascript:;" > Details < / a > < / td > < / TR > < / tbody > < / Table > < / div > `}

8. After the user list is displayed, we can click the details in the list to display the user details. First, we need to create a component to display the details

const UserInfo = {
    props:["id"],
    template:`<div>
      <h5>User details</h5>
      <p>see {{id}} No. user information</p>
      <button @click="goBack">Return to user details page</button>
    </div> `,
    methods:{
      goBack(){
        //When the user clicks the button, it goes back one page
        this.$router.go(-1);
      }
    }
  }

Then we need to set the routing rules of this component

const myRouter = new VueRouter({
    routes:[
        {path:"/",component:app , children:[
            { path:"/users",component:Users },
            //Add a routing rule for / userinfo
            { path:"/userinfo/:id",component:UserInfo,props:true},
            { path:"/accesses",component:Access },
            { path:"/goods",component:Goods },
            { path:"/orders",component:Orders },
            { path:"/systems",component:Systems },
        ]}
    ]
})

const vm = new Vue({
    el:"#app",
    data:{},
    methods:{},
    router:myRouter
})

Then add an event to the detail a connection in the user list

const Users = {
    data(){
        return {
            userList:[
                {id:1,name:"zs",age:18},
                {id:2,name:"ls",age:19},
                {id:3,name:"wang",age:20},
                {id:4,name:"jack",age:21},
            ]
        }
    },
    template:`<div>
        <h3>user management </h3>
        <table>
            <thead>
                <tr>
                    <th>number</th>
                    <th>full name</th>
                    <th>Age</th>
                    <th>operation</th>
                </tr>
            </thead>
            <tbody>
                <tr :key="item.id" v-for="item in userList">
                    <td>{{item.id}}</td>
                    <td>{{item.name}}</td>
                    <td>{{item.age}}</td>
                    <td><a href="javascript:;" @click="goDetail(item.id)">details</a></td>
                </tr>
            </tbody>
        </table>
    </div>`,
    methods:{
        goDetail(id){
            this.$router.push("/userinfo/"+id);
        }
    }
}

Today's goal

1. Be able to understand the relevant specifications of modularization 2. Understand webpack 3. Understand the use of Vue single file components 4. Be able to build Vue scaffold 5. Master the use of element UI

1. Modular classification

A. Browser side modularization

    1).AMD(Asynchronous Module Definition,Asynchronous module definition)
    Representative products are: Require.js
    2).CMD(Common Module Definition,General module definition)
    Representative products are: Sea.js

B. Server side modularization

    The modular specification of the server side is to use CommonJS standard:
    1).use require Introduce other modules or packages
    2).use exports perhaps module.exports Export module members
    3).A file is a module with independent scope

C.ES6 modularization

    ES6 Defined in modular specification:
        1).every last js Files are independent modules
        2).Import module member usage import keyword
        3).Exposed module members export keyword

Summary: ES6 modularization is recommended because AMD and CMD are limited to the browser side, while CommonJS is used on the server side. ES6 modularization is a common specification for browser and server

2. Install babel in NodeJS

A. Install babel

Open the terminal and enter the command: npm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/node
 After installation, enter the command again: npm install --save @babel/polyfill

B. Create Babel config. js

Create in project directory babel.config.js Documents.
edit js The code in the file is as follows:
    const presets = [
        ["@babel/env",{
            targets:{
                edge:"17",
                firefox:"60",
                chrome:"67",
                safari:"11.1"
            }
        }]
    ]
    //expose
    module.exports = { presets }

C. Create index JS file

Create in project directory index.js File as entry file
 stay index.js Enter the to be executed in js Code, for example:
    console.log("ok");

D. Using npx to execute files

Open the terminal and enter the command: npx babel-node ./index.js

3. Set default import / export

A. Default export

export default {
    member A,
    member B,
    .......
},As follows:
let num = 100;
export default{
    num
}

B. Default import

import Receiving name from "Module identifier",As follows:
import test from "./test.js"

Note: in a module, you can only use export default to expose members by default once. Do not write multiple export defaults. If there are no exposed members in a module, other modules will get an empty object when introducing the module

###4. Set up on-demand import / export ####A. Export on demand export let num = 998; export let myName = "jack"; export function fn = function(){ console.log("fn") } ####B. Import on demand import { num,fn as printFn ,myName } from "./test.js" //Import both default exported members and on-demand imported members import test,{ num,fn as printFn ,myName } from "./test.js" Note: a module can be imported on demand or by default, and a module can be exported on demand or by default

5. Import and execute code directly

import "./test2.js";

6. Concept of webpack

webpack is a popular front-end project construction tool, which can solve the current dilemma of web development. webpack provides modularization support, code compression confusion, solving js compatibility problems, performance optimization and other features, which improves the development efficiency and maintainability of the project

###7. Basic use of webpack ####A. Create project directory and initialize Create a project, open the terminal of the directory where the project is located, and enter the command: npm init -y ####B. Create home page and js file Create index. In the project directory HTML page and initialize the page structure: put a ul in the page and several li in the ul Create the js folder in the project directory, and create the index js file

C. Install jQuery

Open the project directory terminal and enter the command:
npm install jQuery -S

D. Import jQuery

open index.js File, write code, import jQuery And realize the following functions:
import $ from "jquery";
$(function(){
    $("li:odd").css("background","cyan");
    $("li:odd").css("background","pink");
})

Note: at this time, the project will run with errors, because import $from "jquery"; This code belongs to the new syntax code of ES6, and there may be compatibility problems in browsers So we need webpack to help us solve this problem.

E. Install webpack

1).Open the project directory terminal and enter the command:
npm install webpack webpack-cli -D
2).Then, in the project root directory, create a webpack.config.js The configuration file is used to configure webpack
 stay webpack.config.js Write code in the file webpack Configuration, as follows:
module.exports = {
    mode:"development"//It can be set to development mode and production mode
}
Supplement: mode Set the compilation mode of the project.
If set to development It means that the project is in the development stage, will not be compressed and confused, and the packaging speed will be faster
 If set to production It means that the project is in the online publishing stage, which will be compressed and confused, and the packaging speed will be slower
3).Modify in project package.json File add run script dev,As follows:
"scripts":{
    "dev":"webpack"
}
be careful: scripts The script under the node can be npm run Operation, such as:
Run terminal command: npm run dev
 Will start webpack Package the project
4).function dev Command to package the project, and the generated by project packaging is introduced into the page js file
 Open the project directory terminal and enter the command:
npm run dev
 wait for webpack After packaging, find the default dist Generated in path main.js File and import it into html Page.
Browse the page to see the effect.

8. Set the packaging entrance / exit of webpack

stay webpack 4.x In, the default is src/index.js As the default packaging entry js file
                 By default dist/main.js As the default packaged output js file
 If you don't want to use the default entry/Export js File, we can change webpack.config.js To set the entry/Exportable js Documents, as follows:
const path = require("path");
module.exports = {
    mode:"development",
    //Set entry file path
    entry: path.join(__dirname,"./src/xx.js"),
    //Set export file
    output:{
        //set up path
        path:path.join(__dirname,"./dist"),
        //Set file name
        filename:"res.js"
    }
}

9. Set the automatic packaging of webpack

By default, we change the entry js The code of the file needs to be packaged by rerunning the command webpack,To generate an exit js file
 It is a very tedious task to re execute command packaging every time. Then, automatic packaging can solve such tedious operations.
The steps to realize the automatic packaging function are as follows:
    A.Packages with automatic packaging installed:webpack-dev-server
        npm install webpack-dev-server -D
    B.modify package.json Medium dev The instructions are as follows:
        "scripts":{
            "dev":"webpack-dev-server"
        }
    C.To be introduced js Change the file path to:<script src="/bundle.js"></script>
    D.function npm run dev,Packaging
    E.Open the URL to view the effect: http://localhost:8080

be careful: webpack-dev-server Automatically packaged output files are placed in the root directory of the server by default.

Supplement: After automatic packaging, the server web page is opened by default. The implementation method is to open package JSON file, modify dev command: "dev": "webpack-dev-server –open –host 127.0.0.1 –port 9999"

10. Configure HTML webpack plugin

use html-webpack-plugin A preview page can be generated.
Because when we access the default http://When localhost:8080 /, you see some files and folders. You want to view our page
 You also need to click the folder and click the file to view, so we hope to see a page by default, rather than a folder or directory.
The steps to realize the function of default preview page are as follows:
    A.Package that installs the default preview feature:html-webpack-plugin
        npm install html-webpack-plugin -D
    B.modify webpack.config.js Documents, as follows:
        //Import package
        const HtmlWebpackPlugin = require("html-webpack-plugin");
        //create object
        const htmlPlugin = new HtmlWebpackPlugin({
            //Set the template file that generates the preview page
            template:"./src/index.html",
            //Sets the name of the generated preview page
            filename:"index.html"
        })
    C.Continue to modify webpack.config.js Files, adding plugins Information:
        module.exports = {
            ......
            plugins:[ htmlPlugin ]
        }

11. Loader in webpack

adopt loader Packing non js Module: by default, webpack Can only be packaged js File, if you want to package non js File, need to call loader Loader to package
    loader The loader contains:
        1).less-loader
        2).sass-loader
        3).url-loader:Packaging processing css Zhongyu url Path related files
        4).babel-loader:Processing advanced js Syntax loader
        5).postcss-loader
        6).css-loader,style-loader

Note: specify multiple loader When the order is fixed, and call loader The sequence of calls is from back to front

A.install style-loader,css-loader To process style files
    1).Installation package
        npm install style-loader css-loader -D
    2).Configuration rules: changing webpack.config.js of module Medium rules array
    module.exports = {
        ......
        plugins:[ htmlPlugin ],
        module : {
            rules:[
                {
                    //test sets the file types that need to be matched and supports regular
                    test:/\.css$/,
                    //use indicates the loader that needs to be called for this file type
                    use:['style-loader','css-loader']
                }
            ]
        }
    }
B.install less,less-loader handle less file
    1).Installation package
        npm install less-loader less -D
    2).Configuration rules: changing webpack.config.js of module Medium rules array
    module.exports = {
        ......
        plugins:[ htmlPlugin ],
        module : {
            rules:[
                {
                    //test sets the file types that need to be matched and supports regular
                    test:/\.css$/,
                    //use indicates the loader that needs to be called for this file type
                    use:['style-loader','css-loader']
                },
                {
                    test:/\.less$/,
                    use:['style-loader','css-loader','less-loader']
                }
            ]
        }
    }
C.install sass-loader,node-sass handle less file
    1).Installation package
        npm install sass-loader node-sass -D
    2).Configuration rules: changing webpack.config.js of module Medium rules array
    module.exports = {
        ......
        plugins:[ htmlPlugin ],
        module : {
            rules:[
                {
                    //test sets the file types that need to be matched and supports regular
                    test:/\.css$/,
                    //use indicates the loader that needs to be called for this file type
                    use:['style-loader','css-loader']
                },
                {
                    test:/\.less$/,
                    use:['style-loader','css-loader','less-loader']
                },
                {
                    test:/\.scss$/,
                    use:['style-loader','css-loader','sass-loader']
                }
            ]
        }
    }

    Supplement: installation sass-loader In case of failure, most cases are due to network reasons. For details, please refer to:
    https://segmentfault.com/a/1190000010984731?utm_source=tag-newest

D.install post-css Auto add css Compatibility prefix for(-ie-,-webkit-)
1).Installation package
    npm install postcss-loader autoprefixer -D
2).Create and configure in the project root directory postcss.config.js file
const autoprefixer = require("autoprefixer");
module.exports = {
    plugins:[ autoprefixer ]
}
3).Configuration rules: changing webpack.config.js of module Medium rules array
module.exports = {
    ......
    plugins:[ htmlPlugin ],
    module : {
        rules:[
            {
                //test sets the file types that need to be matched and supports regular
                test:/\.css$/,
                //use indicates the loader to be called for this file type
                use:['style-loader','css-loader','postcss-loader']
            },
            {
                test:/\.less$/,
                use:['style-loader','css-loader','less-loader']
            },
            {
                test:/\.scss$/,
                use:['style-loader','css-loader','sass-loader']
            }
        ]
    }
}

E.Package pictures and font files in style sheets
 In style sheets css Sometimes, you need to set the background picture and font file loader Processing
 use url-loader and file-loader To handle packaged image files and font files
1).Installation package
    npm install url-loader file-loader -D
2).Configuration rules: changing webpack.config.js of module Medium rules array
module.exports = {
    ......
    plugins:[ htmlPlugin ],
    module : {
        rules:[
            {
                //test sets the file types that need to be matched and supports regular
                test:/\.css$/,
                //use indicates the loader that needs to be called for this file type
                use:['style-loader','css-loader']
            },
            {
                test:/\.less$/,
                use:['style-loader','css-loader','less-loader']
            },
            {
                test:/\.scss$/,
                use:['style-loader','css-loader','sass-loader']
            },{
                test:/\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2$/,
                //Limit is used to set the number of bytes. Only images less than the limit value will be converted
                //base64 image
                use:"url-loader?limit=16940"
            }
        ]
    }
}

F.pack js Advanced syntax in files: Writing js Sometimes we use a higher version when we need to js grammar
 It is possible that these higher versions of syntax are not compatible, and we need to package them as compatible js code
 We need to install babel Series package
A.install babel converter
    npm install babel-loader @babel/core @babel/runtime -D
B.install babel Syntax plug-in package
    npm install @babel/preset-env @babel/plugin-transform-runtime @babel/plugin-proposal-class-properties -D
C.Create and configure in the project root directory babel.config.js file

    module.exports = {
        presets:["@babel/preset-env"],
        plugins:[ "@babel/plugin-transform-runtime", "@babel/plugin-proposal-class-properties" ]
    }
D.Configuration rules: changing webpack.config.js of module Medium rules array
module.exports = {
    ......
    plugins:[ htmlPlugin ],
    module : {
        rules:[
            {
                //test sets the file types that need to be matched and supports regular
                test:/\.css$/,
                //use indicates the loader that needs to be called for this file type
                use:['style-loader','css-loader']
            },
            {
                test:/\.less$/,
                use:['style-loader','css-loader','less-loader']
            },
            {
                test:/\.scss$/,
                use:['style-loader','css-loader','sass-loader']
            },{
                test:/\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2$/,
                //Limit is used to set the number of bytes. Only images less than the limit value will be converted
                //base64 image
                use:"url-loader?limit=16940"
            },{
                test:/\.js$/,
                use:"babel-loader",
                //exclude is an exclusion item, which means do not handle node_ js file in modules
                exclude:/node_modules/
            }
        ]
    }
}

12.Vue single file component

Defects of traditional Vue components: Globally defined components cannot have the same name. The string template lacks syntax highlighting and does not support css (css does not participate in html and js componentization) There is no restriction on the construction steps. Only H5 and ES5 can be used, and the preprocessor (babel) cannot be used Solution: Using Vue single file components, the suffix name of each single file component is vue Each Vue single file component consists of three parts 1).template area composed of template components 2). Business logic area composed of script 3).style area

The code is as follows:

<template>

    Component code area

</template>

<script>

    js Code area

</script>

<style scoped>

    Style code area

</style>

Add: installing Vetur plug-in can make Highlight the code in the vue file

to configure. Loader for vue files A. Loader for installing vue components npm install vue-loader vue-template-compiler -D B. Configuration rule: change webpack config. rules array in JS module const VueLoaderPlugin = require("vue-loader/lib/plugin"); const vuePlugin = new VueLoaderPlugin(); module.exports = { ...... plugins:[ htmlPlugin, vuePlugin ], module : { rules:[ ... / / other rules { test:/.vue$/, loader:"vue-loader",

            }
        ]
    }
}

13. Use vue in webpack

In the previous section, we installed the loader that handles the vue single file component. To make the vue single file component available, we must install vue And use vue to reference vue single file components. A. Install Vue npm install vue -S B. In index JS: import Vue from "vue" C. Create a Vue instance object and specify el, and finally render a single file component using the render function const vm = new Vue({ el:"#first", render:h=>h(app) })

14. Use webpack to package and publish projects

Before the project goes online, we need to package and publish the whole project. A. Configure package json "scripts":{ "dev":"webpack-dev-server", "build":"webpack -p" } B. Before the project is packaged, you can delete the dist directory and generate a new dist directory

15.Vue scaffold

Vue scaffolding can quickly generate the infrastructure of Vue projects. A. Installation 3 Vue scaffolding version x: npm install -g @vue/cli B. Based on 3 Create Vue project with version x: 1). Create a Vue project using the command Command: Vue create my project Select manually select features The checked feature can be checked with a space. Whether to select the route in historical mode: n ESLint selection: ESLint + Standard config When to perform ESLint syntax verification: Lint on save How to place configuration files such as babel and postcss: in dedicated config files Save as template: n Which tool to use to install the package: npm 2). Create Vue project based on ui interface Commands: vue ui Configure project information in the automatically opened create project web page. 3). Based on 2 X old template, create Vue project npm install -g @vue/cli-init vue init webpack my-project

C. Analyze the project structure generated by Vue scaffold node_modules: dependent package directory public: static resource directory src: source directory src/assets: Resource Directory src/components: component directory src/views: view component directory src/App.vue: root component src/main.js: entry js src/router.js: routing js babel.config.js:babel configuration file .eslintrc.js:

16. User defined configuration of Vue scaffold

A.adopt package.json Configure [Not recommended]
    "vue":{
        "devServer":{
            "port":"9990",
            "open":true
        }
    }
B.Configure through a separate configuration file to create vue.config.js
    module.exports = {
        devServer:{
            port:8888,
            open:true
        }
    }

17. Basic use of element UI

Element UI: a set of desktop component library based on 2.0 Official website address: http://element-cn.eleme.io/#/zh-CN A. Installation: npm install element-ui -S B. Import usage: import ElementUI from "element-ui"; import "element-ui/lib/theme-chalk/index.css";

Vue.use(ElementUI)

Today's goal

1. Initialize project 2. Project development based on Vue technology stack 3. Use Vue's third-party components for project development 4. Understand the front and rear end separation development mode

1. Overview of e-commerce business

Business services used by customers: PC, applet, mobile web, mobile app Business services used by administrators: PC background management end. Functions of PC background management end: manage user account (login, exit, user management, authority management), commodity management (commodity classification, classification parameters, commodity information, order), data statistics The e-commerce background management system adopts the development mode of front and rear end separation The front-end project is a Vue based SPA (single page application) project

Front end technology stack: Vue, Vue router, element UI, Axios, echarts Backend technology stack: node JS, express, JWT (simulated session), mysql, serialize (framework for operating database)

2. Project initialization

A. Installation of Vue scaffold B. Create project from scaffolding C. Configure routing D. Configure element UI: install in plug-in, search Vue client plugin element E. Configure Axios: install in dependency, search for Axios (run dependency) F. Initialize git warehouse G. Hosting local projects in github or code cloud

3. Code cloud related operations

A. Registration login code cloud account [the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-G8sAtWwQ-1582446247931)(images / registration code cloud. jpg)]

B. Install git Using Git on Windows, you can download the installer directly from the Git official website for installation. Test command: git – version

C. Click "login" in the upper right corner of the website to login the code cloud and set the account [the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-NeXK5n3u-1582446247931)(images / code cloud click settings. jpg)]

D. Create public key locally: run on the terminal: SSH keygen - t RSA - C“ xxx@xxx.com" [the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-X4DTNc0j-1582446247932)(images / create public key. jpg)] E. Public key address found: Your identification has been saved in /c/Users/My/.ssh/id_rsa. Your public key has been saved in /c/Users/My/.ssh/id_rsa.pub. After we create the public key, please pay attention to the printed message "Your public key has been saved in" /c/Users/My/. ssh/id_rsa.pub: users under Disk C, my under disk C ID under SSH_ rsa. Pub is the public key we created

E. Open id_rsa.pub file, copy all the codes in the file, click the SSH public key in the code cloud, and copy the generated public key to the public key [the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (IMG fouzfpfx-1582446247932) (images / pub file. jpg)]

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (IMG vogcyxdg-1582446247932) (images / SSH public key. jpg)] G. Test public key: open the terminal and enter the command ssh -T git@gitee.com [the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-d2XtBa4E-1582446247933)(images/success.jpg)]

H. Add managed code to the cloud Click the + sign in the upper right corner of the code cloud - > new warehouse [external chain image transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-ciJtFXgg-1582446247933)(images / new warehouse. jpg)] [the transfer of external chain pictures fails. The source station may have an anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (IMG jofuwo5h-1582446247933) (images / create warehouse 2.jpg)]

1. git configuration: [the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-OLPwOz2J-1582446247934)(images/config.jpg)] Open the terminal where the project is located and associate git warehouse [the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-PSjCYV6d-1582446247934)(images / Project terminal implementation Association. jpg)]

4. Configure background items

A. Install phpStudy and import mysql database data [the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-1RoLLmvp-1582446247935)(images/phpStudy.jpg)]

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-6DWr57fm-1582446247935)(images/mysql.jpg)] B. Install nodeJS, configure the background project, and open the background project Vue from the terminal_ api_ server Then enter the command in the terminal to install the project dependency package: npm install

C. Testing api interfaces using postman [the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-y4YMsASa-1582446247935)(images/postman.jpg)]

5. Realize login function

A. Login status remains If the server and the client are of the same origin, it is recommended to use cookie s or session s to maintain the login status If the client and server cross domains, it is recommended to use token to maintain login status.

B. Login logic: Enter the account and password on the login page to log in and send the data to the server The server returns the login result. If the login is successful, the returned data contains a token The client gets the token and saves it. Subsequent requests need to send the token to the server, which will verify the token to ensure the user's identity.

C. Add a new branch login and develop the current project Vue in the login branch_ shop: Open vue_shop terminal, use git status to determine the current project status. After confirming that the current working directory is clean, create a branch for development, and merge it into the master after development git checkout -b login Then look at the newly created branch: git branch Make sure we are using the login branch for development [the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-DBEoHTma-1582446247936)(images/branch.jpg)]

Then execute the vue ui command to open the ui interface, then run serve and run app to view the effect of the current project [the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-2kGF0qOe-1582446247936)(images/ui interface startup project. jpg)]

It is found that it is now a default page. We need to change it. Open the src directory of the project and click main JS file (entry file)

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import './plugins/element.js'

Vue.config.productionTip = false


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

Open the app again Vue (root component), sort out the contents of the root component (leave the root node in the template, leave the default export in the script, remove the component, and remove all styles in the style)

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'app'
}
</script>

<style>
</style>

Then open router JS (routing), clear the routing rules in the routes array, delete the views, and delete HelloWorld. JS in the components Vue delete

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

export default new Router({
  routes: [

  ]
})

Create a new login in the components folder For Vue components, add template, script and style tags. Scoped in the style tag can prevent style conflicts between components. Without scoped, the style is global

<template>
    <div class="login_container">

    </div>
</template>

<script>
export default {

}
</script>

<style lang="less" scoped>
.login_container {
  background-color: #2b5b6b;
  height: 100%;
}

</style>

In router JS and set rules On app Add route placeholder in Vue

const router = new Router({
  routes: [
    { path: '/', redirect: '/login' },
    { path: '/login', component: Login }
  ]
})

When we give login When adding styles to the content in Vue, the error "lack of less loader" will be reported. It is necessary to configure less loader (development dependency) and install less (development dependency) [the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-ku1zEwX9-1582446247936)(images/less.jpg)] Then you need to add a public style, add a css folder under the assets folder, and create a global css file, add global style

/* Global style sheet */
html,body,#app{
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0; 
}

In main JS CSS to make the global style effective import ". / assets/css/global.css" Then login The root element in Vue also needs to be set to hold the full screen (height:100%) Final login The code in the Vue file is as follows

<template>
    <div class="login_container">
        <!-- Login box  -->
        <div class="login_box">
            <!-- head portrait -->
            <div class="avatar_box">
                <img src="../assets/logo.png" alt="">
            </div>
            <!-- login form  -->
            <el-form :model="loginForm" ref="LoginFormRef" :rules="loginFormRules" label-width="0px" class="login_form">
                <!-- user name -->
                <el-form-item prop="username">
                    <el-input v-model="loginForm.username" prefix-icon="iconfont icon-user" ></el-input>
                </el-form-item> 
                <!-- password -->
                <el-form-item prop="password">
                    <el-input type="password" v-model="loginForm.password" prefix-icon="iconfont icon-3702mima"></el-input>
                </el-form-item> 
                <!-- Button -->
                <el-form-item class="btns">
                    <el-button type="primary" @click="login">Sign in</el-button>
                    <el-button type="info" @click="resetLoginForm">Reset</el-button>
                </el-form-item> 
            </el-form>
        </div>
    </div>
</template>

<script>
export default {
  data() {
    return {
      //Data binding
      loginForm: {
        username: 'admin',
        password: '123456'
      },
      //Form validation rules
      loginFormRules: {
        username: [
          { required: true, message: 'Please enter login', trigger: 'blur' },
          {
            min: 3,
            max: 10,
            message: 'The login name is between 3 and 10 characters long',
            trigger: 'blur'
          }
        ],
        password: [
          { required: true, message: 'Please input a password', trigger: 'blur' },
          {
            min: 6,
            max: 15,
            message: 'The password is between 6 and 15 characters long',
            trigger: 'blur'
          }
        ]
      }
    }
  },
  //Add behavior,
  methods: {
    //Add form reset method
    resetLoginForm() {
      //This = > the current component object, in which the attribute $refs contains the set form ref
      //   console.log(this)
      this.$refs.LoginFormRef.resetFields()
    },
    login() {
      //When clicking login, first call the validate method to verify whether the form content is incorrect
      this.$refs.LoginFormRef.validate(async valid => {
        console.log(this.loginFormRules)
        //If the valid parameter is true, the verification passes
        if (!valid) {
          return
        }

        //Send a request to log in
        const { data: res } = await this.$http.post('login', this.loginForm)
        //   console.log(res);
        if (res.meta.status !== 200) {
          return this.$message.error('Login failed:' + res.meta.msg) //console.log("login failed:" + res.meta.msg)
        }

        this.$message.success('Login successful')
        console.log(res)
        //Save token
        window.sessionStorage.setItem('token', res.data.token)
        // Navigate to / home
        this.$router.push('/home')
      })
    }
  }
}
</script>

<style lang="less" scoped>
.login_container {
  background-color: #2b5b6b;
  height: 100%;
}
.login_box {
  width: 450px;
  height: 300px;
  background: #fff;
  border-radius: 3px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  .avatar_box {
    height: 130px;
    width: 130px;
    border: 1px solid #eee;
    border-radius: 50%;
    padding: 10px;
    box-shadow: 0 0 10px #ddd;
    position: absolute;
    left: 50%;
    transform: translate(-50%, -50%);
    background-color: #fff;
    img {
      width: 100%;
      height: 100%;
      border-radius: 50%;
      background-color: #eee;
    }
  }
}
.login_form {
  position: absolute;
  bottom: 0;
  width: 100%;
  padding: 0 20px;
  box-sizing: border-box;
}
.btns {
  display: flex;
  justify-content: flex-end;
}
</style>

Among them, we have the following contents, which need to be further processed:

A. Add form component of element UI Open element in the plugins folder JS file to import elementui on demand import Vue from 'vue' import { Button } from 'element-ui' import { Form, FormItem } from 'element-ui' import { Input } from 'element-ui'

Vue.use(Button) Vue.use(Form) Vue.use(FormItem) Vue.use(Input)

B. Add third party fonts Copy the fonts folder in the material to the assets folder, in the entry file main import 'in JS/ assets/fonts/iconfont.css’ Then directly in Then add the login box

C. To add form validation 1). Add attributes to: Rules = "rules". Rules are a bunch of validation rules defined in script and 2). Add rules: export default {data() {return {..., rules:{ name: [ {required: true, message: 'please enter the activity name', trigger: 'blur'}, {min: 3, max: 5, message: 'length between 3 and 5 characters', trigger:' blur '} ], region: [ {required: true, message: 'please select active area', trigger: 'change'} ] }...... 3). Set the validation rule through the prop property of the

4. Import axios to send ajax requests Open main js,import axios from ‘axios’; Set the root path of the request: Axios defaults. baseURL = ‘ http://127.0.0.1:8888/api/private/v1/'; Mount Axios: Vue prototype.$ http = axios;

5. Configure pop-up prompt: open element in plugins folder JS file, import {Message} from 'element UI' for global mount: Vue prototype. message = Message; In login Write pop-up code in Vue component: this message. Error ('login failed ')

6. Operations after successful login

A. After successful login, you need to save the token returned in the background to sessionStorage After the operation, you need to jump to / home

login() {
      //When clicking login, first call the validate method to verify whether the form content is incorrect
      this.$refs.LoginFormRef.validate(async valid => {
        console.log(this.loginFormRules)
        //If the valid parameter is true, the verification passes
        if (!valid) {
          return
        }

        //Send a request to log in
        const { data: res } = await this.$http.post('login', this.loginForm)
        //   console.log(res);
        if (res.meta.status !== 200) {
          return this.$message.error('Login failed:' + res.meta.msg) //console.log("login failed:" + res.meta.msg)
        }

        this.$message.success('Login successful')
        console.log(res)
        //Save token
        window.sessionStorage.setItem('token', res.data.token)
        // Navigate to / home
        this.$router.push('/home')
      })
    }

Add a component home Vue and add rules to it

<template>
    <div>
        this is home
        <el-button type="info" @click="logout"> sign out </el-button>
    </div>
</template>

<script>
export default {
  methods: {
    logout() {
      window.sessionStorage.clear()
      this.$router.push('/login')
    }
  }
}
</script>

<style lang='less' scoped>
</style>

Add routing rule

const router = new Router({
  routes: [
    { path: '/', redirect: '/login' },
    { path: '/login', component: Login },
    { path: '/home', component: Home }
  ]
})

Add routing guard If the user is not logged in, he / she cannot access / home. If the user accesses directly through the url address, he / she will be forced to jump to the login page Open router js

import Vue from 'vue'
import Router from 'vue-router'
import Login from './components/Login.vue'
import Home from './components/Home.vue'

Vue.use(Router)

const router = new Router({
  routes: [
    { path:'/', redirect:'/login'},
    { path:'/login' , component:Login },
    { path:'/home' , component:Home}
  ]
})

//Mount route navigation guard. To indicates the path to be accessed, from indicates where it comes from, and next is the next operation to be done
router.beforeEach((to,from,next)=>{ 
  if(to.path === '/login')
    return next();

  //Get token
  const tokenStr = window.sessionStorage.getItem('token');

  if(!tokenStr)
    return next('/login');

  next();

})

export default router 

Realize exit function Add an exit function button in the Home component, add a click event to the exit button, and add the event processing code as follows:

export default {
    methods:{
        logout(){
            window.sessionStorage.clear();
            this.$router.push('/login');
        }
    }
}

supplement

A. Handling ESLint warnings Open the scaffold panel and view the warning information [picture] By default, ESLint and vscode format have conflicts. You need to add a configuration file to resolve the conflicts. Add in the project root directory Pretierrc file

{
    "semi":false,
    "singleQuote":true
}

Open eslintrc.js file, disable the check of space before function paren:

  rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    'space-before-function-paren' : 0
  },

B. Merge element UI imported on demand

import Vue from 'vue'
import { Button, Form, FormItem, Input, Message } from 'element-ui'

Vue.use(Button)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)
// Global mount:
Vue.prototype.$message = Message

C. Submit code to code cloud Create a new project terminal and enter the command 'git status' to view the modified and newly added file contents Add all files to the staging area: git add Submit all the code to the local repository: git commit -m "add login function and basic structure of / home" Look at the branch: git branch found that all the code was submitted to the login branch Merge the login branch code into the master main branch and switch to master: git checkout master first Code merging in the master branch: git merge login Push the local master to the remote code cloud: git push

Push the local sub branch to the code cloud. First switch to the sub branch: git checkout branch name Then push it to the code cloud: git push -u origin remote branch name