[email protected] stay Nuxt There are two ways ...">

当前位置:网站首页>Nuxt. JS data prefetching

Nuxt. JS data prefetching

2022-07-01 15:54:00 Black cat crimson

The technical framework used in this paper is :

backstage :Express + MongoDb

The front desk :Vue2.js + [email protected]

stay Nuxt There are two ways to send a request in :

  1. The scheme of separating the front and rear platforms ( The process of data to the page is completed in the browser ) There is no data in the web page source code

    Foreground send request -> Server processing request -> Reception received data -> The foreground renders the data to the page

    Usually through js The data obtained by the behavior of is separated from the front and back

  2. Server side rendering scheme

    1. asyncData: Write it in the page component , Get the data in the page that needs to be rendered by the server , The data return To the page ( Use data directly on the page )
    2. nuxtServerInit: stay store/index.js It says in it , Always run on the server , It will only be executed once when the page is first loaded ( Suitable for writing some globally shared data )
    3. fetch: Write it in the page component , Get the data in the page that needs to be rendered by the server , Save the data to vuex ( Data sharing between parent and child components can be used preferentially fetch)

One 、asyncData

Send a request to get the data before loading the component , Render the data on the page in advance , Then the returned page will contain data .

  1. Because before the client creates the instantiation , therefore Out of commission this, The hook provides a parameter , You can get the context object ({isDev, route, store, env, params, query, req, res, redirect, error} etc. ), So as to do some simple operations .
  2. Can only be used in the routing page component ( Every time you load a page, you call ), Invalid in custom component .
  3. The returned data will eventually match data Data merging , To ensure that page rendering errors do not occur , The return key should be in advance data In the statement ( If template The required attribute... Is not used in , There is no need to declare ).

1.1 An example

When we first open a website , The page will show Login immediately / register The words...

 Insert picture description here

After successful login , This part will be replaced by

 Insert picture description here

Now the need is , Display the user information on the page by rendering on the server

1.2 Preliminary analysis

When the user successfully logs in , Personal information can be saved to the server session in , That means , It seems that we can pass session Get user information .

router.post("/singin", async (req, res) => {
    
    const {
     username, password } = req.body;
    const findUser = await User.findOne({
     username, password });
    // Login successful 
    if (findUser) {
    
        //  Personal information is saved to the server session in 
        req .session.user = findUser;
        res.json({
    
            code: 0,
            msg: " Login successful "
        })
    }
    // Login failed 
    else {
    
        res.json({
    
            code: -1,
            msg: " Account or password error "
        })
    }
})

But ,session Save in server , What we need is to display data in the browser . obviously , The data in the server is not available in the browser .

There seems to be a problem with the bold text above , It seems to write an interface , Request through the interface when entering the home page session The data in seems to be ok , Try it .

1.2.1 code

request session Data interface :

router.get("/userInfo", (req, res) => {
    
    if (req.session.user) {
    
        res.json({
    
            code: 0,
            user: req.session.user,
            msg: " User information obtained successfully "
        })
    }
    else {
    
        res.json({
    
            code: 0,
            user: null,
            msg: " The current user is not logged in "
        })
    }
})

Foreground page :

import {
     request } from "@/utils/request";

export default {
    
    async asyncData() {
    
        //  After the encapsulation axios Request method 
        let result = await request.get("/users/userInfo");
        console.log(result);
        return {
    
	    	result
        }
    },
};

1.2.2 test

After logging in on the homepage Refresh the page

At this time, the data after login can be successfully displayed in the browser , Indicates that the user has logged in :

 Insert picture description here

The server shows that the user is not logged in :

 Insert picture description here

At this point, we need to analyze asyncData The usage of this function .

asyncData It is possible to run in the browser , It may also run on the server .

When you refresh the page ,asyncData Method runs on the server , So the data message will be printed in the server , Through printing, we find that we can't get session data .

Routing jump <nuxt-link> When ,asyncData Method runs in the browser , So the data message will be printed in the browser , By printing, we found that we can get session data .

Why are the printing positions different ,session The printing of data is also different ?

This is where session Principle :

  • After the user logs in through the interface , User information will be saved to the server session in
  • session Inside will create cookie As a voucher , Then the interface returns the certificate to the browser for saving
  • The browser will bring this next time it sends a request cookie voucher

therefore , The reason for the above problem lies in :

  • When the request is sent from the browser , The browser will carry it automatically session Corresponding cookie Send server , So the server can be based on cookie Get data

  • When the request is sent from the server , There is no session Corresponding cookie, So I can't get the login user information

Here I draw a picture to describe , It might be clearer :

 Insert picture description here

In the above error operation , Our method is to call asyncData Method , This method sends a request to the interface in the server , Instead of a request from a browser . because cookie Save in browser , So after the user logs in . The server shows that the user is not logged in .

In the second chapter, specific solutions are introduced .

Two 、nuxtServerInit

This method Only in vuex Use in , forever It will only run on the server , forever It is only executed once when the first screen is loaded

You can take two parameters :

  • The first parameter is saved vuex Information

 Insert picture description here

  • The second parameter is the context object (context)

in other words , After the first screen is loaded , Whether through this.$router.push still <nuxt-link> Jump , This method will not execute , Unless refreshing the page again triggers loading .

It means , use nuxtServerInit Acquired data , After the first screen is loaded, the data cannot be rendered to the page through the above two methods .

//  The function responsible for login 
submitForm() {
    
    //  Here we use Elemnet-ui Form validation method 
    this.$refs.loginForm.validate(async (valid) => {
    
        // Form verification passed , You can send requests 
        if (valid) {
    
            let result = await axios.post("/users/singin", {
    
                username: this.ruleForm.name,
                password: CryptoJS.MD5(this.ruleForm.pwd).toString(),
            });
            //  adopt window.location.href = "/" Refresh the browser , At this point, you can render the data to the page 
            result.code === 0
            	// ? this.$router.push('/')  Invalid 
                ? (window.location.href = "/")
            	: (this.err = result.msg);
        }
    });
},

To write vuex:

import { request } from '@/utils/request'

export const state = () => ({
    user: null,
})

export const mutations = {
    SET_USER(state, payload) {
        state.user = payload
    }
}

export const actions = {
    //  Products are divided into front-end and back-end 
    //  Adopted SSR The front end of can be divided into   Front end client [ Concrete html page ] +  Front end server 
    //  there  nuxtServerInit  Running on the   In the front-end server 
    
    //  The second parameter of this method , You can get the context object of the server 
    //  You can see from the documents , Here you can get nodejs When the server initiates the request  req  data 
    async nuxtServerInit({ commit }, { req }) {
        const user = req.session.user;
        commit("SET_USER", user)
    }
}

Now back to the home page , take vuex Read out the data in :

<template>
  <div>
    <template v-if="user">
       Welcome ,
      <span class="username">{
   { user.username }}</span>
      [<nuxt-link to="/exit"> sign out </nuxt-link>]
    </template>
    <template v-else>
      <nuxt-link to="/login"> Login immediately </nuxt-link> |
      <nuxt-link to="/register"> register </nuxt-link>
    </template>
  </div>
</template>

<script>
import { mapState } from "vuex";
export default {
  computed:{
    ...mapState(['user'])
  }
};
</script>

At this point, the data can be successfully rendered on the page .

3、 ... and 、fetch

This is just about v2.12 The following version

The method and asyncData almost , However, it cannot pass the data return Return to page rendering .

If the page component is set fetch Method , It will be called before each load of the component ( Before the server or switch to the destination route ).

fetch The first parameter of the method is the context object of the page component context, We can use fetch Method to get the data and fill the state tree of the application . To make the acquisition process asynchronous , You need Return to one Promise,Nuxt.js Will wait for this promise Render components after completion .

Be careful : Cannot be used internally this obtain Component instance ,fetch Is in Before component initialization Called

such as :

<template>
	<Son></Son>
</template>

<script>
    export default {
        fetch({ store, params }) {
            return axios.get('/userList').then( res => {
                store.commit('ADD_USER', res.data)
            })
        }
    }
</script>
原网站

版权声明
本文为[Black cat crimson]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/182/202207011543171444.html

随机推荐