Routing and asynchronous requests for Vue2

Table of contents

1. Routing

   1.1 The role of routing

1.2 Use CLI3 to create a Vue2 project with routing function (case)

(1) Create a vue project

 (2) Select Manually select features

 (3) Add routing feature options

 1.3 Getting Started with Routing

1.3.1 Project Routing Planning

 (1) Import global styles in the index.html page (optional)

(2) Project root component App.vue

1.3.2 Route map definition

1.3.3 Switch page content through routing connection (replacement )

2 asynchronous requests

2.1 Backend RESTful web service and proxy

(1) Backend RESTful web service

 (2) Agent of the service

2.2 Use the axois component to request backend data

(1) Promise given fetch API

 (2) axios component

2.3 Use of axios

(1) Add axios to the Vue project

(2) Basic usage of axios

(3) Axios interceptor

2.4 Implement the request in the project


1. Routing

   1.1 The role of routing

In traditional web applications, each URL corresponds to a page in the website; but in SPA (single page application), since there is only one page, if you want to display different routes on the same page with different URLs, you need to use URL To replace Web components, this requires additional routing technology to achieve.

For example, for the following three pages, the header and bottom are the same, but the middle needs to display different intermediate components according to the URL, and routing is required at this time.

 

 

1.2 Use CLI3 to create a Vue2 project with routing function (case)

(1) Create a vue project

vue create funnyshop‐vue2

 (2) Select Manually select features

 (3) Add routing feature options

(4) Use historical mode routing and other feature project features 

 1.3 Getting Started with Routing

1.3.1 Project Routing Planning

According to the functional structure, we can divide the mobile phone micro-business interface into several sub-components.

The specific subcomponent functions are as follows

component name

Functional description

HeaderPart

Navigation and search box in the header of the page

FooterPart

Navigation at the bottom of the page

ProductList

Product List

Login

Log in

Cart

shopping cart

Product Detail

Product Details

 (1) Import global styles in the index.html page (optional)

<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF‐8">
<title>Document</title>
    <meta name="viewport" content="width=device‐width, initial‐scale=1.0, maximum‐scale=1.0, minimum‐scale=1.0, user‐scalable=no"
    <link rel="stylesheet" href="<%= BASE_URL %>css/base.css">
    <link rel="stylesheet" href="<%= BASE_URL %>css/page.css">
</head>
<body>
    <div id="app"></div>
</body>
</html>

(2) Project root component App.vue

Import the common subcomponents (headerpart, footerpart) and the part loaded according to the route (routerview) in the project root component

<template>
    <div class="pageWrapper">
        <header‐part />
        <div class="pageBreak"></div>
        <router‐view></router‐view>
        <div class="pageBreak"></div>
        <footer‐part />
    </div>
</template>
<script>
import HeaderPart from './components/HeaderPart.vue'
import FooterPart from './components/FooterPart.vue'
export default {
    name:"app",
    components:{HeaderPart, FooterPart}
}
</script>

It is not the component we defined, but the routing component of vue, which is just a placeholder for displaying the changed parts that need to be loaded under different urls.

1.3.2 Route map definition

After the vue2 project with router is created, there will be an additional file named "router.js" in the src directory, which is used to define routing rules, that is, the corresponding relationship and parameters of Vue subcomponents to be loaded under different URL paths Delivery rules.

import Vue from 'vue'
import Router from 'vue‐router'
import ProductList from './components/ProductList.vue'
import Login from './components/Login.vue'
import ProductDetail from './components/ProductDetail.vue'
import Cart from './components/Cart.vue'
Vue.use(Router)
export default new Router({
    mode: 'history',
    base: process.env.BASE_URL,
    routes: [
    {
        path: '/',
        name: 'home',
        component: ProductList
    },
    {
        path: '/product‐list',
        name: 'product‐list',
        component: ProductList
    },
    {
        path:'/login',
        name:'login',
        component: Login
    },
    {
        path:'/product/:id',
        name:'product',
        component: ProductDetail
    },
    {
        path:'/cart',
        name:'cart',
        component: Cart
    },
  ]
})

Each item in the routes configuration represents a routing rule.

path is the URL path, which can define path parameters (such as id in "/product/:id"); name is the route name, used for reference; component specifies the name of the loaded component.

After completing component division (*.vue) and routing mapping (router.js), the application can display different page content according to routing rules.

1.3.3 Switch page content through routing connection (replace <a>)

The traditional hyperlink <a href="..."> will cause the page to jump synchronously. There is only one page in the SPA application, and the content switching is all asynchronous.

(1) Realize "jump" through the <router-link> component

routerlink is a routing component, which can be understood as an asynchronous jump connection tag (<a>)

The to attribute of routerlink can set the URL of the switch. After to, you can set a "static URL" or bind "a routing item object". For example, in the following two examples, the former sets a URL, and the latter binds a defined routing object.

<router‐link to="/login">登录</router‐link>
<router‐link :to="{name:'cart'}">购物车</router‐link>。

(2) Change $router.push() by pushing the route to achieve "jump"

In a project with routing configured, we can access the routing object through this.$router in any Vue component, and through the $router.push() method, we can push jumps to the routing to achieve component switching.

this.$router.push({name:"product‐list", query:{"name":val}});

 1.3.4 Obtaining routing parameters

(1) Path parameters and acquisition We have defined the following items in the routing map (router.js):

{ path:'/product/:id', name:'product', component: ProductDetail }

 That is, when jumping to the ProductDetail component, we will pass in a path parameter named id.

For example, if there is the following routing link in the product list, the actual URL may be "/product/5" after clicking, where 5 is the id parameter.

<router‐link :to="{name:'product',params:{id:item.id}}">产品1连接</router‐link>

At this time, we can get the route parameter value through "$route.params.parameter name" in the target component ProductDetail: 

let id = this.$route.params.id;

(2) Acquisition of query string parameters

Path parameters are part of the URL path, usually only used to pass necessary parameters (parameters that must be provided), for optional parameters, query strings should be used to pass, for example: "search?name=abc&page=101" .

For query string parameters, we can pass in the following ways. 

searchByProductName(e){
    var val = e.target.value;
    this.$router.push({name:"product‐list", query:{"name":val}});
}

 The above route push will generate a URL like this: "productlist?name=xxxx" At this time, we can get the query string parameter value through "$router.query.parameter name" in the target component ProductList.

let searchName = this.$route.query.name

2 asynchronous requests

2.1 Backend RESTful web service and proxy

(1) Backend RESTful web service

SPA generally adopts the development method of front-end and back-end separation. The backend can use any server-side web technology, such as JavaEE, PHP, Node.js, Python, etc. The backend provides RESTful-based web services, receives front-end requests and returns data in JSON format.

Here, the Spring Boot-based MVC technology is used to provide back-end services. The specific details are omitted, and only the provided service interface is described here.

URL

Function

http://localhost:9090/api/products/latest

Get the latest 4 products and return data in JSON format

http://localhost:9090/api/products/1

Get product details with id=1

http://localhost:9090/api/products?name=celadon

Fuzzy query product information containing "celadon" in the name, return

JSON format data

The specific request effect is shown in the figure below.

 

 (2) Agent of the service

As a separate front-end and back-end projects, the back-end and front-end often do not run on the same server. For example, in the above development, the back-end JavaEE service runs on the Tomcat server (the container embedded in Spring Boot), while the front-end uses the test server provided by Node.js. The former domain name is "localhost:9090", while the latter is "localhost:3000". At this time, if the front-end requests back-end data through AJAX technology, it will encounter the problem that JavaScript requests cannot be executed across domains and cannot be requested. To solve this problem, either the jsonp protocol (cross-domain JSON protocol) needs to be used, or the front-end and back-end servers must be proxied to the same domain name through a proxy server. In actual deployment, we can implement proxy through static resource servers such as Nginx, while in development, the Vue project can directly configure the back-end proxy to proxy the domain name request of lcoalhost:9090 to the domain name of localhost:3000.

Add the "vue.config.js" file in the root directory of the project, which is the configuration file of the vue project, in which you can set the port "port" of the development server and the proxy "proxy" of the back-end Web service.

module.exports = {
    devServer: {
        port: 3000,
        proxy: {
            '/api': {
                target: 'http://localhost:9090', // target host
            },
        }
    }
};

As shown above, when we request "localhost:3000/api/xxx", the request is proxied to "http://localhost:9090/api/xxx", so that there is no cross-domain problem between the front end and the front end.

2.2 Use the axois component to request backend data

(1) Promise given fetch API

Traditional static web pages implement asynchronous requests for back-end data through XMLHttpRequest objects (such as jQuery's $.ajax), and callback functions need to be executed after the request is successful.

This traditional callback is often nested one after another in a complex usage environment, making the code fall into the "Callback Hell" that is difficult to maintain. The new generation of JavaScript (ES6) no longer recommends using XMLHttpRequest, but uses a method called Promise to organize code, so that we don't have to fall into the chain of callbacks, but handle all callbacks in a flat way. A new generation of browsers supports an API method called fetch, which can implement Promise-style requests.

 (2) axios component

Although the fetch API is very useful based on Promise, the fetch function is still too primitive. In practical applications, we may need some extension modules such as interceptors.

For this reason, the author of vue recommends that we use a JavaScript extension package called axios to implement the background request function. Axios has a good Promise and interceptor mechanism.

2.3 Use of axios

For the detailed use of axios, please refer to the Internet https://www.npmjs.com/package/axios, here is just a brief introduction.

(1) Add axios to the Vue project

Execute the following Node instructions in the project root directory: 

vue add axios

(2) Basic usage of axios

Method

Api

Get

axios.get(url).then(successCallback).catch(errorHandler)

Post

axios.post(url, data).then(successCallback).catch(errorHandler)

Put

axios.put(url, data).then(successCallback).catch(errorHandler)

Delete

axios.delete(url).then(successCallback).catch(errorHandler)

(3) Axios interceptor

Axios can insert interceptors before (component's) requests or corresponding processing, and uniformly handle common problems in asynchronous requests.

For example, we can add the following code in the react program entry "index.js" to uniformly add the jwt request header before the request is sent, or locate the page when the response fails. 

import axios from 'axios';
//请求前处理
axios.interceptors.request.use(
    config => {
        const token = window.localStorage.getItem("jwt‐token");
        if(token)
            config.headers={'Authorization': 'Bearer '+token};
        return config;
    },
    error=>{
        return Promise.reject(error);
    }
);
//响应前处理
axios.interceptors.response.use(
    response => {
        return response;
    },
    error => {
        const httpCode = error.response.status;
        if(httpCode>=400 && httpCode<600){
            window.location.href="/error";
        }
        return Promise.reject(error);
    }
);

2.4 Implement the request in the project

The following demonstrates how to request product information from the backend in the ProductList component.

<template>
        <div class="contentWrapper">
            <h4 class="contentTitle">新品上架:</h4>
            <div class="productListWrapper">
                <div class="productWrapper" v‐for="(item,i) in products" :key="i">
                    <router‐link :to="{name:'product',params:{id:item.id}}">
                        <img :src="'images/content/'+item.id+'‐1.jpg'" alt=""/>
                    </router‐link>
                <div class="productInfoWrapper">
                    <span class="productTitle">{
   
   {item.name}}</span>
                    <a class="purchaseButton">¥{
   
   {item.unitPrice}} 购买</a>
                </div>
            </div>
          </div>
        </div>
</template>

<script>
export default {
    name: 'product‐list',
    data(){
        return {
            products:[]
        };
    },
    mounted(){
        this.fetchData();
    },
    methods:{
        fetchData(){
            if(this.$route.query.name){
                this.axios.get("/api/products?name="+this.$route.query.name).then(res=>this
            }else{
                this.axios.get("/api/products/latest").then(res=>this.products=res.data);
            }
        }
    }
}
</script>

Guess you like

Origin blog.csdn.net/qq_55917018/article/details/127908650