ajax, promessa, reagir, registro de nota de cache

solicitação ajax

1. Solicitar etapas básicas

<body>
    <form action="###">
    手机号:<input type="text" name="phone" placeholder="手机号" id="phone">
    <br>
    密码:<input type="text" name="pass" id="pass">
    <br>
    <button id="btn">登录</button>
  </form>
    <script>
        const phone=document.getElementById('phone')
        const pass=document.getElementById('pass')
        const btn=document.getElementById('btn')
        btn.onclick=function(){
      
      
            //1.1利用ajax核心对象xmlHttpRequest创造实例对象
            //1.2 利用open方法打开路径
            //1.3 利用send方法发送请求参数
            //1.4 利用readystatechange事件监听readyState请求状态码的变化
            return false
        }
    </script>
</body>

1.1 Crie um objeto de instância usando o objeto principal ajax xmlHttpRequest

Porque o objeto protótipo de XMLHttpRequest contém muitos métodos para dar suporte a solicitações ajax

const xhr=new XMLHttpRequest()

Nota: Ao usar tags de formulário, preste atenção ao evento de solicitação padrão retornar falso do formulário de formulário

1.2 Use o método open para abrir o caminho

Os 3 parâmetros de abertura:

Método de solicitação: get/post

Endereço do pedido:

​ 1. O endereço da solicitação get contém o campo de caractere de consulta (parâmetros da solicitação). Como a solicitação get lê o cache por padrão, ela pode ser emendada atrás da string de consulta com um carimbo de data/hora para garantir que o endereço da solicitação seja diferente

2. Os parâmetros de pós-solicitação estão no corpo da solicitação

​ Se assíncrono: falso/verdadeiro

//get请求
xhr.open('get',`/login?phone=${
      
      phone.value}&pass=${
      
      pass.value}&_=${
      
      Date.now()}`,true)
//post请求
xhr.open('post','/login',true)

1.3 Use o método send para enviar parâmetros de solicitação

parâmetros de envio:

​ 1. Se for uma solicitação get, porque os parâmetros da solicitação estão todos no endereço da solicitação, não é necessário preencher os parâmetros, ou você pode preencher null

2. Caso seja uma solicitação postal, preencha o corpo da solicitação a ser enviada

Quando enviar envia dados, você precisa definir o cabeçalho da solicitação para informar ao servidor que tipo de dados estou enviando

​ - Se o formato de dados em enviar for o formato de string de consulta url, o tipo de conteúdo do cabeçalho da solicitação: application/x-www-form-urlencoded

​ - Se o formato de dados no envio for o formato de string json, o tipo de conteúdo do cabeçalho da solicitação: application/json

//get请求
xhr.send() 或 xhr.send(null)
//post请求
xhr.setRequestHeader('Content-Type','application/json;charset=utf-8')
xhr.send(JSON.stringfy{
    
    
         phone:phone.value,
         pass:pass.value
         })

1.4 Use o evento readystatechange para monitorar a alteração do código de status da solicitação readyState

código de status da solicitação readyState (0-4):

​ 0 : significa sem envio

​ 1 : Indica que o método open foi iniciado

​ 2 : Indica que o método send foi iniciado

​ 3 : Indica que a parte inicial aceita dados

4 : Indica sucesso

status Código de status da resposta (200-299)

responseText aceita outras respostas semelhantes a texto (json)

responseXml aceita respostas xml

xhr.onreadystatechange=function(){
    
    
    console.log('readyState'+xhr.readyState)
    if(xhr.readyState===4&&xhr.status>=200&&xhr.status<=299){
    
    
       console.log('请求发送成功了')
        const resData=JSON.parse(xhr.responseText)
        //app.js 设置了响应成功code :200
        if(resData.code===200){
    
    
          return alert("登录成功,您的用户名是" + resData.data.username)
        }
        alert('登录失败')
}

2. ajax em jQuery

2.1 Embalagem de Nível 1

$(function(){
    
    
    $('#btn').click(function(){
    
    
        $.ajax({
    
    
            url:'/login',//请求地址
            type:'get' /'post' , //请求方式
            cache:false,//是否缓存
            data:{
    
    
                //请求参数
                //数据:如果是get请求 则帮我们拼接在url上,如果是post请求 会转成字符串
                 phone:$('#phone').value,
         		pass:$('#pass').value
            },
            dataType: "json", //预期的响应数据的格式
            headers: {
    
    }, //请求头
            timeout: 2000, //设置超时时间
            sucess(val){
    
    
                //成功的回调函数,参数就是得到的数据
                console.log(val)
			}
          })
           return false 
        })  
     })

2.2 Embalagem Secundária

$(function(){
    
    
  $('#btn').click(function(){
    
    
    //get请求
    $.get('/login',
          {
    
    
                //请求参数
                //数据:如果是get请求 则帮我们拼接在url上,如果是post请求 会转成字符串
                 phone:$('#phone').value,
         		pass:$('#pass').value
            },
          (val)=>{
    
    
        //成功的回调函数,参数就是得到的数据
                console.log(val)
    	},
          'json')
    
    //post请求
     $.post('/login',
          {
    
    
                //请求参数
                //数据:如果是get请求 则帮我们拼接在url上,如果是post请求 会转成字符串
                 phone:$('#phone').value,
         		pass:$('#pass').value
            },
          {
    
    
                //请求参数
                //数据:如果是get请求 则帮我们拼接在url上,如果是post请求 会转成字符串
                 phone:$('#phone').value,
         		pass:$('#pass').value
            },
          (val)=>{
    
    
        //成功的回调函数,参数就是得到的数据
                console.log(val)
    	},
          'json')
    
    return false
    
	})
})

2.3 Embalagem de três níveis

$(function(){
    
    
    $('#btn').click(function(){
    
    
        $.getJSON('/login',
                  {
    
     //请求参数
            phone:$('#phone').value,
            pass:$('#pass').value
           },
              	(val)=>{
    
    
     					console.log(val)
    	})
	})
})

Promessa

1. Introdução básica ao Promise

1.1 Construtor de promessa

  1. O objeto Promise é uma solução para programação assíncrona, que pode expressar operações de código assíncronas em um processo síncrono, evitando camadas de funções de callback aninhadas (comumente conhecidas como 'callback hell')

  2. Promise tem três métodos de protótipo de então, pegar e finalmente

  3. Existem seis métodos estáticos em Promise: all, allSettled, race, any, rejeitar e resolver

  4. Promise lida com código assíncrono e a execução da própria função de retorno de chamada de Promise é síncrona

1.2 Promessa de uso básico

  1. A instanciação de promessa recebe uma função de retorno de chamada como parâmetro

  2. A função de retorno de chamada Promise aceita dois parâmetros, reslove e rejeitar (ambos são funções)

  3. Escreva código assíncrono em Promise. Quando o código assíncrono for bem-sucedido, você poderá chamar a função reslove e, quando o código assíncrono falhar, poderá chamar a função de rejeição.

  4. O valor de retorno de Promise determinará o status de acordo com as chamadas de resolver e rejeitar. Se não houver rejeição ou resolução, o objeto de instância de promessa no estado pendente será retornado. Se o erro do código de sincronização for encontrado, a promessa de objeto de instância com falha será retornada diretamente
    .

  5. O estado do objeto de instância Promise só pode mudar de pendente para outros estados

1.3 Objeto de instanciação de promessa

  1. PrometeState propriedade: o estado da promessa atual

    • O padrão é o estado pendente, o que significa que o código assíncrono está sendo executado

    • cumprido/resolvido: indica que o código assíncrono foi executado com sucesso e a função resolve foi chamada

    • rejeitado: indica que a execução do código assíncrono falhou e a função de rejeição foi chamada

  2. Propriedade PromiseResult: o resultado da execução da promessa atual

    • Se o código assíncrono for executado com sucesso, o valor será o valor passado na função resolver

    • Se a execução do código assíncrono falhar, o valor é a mensagem de erro na função de rejeição

2. Método de protótipo de promessa

const p1=new Promise((resolve,reject)=>{
    
    
    try{
    
    
        throw new Error('A有错误')
        setTimeout(()=>{
    
    
            throw new Error('A异步有错误')
            console.log('A打印成功')
            resolve('A')
        })
    }catch(e){
    
    
        reject(e.message)
    }
})
注意:try...catch...只能捕获同步错误,异步里面的错误不能到catch里面,会直接报错
同时同步代码里面有错误后,同步代码后面的代码不会执行,会直接进入catch里面
try...catch...捕获错误后,就不会直接报错 就是会进入catch,我们可以通过error.message获取错误信息,但是不会直接直接在页面里报错

2.1 método then()

p1.then((value)=>{
    
    
    //若调用then方法的promise实例状态为成功,则进入这个回调函数,value是promise实例的值
    console.log(value) //A
},(reason)=>{
    
    
    //若调用then方法的promise实例状态为失败,则进入这个回调函数,reason是promise实例的传入的错误信息
    console.log(reason)//e.message的具体信息
})

2.1.1 Introdução básica do método

  1. O método then é chamado pelo objeto de instância de Promise e pode executar a próxima operação por meio do estado do objeto de instância
  2. O método then pode aceitar 2 parâmetros, ambos funções de retorno de chamada, respectivamente manipulando o objeto de instância de promessa do estado de sucesso e o estado de falha
  3. As funções de retorno de chamada no método then são todas executadas de forma assíncrona
  4. O parâmetro da função callback no método then é o sucesso ou falha da instância da promessa

2.1.2 valor de retorno do método

  1. Por padrão, um objeto de promessa com status de sucesso é retornado e o valor é o valor retornado
  2. Se ocorrer um erro em then e não for resolvido, um objeto de promessa em estado de falha será retornado e o valor será uma mensagem de erro
  3. Se então retorna um objeto de promessa, o valor de retorno é vinculado ao objeto de promessa
  4. Se não houver nenhuma função de retorno de chamada em then que lide com o estado correspondente da instância de promessa chamando o método then , ocorrerá penetração de valor

(Fenômeno de penetração de valor: retorna um objeto de promessa, o conteúdo do objeto de promessa é o mesmo que a instância de promessa do método de chamada)

2.2 método catch ()

p1.catch(reson=>{
    
    
   //catch只处理调用该方法的失败状态下的promise实例,如果是成功状态的promie实例,会发生值的穿透
   //若调用then方法的promise实例状态为失败,则进入这个回调函数,reason是promise实例的传入的错误信息
     console.log(reson)//e.message的具体信息
})

2.2.1 Introdução básica do método catch

  1. Consistente com a segunda função de callback de então
  2. Não pode ser usado com a segunda função de callback de then ao mesmo tempo

2.2.2 valor de retorno catch: a regra é consistente com o método then

2.3 método finalmente()

p1.finally(()=>{
    
    
    //调用的promise实例状态为成功或失败都可以进入这个回调函数
    console.log(reson)//undefined
    console.log(value)//undefined
})

2.3.1 Introdução básica do método finalmente

  1. Independentemente de o status da instância de promessa do método de chamada ser bem-sucedido ou não, ele entrará na função de retorno de chamada final
  2. a função de retorno de chamada de finalmente não aceita nenhum parâmetro

2.3.2 finalmente retorna o valor:

  1. Penetração direta por padrão

  2. Se ocorrer uma exceção em finalmente, um objeto de promessa com falha será retornado, cujo valor é a informação da exceção

  3. Se a instância da promessa for retornada em finalmente

    • Se a instância de promessa retornada for bem-sucedida, ignore-a e passe diretamente
    • Se a instância de promessa retornada falhar, finalmente retorna a instância de promessa com falha

2.4 Exercícios de caso

3. Prometa o método estático

    const p1 = new Promise((resolve, reject) => {
    
    
      console.log("开始请求A");
      try {
    
    
        // throw new Error("A错误")
        setTimeout(() => {
    
    
          console.log("A成功");
          resolve("A")
        }, 2000)
      } catch (e) {
    
    
        reject(e.message)
      }
    })

    const p2 = new Promise((resolve, reject) => {
    
    
      console.log("开始请求B");
      try {
    
    
        // throw new Error("B错误")
        setTimeout(() => {
    
    
          console.log("B成功");
          resolve("B")
        }, 1000)
      } catch (e) {
    
    
        reject(e.message)
      }
    })

    const p3 = new Promise((resolve, reject) => {
    
    
      console.log("开始请求C");
      try {
    
    
        // throw new Error("C错误")
        setTimeout(() => {
    
    
          console.log("C成功");
          resolve("C")
        }, 1500)
      } catch (e) {
    
    
        reject(e.message)
      }
    })
	const allResult = Promise.all([p1, p2, p3]);//传入的参数必须是iterable
	const allResult = Promise.allSettled([p1, p2, p3]);
	const allResult = Promise.race([p1, p2, p3]);
	const allResult = Promise.any([p1, p2, p3]);
	const allResult = Promise.resolve([p1, p2, p3]);
	const allResult = Promise.reject([p1, p2, p3]);
    console.log("allResult", allResult);

3.1 método all()

  1. retorna um objeto de promessa
  2. Se o status do objeto de promessa no parâmetro for bem-sucedido, retorne um objeto de promessa de sucesso cujo valor seja um array composto pelos valores de todos os objetos de promessa no parâmetro
  3. Se o estado de qualquer objeto de promessa no parâmetro for reprovado, um objeto de promessa com falha será retornado e o valor será a mensagem de erro do primeiro objeto de promessa com falha monitorado no parâmetro (o valor em rejeição)

3.2 método allSettled()

  1. retorna um objeto de promessa
  2. O objetivo principal é detectar se todos os objetos de promessa são executados (seja com sucesso ou com falha)
  3. O método allSettled sempre retorna um estado de promessa bem-sucedido, o valor é uma matriz e cada valor da matriz é um novo objeto composto pelo estado e valor do objeto de promessa monitorado

3.3 método race()

  1. retorna um objeto de promessa
  2. O objeto de promessa retornado é conectado ao primeiro objeto de promessa no parâmetro que muda de estado

3.4 método any()

  1. retorna um objeto de promessa
  2. O objeto de promessa retornado está vinculado ao objeto de promessa mais rápido e bem-sucedido no parâmetro
  3. Se o status de todos os objetos de promessa no parâmetro for falhado, retorne um objeto de promessa com um status de erro e o valor seja o novo tipo de erro AggregateError: Todas as promessas foram rejeitadas

3.5 método resolve()

  1. Obtenha rapidamente um objeto de promessa bem-sucedido, cujo valor é o parâmetro de resolução (você também pode agrupar rapidamente um valor em um objeto de promessa bem-sucedido e, em seguida, continuar o processamento assíncrono dele)
  2. Quando o parâmetro de resolve é um objeto de promessa, o valor de retorno de resolve é vinculado ao objeto de promessa

3.6 método rejeitar ()

  1. Obtenha rapidamente um objeto de promessa com falha, cujo valor é o parâmetro de rejeição (você também pode agrupar rapidamente um erro em um objeto de promessa com falha e pode continuar a capturar o processamento assíncrono)
  2. Quando o parâmetro de rejeição for um objeto de promessa, retorna um objeto de promessa em status de falha, cujo valor é o objeto de promessa passado como parâmetro

async&await

1.gerador

      // generator函数 *号  yield关键字

      function* fn() {
    
    
        console.log("123");
        yield console.log("1");
        // 一个yield分号结束之前,都属于yield
        yield console.log("2");
        yield console.log("3");
        yield console.log("4");
        yield console.log("5");
      }
      const res = fn();
      console.log(res); //res中的原型链上有next方法 返回一个迭代器对象(iterator)

      document.onclick = function () {
    
    
        res.next();
      };
    function* getData() {
    
    
        yield setTimeout(() => {
    
    
          console.log("要1");
          res.next();
        }, 2000);

        yield setTimeout(() => {
    
    
          console.log("要2");
          res.next();
        }, 1000);

        yield setTimeout(() => {
    
    
          console.log("要3");
          res.next();
        }, 1500);

        yield setTimeout(() => {
    
    
          console.log("要4");
          res.next();
        }, 1500);

        yield setTimeout(() => {
    
    
          console.log("要5");
        }, 1000);
      }

      const res = getData(); //先调用generator函数 得到一个对象

      
      document.onclick = function () {
    
    
        // 点击文档后开始调用getData 每次点击会重新调用,重新开始
        // const res = getData();
        res.next();
      };

2.async&await

// 最终结果顺序:1 3 2
        async function fn(){
    
    
          await console.log(1);
          // await语法语句后面的代码是异步代码
          console.log(2);
      }
      fn()
      console.log(3);
      // 最终结果顺序:3 2 1
      async function fn() {
    
    
        // await后面的代码 没有等待前面计时器异步代码的执行
        await setTimeout(() => {
    
    
          console.log(1);
        }, 2000);
        // await语法语句后面的代码是异步代码
        console.log(2);
      }
      fn();
      console.log(3);

      // 结果顺序:3 1 2
      async function fn() {
    
    
        // await 后面等待promise对象 因为promise对象有异步代码成功结束节点提示
        // 如果接受到的是reject失败结果,await语句后面的代码不会执行 会报错
        // 如果接受到的是resolve成功结果,await语句后面代码正常执行,await返回值是promise实例对象的值(resolve传的值)
        const p=await new Promise((resolve, reject) => {
    
    
          setTimeout(() => {
    
    
            console.log(1);
            resolve('这是异步代码结果');
            reject()
          }, 2000);
        });
        console.log(p);//这是异步代码结果 
        console.log(2);
      }
      fn();
      console.log(3);
      

valor de retorno da função assíncrona

  1. função assíncrona retorna um objeto de promessa
  2. Por padrão, o objeto de promessa do status de sucesso é retornado e o valor é o valor de retorno da função (não tem nada a ver com await)
  3. Quando ocorre um erro dentro da função assíncrona, retorna um objeto de promessa no estado com falha e o valor é a mensagem de erro
  4. Quando await na função assíncrona espera por um objeto de instância de promessa com falha, o valor de retorno da função é vinculado ao objeto de promessa
  5. await return value : o valor do objeto de promessa bem-sucedido
async function getA() {
    
    
        // throw new error('错啦')
        const p=await new Promise((resolve, reject) => {
    
    
          //  throw new Error('错啦')

          try {
    
    
            console.log("开始请求A");
            // throw new Error("A错啦");
            setTimeout(() => {
    
    
              console.log("A开始执行");
              // throw new Error("A错啦");
              console.log("A成功啦");
              resolve("A成功");
            }, 1000);
          } catch (e) {
    
    
            reject(e.message);
          }
        });
        console.log('B');
        console.log('p',p);
        
        return 1;
      }
      const res = getA();
      console.log("async函数的返回值", res);

3. Exercícios de casos

3.1 caso getData

3.1.1 Edição Normal

async function getData(){
    
    
          console.log('开始请求A数据');
          const A=await new Promise((resolve,reject)=>{
    
    
              try{
    
    
               
                  setTimeout(()=>{
    
    
                      console.log("A成功了");
                      resolve({
    
    
                          name:'laowang'
                      })
                  })
              }catch(e){
    
    
                  reject(e.message)
              }
          })

          console.log('开始请求B数据');
          const B=await new Promise((resolve,reject)=>{
    
    
              try{
    
    
                 
                  setTimeout(()=>{
    
    
                      console.log("B成功了");
                      resolve({
    
    
                          age:18
                      })
                  })
              }catch(e){
    
    
                  reject(e)
              }
            })


            console.log('开始请求C数据');
            const C=await new Promise((resolve,reject)=>{
    
    
              try{
    
    
                  
                  setTimeout(()=>{
    
    
                      console.log("C成功了");
                      resolve(Object.assign(A,B,{
    
    gender:'nan'}))
                  })
              }catch(e){
    
    
                  reject(e)
              }
            })

        console.log(C)
    }

    getData()



3.1.2 Versão do encapsulamento da função

function getName() {
    
    
  return new Promise((resolve, reject) => {
    
    
    try {
    
    
      setTimeout(() => {
    
    
        resolve({
    
    
          name: "zs",
        });
      }, 2000);
    } catch (e) {
    
    
      reject(e.message);
    }
  });
}

function getAge() {
    
    
  return new Promise((resolve, reject) => {
    
    
    try {
    
    
      setTimeout(() => {
    
    
        resolve({
    
    
          age: 18,
        });
      }, 1500);
    } catch (e) {
    
    
      reject(e.message);
    }
  });
}

function getGender(name, age) {
    
    
  return new Promise((resolve,reject) => {
    
    
    try {
    
    
      setTimeout(() => {
    
    
        resolve(Object.assign(name, age, {
    
     gender: "男" }));
      }, 1000);
    } catch (e) {
    
    
      reject(e.message);
    }
  });
}

async function getData() {
    
    
  const name = await getName();
  const age = await getAge();
  const data = await getGender(name, age);
  console.log(data);
}
getData()

3.2 Casos de gravação de arquivos

3.2.1 Edição Normal

const fs = require("fs");
const path = require("path");
const filePath = path.join(__dirname, "./a.txt");

async function writeWordsInTxt() {
    
    
  const fd = await new Promise((resolve, reject) => {
    
    
    fs.open(filePath, "a", (err, fd) => {
    
    
      if (err) return reject(err.message);
      resolve(fd);
    });
  });
  await new Promise((resolve, reject) => {
    
    
    fs.write(fd, "你好呀", (err) => {
    
    
      if (err) return reject(err.message);
      resolve();
    });
  });
  await new Promise((resolve, reject) => {
    
    
    fs.close(fd, (err) => {
    
    
      if (err) return reject(err.message);
      resolve();
    });
  });
}

writeWordsInTxt() 

3.2.2 Versão do encapsulamento da função

const fs = require("fs");
const path = require("path");
const filePath = path.join(__dirname, "./a.txt");

function open() {
    
    
  return new Promise((resolve, reject) => {
    
    
    fs.open(filePath, "a", (err, fd) => {
    
    
      if (err) return reject(err.message);
      resolve(fd);
    });
  });
}

function write(fd) {
    
    
  return new Promise((resolve, reject) => {
    
    
    fs.write(fd, "封装好啦", (err) => {
    
    
      if (err) return reject(err.message);
      resolve();
    });
  });
}

function close(fd) {
    
    
  return new Promise((resolve, reject) => {
    
    
    fs.close(fd, (err) => {
    
    
      if (err) return reject(err.message);
      resolve;
    });
  });
}

async function writeWordsInFile() {
    
    
  const fd = await open();

  await write(fd);
  close(fd);
}

writeWordsInFile();

3.2.3 versão prometida

const fs = require("fs");
const path = require("path");
const filePath = path.join(__dirname, "./a.txt");
const {
    
     promisify } = require("util");
const open = promisify(fs.open);
const write = promisify(fs.write);
const close = promisify(fs.close);

(async function () {
    
    
  const fd = await open(filePath, "a");
  await write(fd,'promisify完成啦');
  close(fd);
})();

axios

1. Solicitação básica do Axios

usar:

  1. usar
<button id="get">get-得到用户信息</button>
    <button id="post">post-得到用户信息</button>
    <button id="put">put-得到用户信息</button>
    <button id="del">delete-删除用户信息</button>

    <script>

        const oGet = document.getElementById("get");
        const oPost = document.getElementById("post");
        const oPut = document.getElementById("put");
        const oDel = document.getElementById("del");

        //  get请求
        oGet.onclick =async function () {
    
    
          try{
    
    
            const re=await axios({
    
    
            url: "/user",
            method: "GET",
            // get请求发送的数据 1.拼接到url上 2.使用params配置
            // params有2种格式 1.对象格式 2.查询字符串格式
            params:{
    
    
              userID:001
            },
            timeout:1000,
          });
          console.log('get',re);
          }catch(e){
    
    
            console.log(e.message);
          }
        };


        //  post请求
      oPost.onclick =  async function () {
    
    
          try{
    
    
            const re=await axios({
    
    
            url: "/login",
            method: "POST",
            // post请求 请求体参数用data发送,data是一个对象类型
            data:{
    
    
              phone:'1300000001',
              pass:'11111'
            },
            timeout:1000,
          });
          console.log('post',re);
          }catch(e){
    
    
            console.log(e.message);
          }
        };


        // put请求
        oPut.onclick = async function () {
    
    
          try{
    
    
            const re=await axios({
    
    
            url: "/update",
            method: "put",

            //put请求同post请求一样
           data:{
    
    
              userID:'zs',
              age:18
            },
            timeout:1000,
          });
          console.log('put',re);
          }catch(e){
    
    
            console.log(e.message);
          }
        };


        //  delete请求
        oDel.onclick = async function () {
    
    
          try{
    
    
            const re=await axios({
    
    
            url: "/deleteuser",
            method: "Delete",
            // delete请求同get请求一样
            params:{
    
    
              userID:'zs',

            },

            timeout:1000,
          });
          console.log('del',re);
          }catch(e){
    
    
            console.log(e.message);
          }
        };
    </script>

2. solicitação de alias axios

<button id="get">get-得到用户信息</button>
    <button id="post">post-得到用户信息</button>
    <button id="put">put-得到用户信息</button>
    <button id="del">delete-删除用户信息</button>

    <script>
      const oGet = document.getElementById("get");
      const oPost = document.getElementById("post");
      const oPut = document.getElementById("put");
      const oDel = document.getElementById("del");

      //  get请求
      oGet.onclick = async function () {
    
    
        try {
    
    
          const re = await axios.get("/user", {
    
    
            params: {
    
    
              userID: 001,
            },
            timeout: 1000,
          });

          // 将查询字符串写在请求地址上
          // const re=await axio.get('/user?userid=001',{
    
    
          //   timeout: 1000,
          // })


          console.log("get", re);
        } catch (e) {
    
    
          console.log(e.message);
        }
      };

      //  post请求
      oPost.onclick = async function () {
    
    
        try {
    
    
          const re = await axios.post("/login", {
    
    
            data: {
    
    
              phone: "1300000001",
              pass: "11111",
            },
            timeout: 1000,
          });
          console.log("post", re);
        } catch (e) {
    
    
          console.log(e.message);
        }
      };

      // put请求
      oPut.onclick = async function () {
    
    
        try {
    
    
          const re = await axios.put("/update", {
    
    
            data: {
    
    
              userID: "zs",
              age: 18,
            },
            timeout: 1000,
          });
          console.log("put", re);
        } catch (e) {
    
    
          console.log(e.message);
        }
      };

      //  delete请求
      oDel.onclick = async function () {
    
    
        try {
    
    
          // const re = await axios.delete("/deleteuser", {
    
    
          //   params: {
    
    
          //     userID: "zs",
          //   },
          //   timeout: 1000,
          // });

          const re=await axios.delete('/deleteuser?userid=zs',{
    
    
            timeout: 1000,
          })



          console.log("del", re);

        } catch (e) {
    
    
          console.log(e.message);
        }
      };
    </script>

3. Valor padrão de configuração do Axios

 // axios全局默认配置(配置默认基础路径)
    axios.defaults.baseURL = "/api";

4. Crie uma instância de axios

 	const oGet = document.getElementById("get");
      const oPost = document.getElementById("post");
      const oPut = document.getElementById("put");
      const oDel = document.getElementById("del");

      // axios全局默认配置(配置默认基础路径)
      // axios.defaults.baseURL = "/api";

      // 创建实例 (创建一个副本)
      // const myReq = axios.create();
      // 创建实例,并传入配置项
      const myReq = axios.create({
    
    
        // 配置当前实例的基础路径
        baseURL: "/api",
        // 配置当前实际的超时时间
        timeout: 1000,
        // 配置当前实例的请求头
        headers: {
    
    
          "hello": "world",
        },
      });

      // 创造另一个实例,并传入配置项
      const yourReq = axios.create({
    
    
        // 配置当前实例的基础路径
        baseURL: "/sss",
        // 配置当前实际的超时时间
        timeout: 1000,
        // 配置当前实例的请求头
        headers: {
    
    
          "isAction": "no",
        },
      });
 const oGet = document.getElementById("get");
      const oPost = document.getElementById("post");
      const oPut = document.getElementById("put");
      const oDel = document.getElementById("del");

      // axios全局默认配置(配置默认基础路径)
      // axios.defaults.baseURL = "/api";

      // 创建实例 (创建一个副本)
      // const myReq = axios.create();
      // 创建实例,并传入配置项
      const myReq = axios.create({
    
    
        // 配置当前实例的基础路径
        baseURL: "/api",
        // 配置当前实际的超时时间
        timeout: 1000,
        // 配置当前实例的请求头
        headers: {
    
    
          "hello": "world",
        },
      });

      // 创造另一个实例,并传入配置项
      const yourReq = axios.create({
    
    
        // 配置当前实例的基础路径
        baseURL: "/sss",
        // 配置当前实际的超时时间
        timeout: 1000,
        // 配置当前实例的请求头
        headers: {
    
    
          "isAction": "no",
        },
      });

      //  get请求
      oGet.onclick = async function () {
    
    
        try {
    
    
          const re = await myReq.get("/user", {
    
    
            params: {
    
    
              userID: 001,
            },
          });
          console.log("get", re);
        } catch (e) {
    
    
          console.log(e.message);
        }
      };

5. interceptor de axios

 // 配置请求拦截器
      myReq.interceptors.request.use(
        (config) => {
    
    
          // 请求拦截器中拦截的是axios请求的配置项
          console.log("请求配置项", config);
          // 拦截配置项后,要把配置项return出去,否则请求无法进行
          return config;
        },
        (error) => {
    
    
          // 进入这个函数,说明请求未到达服务器,请求就有错,此时可以放回一个失败的promise对象,同时错误原因也返回出去,await等到这个失败的promise对象,可以知道请求有问题
          return Promise.reject(error);
        }
      );

      // 配置响应拦截器
      myReq.interceptors.response.use(
        (response) => {
    
    
          console.log("response", response);

          return response;
        },
        (error) => {
    
    
          //如果请求出现错误,则我们希望进入发请求的时候catch的异常处理
          //在发请求阶段得到响应后异常处理怎么进去呢?await等的时候失败的promise对象
          //所以我们可以把error包装成一个失败的promise对象,返回出去交给请求的地方处理
          console.log("响应拦截器失败处理函数");
          // 进入这个函数,说明请求到达服务器,回来的时候发现有错,返回这个失败的promise对象,可以知道请求有问题
          return Promise.reject(error);
        }
      );

6. Aplicação do interceptador axios

      // 配置请求拦截器
      myReq.interceptors.request.use(
        (config) => {
    
    
          // 请求拦截器中拦截的是axios请求的配置项
          console.log("请求配置项", config);
          // 应用1:此处进度条开始
          NProgress.start()
          
          return config;
        },
        (error) => {
    
    
          // 响应有问题,进度条也可以结束
          NProgress.done()
          // 进入这个函数,说明请求未到达服务器,请求就有错,此时可以放回一个失败的promise对象,同时错误原因也返回出去,await等到这个失败的promise对象,可以知道请求有问题
          return Promise.reject(error);
        }
      );

      // 配置响应拦截器
      myReq.interceptors.response.use(
        (response) => {
    
    
          console.log("response", response); //response是个对象 其中data是response回来的数据
          // 1.响应拦截器用法1:进度条执行结束 NProgress
          // 此处进度条结束
          NProgress.done()

          // 应用2:对响应的数据进行处理 server可以根据我们传过去的信息判断符不符合要求,response根据符不符合要求返回对应状态 我们可以通过判断状态 看是否提供对应页面
          //比如登录-无论登录成功还是失败,只要把结果响应回来了都算响应成功
          //但是对于我们来说,只有登录成功才叫响应成功,如果登录失败,我们就把他交给catch处理
          // 拦截配置项后,要把配置项return出去,否则请求无法进行
          if(response.data.code !== 200){
    
    
          return Promise.reject({
    
    message:response.data.msg})
          }

          return response.data;
        },
        (error) => {
    
    
          //如果请求出现错误,则我们希望进入发请求的时候catch的异常处理
          //在发请求阶段得到响应后异常处理怎么进去呢?await等的时候失败的promise对象
          //所以我们可以把error包装成一个失败的promise对象,返回出去交给请求的地方处理
          console.log("响应拦截器失败处理函数");
          // 进入这个函数,说明请求到达服务器,回来的时候发现有错,返回这个失败的promise对象,可以知道请求有问题
          return Promise.reject(error);
        }
      );

7. Solicitação de cancelamento do Axios

      // 取消axios请求 首先要拿到cancelToken构造函数,cancelToken构造函数在axios上
      // 注:cancelToken构造函数只能在axios拿 不能从axios实例上拿
      const CancelToken = axios.CancelToken;

      // 定义一个全局变量,用来保存局部中得等到取消请求的函数
      let cancel=null;
 	oCancel.onclick=function(){
    
    
        // 启动cancel函数
        // 函数里可以传入参数 请求理由
        cancel()
      }

domínio cruzado

1.JSONP

<button id="get">get-得到用户信息</button>
  <script>
    const oGet = document.getElementById('get');

    //回调函数,用来jsonp发请求的时候 携带回调函数给服务端 用来服务端调用
    function callback(value) {
    
    
      alert("我是callback:" + value)
    }

    let oScript = null;
    //get请求
    oGet.onclick = async function () {
    
    
      if (oScript) {
    
    
        oScript.remove()
      }
      //因为跨域原因无法直接请求,但是script标签的src可以跨域,我们选择创建一个script标签,帮助我们发送请求
      oScript = document.createElement("script");
      //把请求地址赋值给script标签的src属性
      oScript.src = "http://192.168.20.82:8888/user?userID=001&cb=callback";
      //把script标签插入页面中,则直接会把请求发送
      document.body.appendChild(oScript)
    }
  </script>

//服务器部分
app.get("/user", (req, res) => {
    
    

  const {
    
    
    userID,
    //拿到客户端发送的回调函数名称
    cb
  } = req.query;

  console.log("请求进来了", userID);

  //模拟客户端需要的数据
  const userToken = "abcdefghijk";
  //设置响应的数据类型是js类型
  res.set("Content-Type", "application/javascript;charset=utf-8")
  //给客户端的script标签响应一个js代码(js代码是调用了客户端发来的回调函数,并传入了数据作为实参)
  return res.send(`${
      
      cb}('${
      
      userToken}')`);


})

2.cors

//get请求
    oGet.onclick = async function () {
    
    
      try {
    
    
        //get请求参数放在配置中写
        const re = await axios.get("http://192.168.20.82:8888/user", {
    
    
          params: {
    
    
            userID: "001"
          }
        })
        console.log("最终的数据是1", re);
      } catch (e) {
    
    
        console.log("请求出现异常,异常信息是", e);
      }
    }
//服务器部分
app.get("/user", (req, res) => {
    
    
  const {
    
    
    userID
  } = req.query;

  //获取当前的origin地址
  const nowOrigin = req.headers.origin;

  //设置白名单
const allowOrigin = ["http://127.0.0.1:5501", "http://127.0.0.1:5505", "http://127.0.0.1:5500", "http://127.0.0.1:5504"]

  //判断当前的origin地址是否在白名单中 如果在 则设置跨域
  if (allowOrigin.includes(nowOrigin)) {
    
    
    //设置cors跨域
    res.set("Access-Control-Allow-Origin", nowOrigin)
  }

  if (userID === "001") {
    
    
    return res.json({
    
    
      code: 200,
      msg: "ok",
      data: {
    
    
        username: "laoli"
      }
    });
  }

  res.json({
    
    
    code: 201,
    msg: "用户id出错",
    data: null
  })
})

3. Procuração

cache

1. Cache obrigatório

Forçar cache:

  1. O cache forçado é o processo de procurar o resultado da solicitação no cache do navegador e decidir se podemos usar o cache com base no resultado da solicitação

  2. Simplificando, o navegador usa diretamente seu próprio cache sem fazer nenhuma solicitação

  3. Forçar o processo de configuração do cache

    • Quando o cliente solicita, ele precisa carregar o campo de cabeçalho da solicitação Cache-Control e o valor é max-age=XXXX (número de segundos)

    • Quando o servidor responde, ele também precisa carregar o campo de cabeçalho de resposta Cache-Contorl, o valor é max-age=XXXX (segundos)

    • Ao solicitar novamente na próxima vez, julgue se você atende às condições de cache obrigatórias; em caso afirmativo, leia o cache diretamente; caso contrário, vá para o cache de negociação

///服务器部分
app.get("/img", (req, res) => {
    
    
    const filePath = path.resolve(__dirname, "./01.jpg");
    const rs = fs.createReadStream(filePath);
    res.set("Cache-Control", "max-age=1000")
    rs.pipe(res)
})

2. Cache de negociação

Cache de negociação:

  1. O cliente envia uma solicitação ao servidor, solicitando um determinado arquivo de recurso
  2. O servidor responde ao cliente com o arquivo atual e adiciona dois campos no cabeçalho de resposta, que são o identificador exclusivo do arquivo (eTag) e o horário da última modificação (última modificação) do arquivo solicitado atualmente
  3. Depois de receber a resposta, o cliente precisa processar as informações sobre o cache de negociação, salvar o identificador exclusivo e a hora da última modificação do arquivo e também modificar o nome do campo, renomear eTag para if-none-match e renomear last-modified para if-modified-since
  4. Quando o cliente solicitar o recurso novamente, ele carregará os campos if-none-match e if-modified-since
  5. Depois de receber a solicitação, o servidor comparará if-none-match com sua própria eTag e if-modified-since com sua própria last-modified. Se forem iguais, ele responderá diretamente com um código de status 304 e solicitará a leitura do cache. Caso contrário, os dados de resposta carregarão a eTag mais recente e a última modificação
//服务器部分
app.get("/axios", async (req, res) => {
    
    
    console.log(1);
    const filePath = path.resolve(__dirname, "axios.min.js");
    //获取文件的唯一标识
    const Etag = etag(filePath);

    //获取文件的最后修改时间 fs.stat可以得到文件的详情
    const stat = promisify(fs.stat);
    const fileStat = await stat(filePath)
    console.log(fileStat.mtime.toGMTString());
    const lastModified = fileStat.mtime.toGMTString();

    //获取请求对象携带的if-modified-since if-none-match
    console.log(req.headers);
    const ifNoneMatch = req.headers["if-none-match"];
    const ifModifiedSince = req.headers['if-modified-since'];

    //把请求携带的信息和服务端文件的信息对比,如果有一个不一致,则重新响应文件

    if (ifNoneMatch !== Etag || ifModifiedSince !== lastModified) {
    
    
        //当读取新资源的时候,需要重新设置文件唯一标识 和最后修改时间的 响应头
        res.set("etag", Etag);
        res.set("last-modified", lastModified);
        return res.sendFile(filePath);
    }

    //如果上边的判断不成立,则需要读取缓存
    res.status(304).send();
})

3. Compressão

app.get("/", async (req, res) => {
    
    

    const filePath = path.resolve(__dirname, "./index.html")
    const rs = fs.createReadStream(filePath);
    //查看支持的压缩格式
    const accpetEncoding = req.headers['accept-encoding'];
    console.log(accpetEncoding)

    //根据客户端的支持的格式来进行不同的压缩
    if (accpetEncoding.includes("gzip")) {
    
    
        //zlib.createGzip()//创建一个gzip压缩的盒子,能够被流式写入
        const gzipFile = rs.pipe(zlib.createGzip()) //返回一个gizp压缩格式的可读流

        //告诉客户端我响应的压缩格式是什么
        res.set("content-encoding", "gzip")
        //把压缩好的文件写入到响应中
        return gzipFile.pipe(res) //22.1kb
    }
    
    //根据客户端的支持的格式来进行不同的压缩
    if (accpetEncoding.includes("deflate")) {
    
    
        //zlib.createDeflate()//创建一个gzip压缩的盒子,能够被流式写入
        const gzipFile = rs.pipe(zlib.createDeflate()) //返回一个gizp压缩格式的可读流

        //告诉客户端我响应的压缩格式是什么
        res.set("content-encoding", "deflate")
        //把压缩好的文件写入到响应中
        return gzipFile.pipe(res) //22.1kb
    }


    //没有压缩的响应
    rs.pipe(res) //99.1kb
})

Mecanismo de sondagem de eventos

1. Objeto global

2. mecanismo de sondagem de eventos nodejs

3. Mecanismo de sondagem de eventos do navegador

Função callback: a função A é usada como parâmetro da função B e a função A é chamada na função B

3.1 Classificação do código

  • Código de inicialização (código síncrono): definir temporizadores, vincular eventos, enviar ajax, etc.
  • Código de execução de retorno de chamada (código assíncrono): função de retorno de chamada de timer, função de retorno de chamada de evento, função de retorno de chamada ajax

3.2 Mecanismo de votação

  • O navegador executa o código síncrono antes de executar o código assíncrono.
  • Quando o código síncrono é executado, o código assíncrono é entregue ao módulo de gerenciamento do navegador para gerenciamento (módulo de gerenciamento de eventos, módulo de gerenciamento ajax, módulo de gerenciamento de timer).
  • Quando a função de retorno de chamada do código assíncrono precisar ser executada, a função de retorno de chamada será colocada na fila de retorno de chamada (fila de tarefas) para aguardar a execução.
  • Depois que o código de sincronização é executado, a thread principal irá para a fila de tarefas para pesquisar e retirar as tarefas (funções de retorno de chamada) na fila de tarefas para execução. A thread principal repete esta etapa continuamente, por isso é chamada de polling de evento.

4. Macrotarefas e Microtarefas

  1. O código assíncrono tem um relacionamento de prioridade. Alguns com prioridade mais alta são executados primeiro e alguns com prioridade mais baixa são executados posteriormente. Dividido em tarefas macro (macrotask) e tarefas micro (microtask)

  2. As microtarefas são iniciadas pelo próprio js: Promise.then/catch/fanally, o conteúdo após a instrução await, process.nextTick, queueMicrotask

  3. A tarefa de macro é iniciada pelo host: incluindo o script de código geral, setTimeout, setInterval, etc.

  4. O mecanismo js executa código assíncrono. As microtarefas serão executadas primeiro e, em seguida, as macrotarefas serão executadas

  5. O processo é como se segue:

    5.1 A pilha de execução seleciona a macro tarefa (normalmente script) que entra primeiro na fila, e executa seu código de sincronização até o final;

    5.2 Verificar se existem microtarefas na fila de microtarefas, caso positivo, será executado até que a fila de microtarefas fique vazia;

    5.3 Execute o código assíncrono na tarefa macro

    5.4 Se uma microtarefa for encontrada durante a execução, adicione-a à fila de tarefas da microtarefa

    5.5 Após a execução da macrotarefa atual, execute imediatamente todas as microtarefas na fila de microtarefas atual (executadas sequencialmente)

    5.6 Ao iniciar a próxima tarefa de macro (adquirida da fila de eventos)

modular

1. Original

2. modularização do commonJS

3. Especificação modular ES6

webpack

1. Seção de configuração básica

Cinco 'Guardiões'

  1. entrada: ponto de entrada

    • Ao empacotar, o primeiro arquivo fonte acessado indica qual módulo o webpack deve usar (tudo no webpack é um módulo) como o início da construção de seu gráfico de dependência interno

    • O padrão é src/index.js (pode ser especificado pelo arquivo de configuração)

    • webpack pode carregar as dependências de todo o projeto através da entrada

  2. saída: exportação

    • Após a embalagem, o nome do arquivo de saída
    • O padrão é dist/main.js (pode ser especificado pelo arquivo de configuração)
  3. carregador: carregador

    • O carregador permite que o webpack processe esses arquivos não JavaScript (o próprio webpack só pode analisar JavaScript)
  4. plug-ins: plug-in

    • Realize outras funções além do carregador (otimização e compactação de pacotes, etc.)
    • É o suporte do Webpack, que é usado para realizar funções ricas
  5. modo: modo

    • modo de produção produção
    • modo de desenvolvimento desenvolvimento

2. Use o arquivo de configuração do webpack

2.1 Configuração detalhada da embalagem

2.1.1 CSS de empacotamento

2.1.1.1 Embalagem básica
  1. O empacotamento CSS inclui: lógica de empacotamento, empacotamento MENOS, empacotamento em arquivos CSS independentes, adição de prefixos de estilo, validação de formato e compactação de CSS
  2. css-loader: Converte CSS para JS (saída css para o arquivo js empacotado)
  3. style-loader: monte o código JS contendo conteúdo CSS na tag de estilo da página
  4. CSS precisa ser introduzido no arquivo de entrada (import'./css/main.css')
  5. configuração do carregador: use: ['style-loader', 'css-loader']
  6. Instale npm i css-loader style-loader -D
rules[
    {
    
    
        //匹配后缀名
        test:/\.css$/i,
        use:[
            //use中loader加载是有顺序的,先上后下,注意有的loader需要按照顺序书写
            'style-loader',
            'css-loader'
        ]
    }
]
2.1.1.2 Embalagem menos
  1. less-loader: carregador para empacotar menos

  2. corresponder ao sufixo

  3. Configuração do carregador: use:['style-loader','css-loader','less-loader']

  4. Instale o npm i less less-loader -D

rules: [{
    
    
    test: /\.less$/i,
    use: [
        //use中loader加载是有顺序的,先下后上,注意有的loader需要按照顺序书写
        "style-loader",
        'css-loader',
        'less-loader'
    ]
}]

Reagir

1. Uso básico

1.1 Biblioteca js relacionada

  1. react.js: biblioteca principal do React.
  2. react-dom.js: fornece uma biblioteca de extensão de reação para manipular o DOM.
  3. babel.min.js: Uma biblioteca que analisa JSX em JS.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <!-- react的核心包 包含了react的核心内容 -->
    <script src="./js/react.development.js"></script>
    <!-- react中处理虚拟DOM和diffing算法的工具 -->
    <script src="./js/react-dom.development.js"></script>
    <!-- react中使用的jsx语法,babel用来编译jsx语法 -->
    <script src="./js/babel.min.js"></script>
  </head>
  <body>
    <div id="app"></div>
    <!-- 因为script标签中写的是jsx语法,所以我们要一如babel并且设置script标签的type为text/babel -->
    <script type="text/babel">
      // 定义一个虚拟DOM
      const vDOM = <h1>hello world</h1>;
      // 使用ReactDOM的render方法 把虚拟DOM渲染在真实DOM中
      ReactDOM.render(vDOM, document.getElementById("app"));
    </script>                     
  </body>
</html>

1.2 maneira js de criar DOM virtual

<!-- 此处用js写虚拟DOM所以不用定义type,默认就是text/javascript -->
<script>
      // 利用js创建一个虚拟DOM
      // const vDOM = React.createElement(
      //   "div",
      //   {
      //     className: "box",
      //     // data-index:1,
      //     // dataIndex: 1,
      //     "data-index": 1,
      //   },
      //   "欢迎"
      // );


      // 嵌套
      const vDOM = React.createElement(
        "div",
        {
          className: "box",
          // data-index:1,
          // dataIndex: 1,
          "data-index": 1,
        },
        React.createElement(
          "h1",
          null,
          React.createElement("span", null, "title")
        )
      );

      // 使用ReactDOM的render方法 把虚拟DOM渲染在真实DOM中
      ReactDOM.render(vDOM, document.getElementById("app"));

1.3 maneira jsx de criar DOM virtual

  <style>
      .red {
        color: red;
      }
    </style>
  </head>
  <body>
    <div id="app"></div>
<!-- 因为script标签中写的是jsx语法,所以我们要一如babel并且设置script标签的type为text/babel -->
    <script type="text/babel">
      const vDOM = (
        <div>
          <h3>boring</h3>
          <ul>
            <li className="red">boring1</li>
            <li>boring2</li>
            <li>boring3</li>
          </ul>
        </div>
      );
      // 使用ReactDOM的render方法 把虚拟DOM渲染在真实DOM中
      ReactDOM.render(vDOM, document.getElementById("app"));

1.4 DOM virtual e DOM real

DOM virtual:

  1. A essência é um objeto do tipo Object (objeto geral)

  2. O DOM virtual é relativamente "leve", enquanto o DOM real é relativamente "pesado" O DOM virtual é usado internamente pelo React, e não há necessidade de tantos atributos no DOM real.

  3. Mais cedo ou mais tarde, o DOM virtual será transformado em um DOM real pela reação e apresentado na página

<script type="text/babel" >
    //1.创建一个虚拟DOM
    const VDOM = <h1>Hello,React</h1>
    console.log(VDOM) //输出的是虚拟DOM,本质就是Object类型的一般对象
        
    const TDOM = document.getElementById('test')
    console.log(TDOM) //输出的是真实DOM
    debugger;
        
    //2.将虚拟DOM准备真实DOM渲染到页面
    ReactDOM.render(VDOM,document.getElementById('test'))
</script>

1.5 Sintaxe React JSX

expressão js: valor de retorno instrução js: sem valor de retorno

  1. Ao definir o DOM virtual, não escreva aspas

  2. Para misturar expressões js na estrutura do rótulo , você precisa usar {} para dividir, ou seja: {js expression}

  3. Ao especificar o nome da classe do rótulo, use className

  4. Para estilo inline, use style={ {}}, a camada externa de {} é para representar a área js e o {} interno representa o objeto e preencha a chave e o valor da chave, como font-size, que deve ser convertido em fontSize

  5. Só pode haver uma tag raiz

  6. a etiqueta deve estar fechada

  7. Inicial da etiqueta:

    • Se a primeira letra do tag for minúscula: o tag será convertido para um elemento com o mesmo nome no html, caso não exista esse elemento no html, será reportado um erro.

    • Se a primeira letra do rótulo estiver em maiúscula: indica que é o componente correspondente a ser renderizado pelo React.Se o componente não tiver sido definido, será reportado um erro.

1.6 Representação de valor na área js {} no JSX

{} em jsx obtém a resposta de diferentes tipos de valores

  1. string e número: inserir diretamente

  2. nulo, indefinido, verdadeiro, falso: diretamente vazio

  3. Array : Coloque os valores do array no DOM virtual em ordem

  4. Objeto: o objeto não é permitido como um valor na interpolação jsx

  <script type="text/babel">
      const arr = ["Angular", "React", "Vue"];
      const vDOM = (
        <div>
          <h1>前端框架</h1>
          <ul>
            {arr.map((item, index) => {
             //每一个虚拟DOM变化的地方都有一个key值,以便以后改变的时候有对比参照
              return <li key={index}>{item}</li>;
            })}
          </ul>
        </div>
      );

      ReactDOM.render(vDOM, document.getElementById("box"));

2. Componentes em React

2.1 Componentes funcionais

Se o construtor for instanciado, seu valor de retorno:

  1. Se não houver retorno no construtor ou um tipo de dados básico for retornado, a função retornará um objeto instanciado
  2. Se um tipo de dado complexo for retornado dentro do construtor, depois que a função for instanciada, a função retornará esses dados complexos
<script type="text/babel">
    //1.声明一个函数式组件
    function Dome(){
        console.log(this);//undefined
        return <h1>我是用函数定义的组件</h1>
    }
    //2.渲染组件到页面 	ReactDOM.render(<Dome/>,getElementById('app'))
</script>

Definição de componente funcional :

  1. Ao definir uma função de componente, a primeira letra do nome da função deve ser maiúscula
  2. A função do componente deve ter um valor de retorno e o valor de retorno é geralmente um DOM virtual
  3. Ao renderizar um componente de função para a página, o componente de função deve ser colocado na tag de fechamento automático, <nome da função/>

Características dos componentes funcionais :

  1. O this inside é indefinido (no modo estrito do babel)
  2. sem ciclo de vida
  3. Sem status

O processo de usar componentes de função:

  1. Encontre a declaração do componente e confirme se o tipo de componente é um componente de função
  2. Chame o componente de função (certifique-se de não chamar a função você mesmo, mas use o método de chamada de componente, caso contrário, não terá nenhuma característica de componente)
  3. A chamada do componente retorna um DOM virtual e o coloca na posição definida
  4. Converter DOM virtual em DOM real e renderizar na página

2.2 Componentes de classe

2.1.1 Conhecimento básico das aulas

Métodos e propriedades públicos: propriedades e métodos definidos em objetos instanciados

Métodos e propriedades privadas: variáveis ​​ou funções declaradas no construtor

Métodos e propriedades estáticos: As propriedades e métodos que podem ser obtidos sem instanciação em js são as propriedades e métodos do construtor

//创建一个Person类
class Person{
    
    
    //构造器方法或函数
    constructor(name,age){
    
    
        //构造器中的this指向类的实例对象
        //公有属性
        this.name=name;
        this.age=age
    }
    //一般方法 
    //公有方法
    speak(){
    
    
        //speak方法放在了Person类的原型对象上,供实例使用
        //通过Person实例调用speak时,speak中的this就是Person实例
        
        console.log(`我叫${
      
      this.name},年龄是${
      
      this.age}`)
    }   
}
//创建一个Person的实例对象
const p1=new Person('tom',18)
const p2=new Person('jerry',20)


//创建一个Student类,继承于Person类
class Student extends Person{
    
    
    //若和Person类父类属性一致,不需要写构造器,也可以正常继承
    constructor(name,age,gender){
    
    
        //super方法,将与Person类父类属性一致的属性作为参数
        super(name,age)
        this.gender=gender
    }
   //重写从父类继承过来的方法
   speak(){
    
    
       console.log(`这是Student的原型对象,我叫${
      
      this.name},年龄是${
      
      this.age},gender是${
      
      this.gender}`)
   }
}
const s1=new Student('zs',21,'nan')
s1.speak();

2.1.2 Componentes de classe

class Demo extends React.Component{
    render(){
        return <h1>我是标题</h1>
    }
}
ReactDOM.render(<Demo/>,document.getElementById('app'))

Definição de componentes de classe:

  1. Use class para declarar um componente de classe, herdando React.Component
  2. Deve haver um método de renderização no componente de classe para retornar um DOM virtual

método de renderização:

  1. O método render é definido no componente de classe e pertence ao método no objeto protótipo do componente de classe
  2. Quando o componente de classe é usado, o método render será chamado

O processo de usar componentes de classe:

  1. Encontre a declaração do componente e confirme se o tipo de componente é um componente de classe
  2. Instanciar o componente de classe para obter um objeto instanciado (instância do componente)
  3. A instância do componente chamará o método render no objeto protótipo do componente de classe. O método render retorna um DOM virtual e o coloca na posição definida
  4. Converter DOM virtual em DOM real e renderizar na página

3. Três atributos principais das instâncias de componente 1: estado

3.1 Escrita básica do estado

Atributo importante da instância do componente - estado

  1. estado é o atributo mais importante do objeto componente e o valor é um objeto (pode conter várias combinações de valor-chave)
  2. state representa o estado do componente atual, que contém os dados exigidos pelo componente atual
  3. Se o DOM virtual usar os dados no estado, modifique os dados no estado e o DOM virtual será atualizado de acordo
  4. O estado é definido para o objeto de instância e o estado precisa ser definido no construtor da classe this.state={XXX:XXX}

3.2 Método de modificação do estado

método:

  1. O estado não pode ser modificado diretamente, você precisa usar o método setState da instância do componente
  2. O parâmetro aceito por setState é um objeto, que será mesclado no estado original no futuro

prática:


3.3 Exercícios de adição e subtração de quantidades


4. Reagir ao evento de ligação

4.1 Eventos básicos de vinculação

class Demo extends React.Component{
    render(){
        return <button onClick={this.printWeather}>点击<button/>
    }
    //事件函数,位于Demo原型对象上
    printWeather(){
                console.log('今天天气好')
                console.log('this',this)//this为undefined
    }
            
 }
 ReactDOM.render(</Demo>,document.getElementById('app'))
   

Definição do evento:

  1. O nome é nomeado usando o método small hump e colocado no rótulo encadernado
  2. A função vinculada está localizada na área js{} de jsx
  3. A função geral é um método no protótipo ou na instância, que precisa ser chamado com este nome do método, e isso não pode ser omitido

Nesse evento de ligação básica, há um problema: isso na função de chamada de evento padrão no React é indefinido

4.2 Eventos de Vinculação Avançados

4.2.1 Método 1

class Demo extends React.Component{
    render(){
        this.printWeather=this.printWeather.bind(this)
        return <button onClick={this.printWeather}>点击<button/>
    }
    //事件函数,位于Demo原型对象上
    printWeather(){
                console.log('今天天气好')
                console.log('this',this)//this为调用的实例对象
    }
            
 }
 ReactDOM.render(</Demo>,document.getElementById('app'))

4.2.1 Método 2

class Demo extends React.Component{
    constructor(){
       super()//不可少,少了无法得到this
       this.printWeather=this.printWeather.bind(this)
    }
    render(){
        return <button onClick={this.printWeather}>点击<button/>
    }
    //事件函数,位于Demo原型对象上
    printWeather(){
                console.log('今天天气好')
                console.log('this',this)//this为调用的实例对象
    }
            
 }
 ReactDOM.render(</Demo>,document.getElementById('app'))

4.3 Eventos de ligação e atalhos de estado

Dois usos da função construtora:

  1. Passar parâmetros quando a instanciação é necessária
  2. isso aponta para a instância do componente

Mas basicamente não precisamos instanciar e passar parâmetros no react no futuro, e atribuir diretamente uma variável na sintaxe da classe, que pertence ao atributo da instância do componente

class Demo extends React.Component{
    //直接写在类class里面的属性,是实例的属性
   state={
       project:'js',
   }
   //事件函数的简写位置
   printWeather=this.printWeather.bind(this)
   render(){
        return <button onClick={this.printWeather}>点击<button/>
    }
    //事件函数,位于Demo原型对象上
    printWeather(){
                console.log('今天天气好')
                console.log('this',this)//this为调用的实例对象
    }
            
 }
 ReactDOM.render(</Demo>,document.getElementById('app'))

4.4 Como escrever eventos de ligação reais

4.4.1 Método 1


4.4.2 Método 2


4.5 evento objeto de evento do evento React

js evento:

  1. evento onput: acionado quando o conteúdo do formulário muda
  2. evento onchange: acionado quando o conteúdo do formulário muda e perde o foco
  3. O evento onChange do React é acionado quando o conteúdo do formulário atual muda

Objeto de evento de reação:

  1. O objeto de evento pode ser obtido diretamente
  2. Você não pode usar return false para evitar o evento padrão, você precisa usar preventDefault() diretamente para evitar o evento padrão
  3. e.target pode obter o elemento atual sem usar ref
      class App extends React.Component {
        render() {
          return (
            <div>
              <a href="http://www.baidu.com" onClick={(e)=>{e.preventDefault()}}></a>
              <button onClick={e=>{console.log(e.target.textContent)}}>点击可以获取内容</button>
              <input type="text" onChange={e=>{console.log(e.target.value)}} />
            </div>
          );
        }
      }
        
      ReactDOM.render(<App/>,document.getElementById('app'))

5. Três atributos centrais de instâncias de componentes II: props

5.1 Método básico de transferência de valor

adereços:

  1. É usado principalmente para transferir valores de fora para dentro do componente
  2. O método de escrita é escrever o atributo na tag do componente
  3. Componentes que aceitam props, o objeto props pode ser acessado na instância do componente
  4. Não modifique o valor de props, props são somente leitura
class Myself extends React.Component{
    //组件实例内部,可以通过this.props拿到从外部传过来的值,不要修改props的值,props是只读的
    render(){
        console.log(this.props)//看下图1
        let {name,age,gender}=this.props.mes;
        //如果真的要修改值,则可以结构出来变量,然后对变量进行修改
        name+='~';
        return (
            <ul>
                <li>我的名字是{name}</li>
                <li>我的性别是{age}</li>
                <li>我的年龄是{gender}</li>
            </ul>
        )
    }
}
class App extends React.Component{
    state={
        persons:{
            [name:'zs',age:20,gender:'n'],
            [name:'ls',age:21,gender:'w'],
            [name:'ws',age:23,gender:'w'],
        }
    }
    render(){
        const {persons}=this.state;
        return (
            <div>
                <Myself mes={persons[0]}/>
                <Myself mes={persons[1]}/>
                <Myself mes={persons[2]}/>
            </div>
        )
    }
}
ReactDOM.render=(<App/>,document.getElementById('app'))

objeto this.props: (Figura 1)

5.2 props passar valor

 class Myself extends React.Component {
        render() {
          console.log(this);
          console.log(this.props);
          const { name, age, gender } = this.props.mes;
          return (
            <ul>
              <li>姓名是:{name}</li>
              <li>年龄是:{age}</li>
              <li>性别是:{gender}</li>
            </ul>
          );
        }
      }
      class App extends React.Component {
        state = {
          persons: [
            { name: "zs", age: 20, gender: "nan" },
            { name: "ls", age: 18, gender: "wn" },
            { name: "wl", age: 25, gender: "nan" },
          ],
        };
        render() {
          const { persons } = this.state;
          return (
            <div>
              {persons.map((item, index) => {
                //每一个虚拟DOM变化的地方都有一个key值,以便以后改变的时候有对比参照
                return <Myself mes={item} key={index} />;
              })}
            </div>
          );
        }
      }

5.3 props transferência de valor em lote

{…obj} Ao escrever em jsx, você pode expandir o objeto em valor-chave (implementado por jsx+react, não pela sintaxe js)

 class Myself extends React.Component {
        render() {
          console.log(this);
          console.log(this.props);
          const { name, age, gender } = this.props;
          return (
            <ul>
              <li>姓名是:{name}</li>
              <li>年龄是:{age}</li>
              <li>性别是:{gender}</li>
            </ul>
          );
        }
      }
      class App extends React.Component {
        state = {
          persons: [
            { name: "zs", age: 20, gender: "nan" },
            { name: "ls", age: 18, gender: "wn" },
            { name: "wl", age: 25, gender: "nan" },
          ],
        };
        render() {
          const { persons } = this.state;
          return (
            <div>
              {persons.map((item, index) => {
                // {...obj}在jsx中书写时,可以展开对象为key-value(jsx+react实现,不是js语法)
                // 后面再给组件添加属性,也没有影响,this.props会直接展开为一个对象
                return <Myself {...item} index={index} key={index} />;
              })}
            </div>
          );
        }
      }

5.4 Configurar restrições de props

usar:

  1. Importar pacotes de terceiros
  2. Defina como o atributo estático do construtor para passar o valor.O componente de classe pode ser configurado estaticamente ou como um atributo estático do construtor externo.
      class Myself extends React.Component {
        static propTypes = {
          name: PropTypes.string.isRequired,
          age: PropTypes.number,
          gender: PropTypes.string,
          gender: PropTypes.oneOf(["nan", "wn"]),
        };
        render() {
          console.log(this);
          const { name, age, gender } = this.props;
          return (
            <ul>
              <li>姓名是:{name}</li>
              <li>年龄是:{age}</li>
              <li>性别是:{gender}</li>
            </ul>
          );
        }
      }

      //   Myself.propTypes={
      //     name:PropTypes.string.isRequired,
      //     age:PropTypes.number,
      //     gender:PropTypes.string,
      //     gender:PropTypes.oneOf(['nan','wn'])
      //   }
      class App extends React.Component {
        state = {
          persons: [
            { name: "zs", age: 20, gender: "nan" },
            { name: "ls", age: 18, gender: "wn" },
            { name: "wl", age: 25, gender: "nan" },
          ],
        };
        render() {
          const { persons } = this.state;
          return (
            <div>
              {persons.map((item, index) => {
                return <Myself {...item} key={index} />;
              })}
            </div>
          );
        }
      }

5.5 Como escrever adereços de componentes funcionais

processo:

  1. Determine o tipo de componente e confirme se é um componente funcional
  2. Depois de julgar como um componente funcional, chame a função
  3. Combine as propriedades do componente em um objeto e passe-o para a função como um parâmetro
function Myself({ name, age, gender }) {
        return (
          <ul>
            <li>姓名是:{name}</li>
            <li>年龄是:{age}</li>
            <li>性别是:{gender}</li>
          </ul>
        );
      };

      Myself.propTypes = {
        name: PropTypes.string.isRequired,
        age: PropTypes.number,
        gender: PropTypes.string,
      };

      const persons = [
        { name: "zs", age: 20, gender: "nan" },
        { name: "ls", age: 18, gender: "wn" },
        { name: "wl", age: 25, gender: "nan" },
      ];

      function App() {
        return (
          <div>
            {persons.map((item, index) => {
              let { name, age, gender } = item;
              return (
                <Myself name={name} age={age} gender={gender} key={index} />
              );
            })}
          </div>
        );
      };

      ReactDOM.render(<App />, document.getElementById("app"));

6. Três atributos principais de instâncias de componentes Três: refs

Cenário de uso:

  1. Gerenciar foco, seleção de texto ou reprodução de mídia
  2. desencadear animação forçada
  3. Integrar a biblioteca DOM de terceiros

6.1 Método de string de refs - Método 1:

Passos Básicos: Caminho da Corda

  1. Refs é usado principalmente pelo React para manipular o DOM
  2. O método string de ref, você só precisa definir o atributo ref no estoque DOM, e o valor é um nome personalizado XXX, que é semelhante à definição do ID para o rótulo
  3. Em outras posições do componente atual, o DOM atual pode ser obtido por meio de this.refs.XXX (o nome da configuração)
      class App extends React.Component {
        render() {
          console.log(this);
          return (
            <div>
              <input type="text" ref="oIpt" />
              <button onClick={this.printMsg}>打印输出内容</button>
            </div>
          );
        }
        printMsg = () => {
          console.log(this.refs.oIpt.value);
          console.log(this.refs);
        };
      }
	ReactDOM.render(<App />, document.getElementById("app"));   

6.2 Método de função de retorno de chamada de refs - Método 2

Etapas básicas: formulário de retorno de chamada

  1. Defina o atributo ref para o DOM buscado
  2. O valor do atributo ref é uma função (função de seta)
  3. Quando o atributo ref for lido, o React chamará a função de retorno de chamada do atributo ref e passará o DOM atual como o parâmetro real
  4. Atribua o parâmetro formal que aceita o parâmetro real a uma propriedade do objeto de instância, e essa propriedade é o DOM obtido
      class App extends React.Component {
        render() {
          console.log(this);
          return (
            <div>
              <input type="text" ref={(c) => (this.oIpt = c)} />
              <button onClick={this.printMsg}>打印输出内容</button>
            </div>
          );
        }
        printMsg = () => {
          console.log(this.oIpt);
          console.log(this.oIpt.value);
          console.log(this.refs);
        };
      }
	ReactDOM.render(<App />,document.getElementById("app"));

6.3 Como criar um container para refs - Método 3

Etapas básicas: criar modo de contêiner

  1. Primeiro, use o método React.createRef() para criar um contêiner
  2. Forneça este contêiner ao atributo ref do nó DOM a ser buscado
  3. Obtenha o DOM atual por meio de this.container.current
      class App extends React.Component {
        //设置一个ref的容器
        oIpt = React.createRef();
        render() {
          console.log(this);
          return (
            <div>
              <input type="text" ref={this.oIpt} />
              <button onClick={this.printMsg}>打印输出内容</button>
            </div>
          );
        }
        printMsg = () => {
          console.log(this.oIpt);
          console.log(this.oIpt.current.value);
          console.log(this.refs);
        };
      }

      ReactDOM.render(<App />, document.getElementById("app"));

7. React coleta dados de formulário

7.1 Formas não controladas

     class Demo extends React.Component {
        render() {
          return (
            <form action="###">
            用户名:
            <input type="text" ref={(c) => (this.user = c)} />
            <br />
            密码:
            <input type="text" ref={(c) => (this.pass= c)} />
            <br />
            <button onClick={this.login}>登录</button>
          </form>
          )

        }

        login = (e) => {
          e.preventDefault();
          console.log(`用户名是${this.user.value},密码是${this.pass.value}`);
        };
      }

7.2 Formas controladas

 class Demo extends React.Component {
        state = {
          user: "",
          pass: "",
        };
        render() {
          return (
            <form action="###">
              用户名:
              <input type="text" onChange={this.setUser} />
              <br />
              密码:
              <input type="text" onChnage={this.setPass} />
              <br />
              <button onClick={this.login}>登录</button>
            </form>
          );
        }
        setUser = (e) => {
          this.setState({ user: e.target.value });
        };

        setPass = (e) => {
          this.setState({ user: e.target.value });
        };

        login = (e) => {
          e.preventDefault();
          const { user, pass } = this.state;
          console.log(`用户名是${user},密码是${pass}`);
        };
      }

7.3 Escrita de alto nível de formulários controlados


      class Demo extends React.Component {
        state = {
          user: "",
          pass: "",
        };
        render() {
          return (
            <form action="###">
              用户名:
              <input type="text" onChange={this.setFormData("user")} />
              <br />
              密码:
              <input type="text" onChange={this.setFormData("pass")} />
              <br />
              <button onClick={this.login}>登录</button>
            </form>
          );
        }

        setFormData = (type) => {
          return (e) => {
            this.setState({ [type]: e.target.value });
          };
        };

        login = (e) => {
          e.preventDefault();
          const { user, pass } = this.state;
          console.log(`用户名是${user},密码是${pass}`);
        };
      }

7.4 Funções de ordem superior e currying de funções

Função de ordem superior: Se houver uma função A, A só precisa atender a qualquer uma das duas condições a seguir e A é uma função de ordem superior

  1. Se o parâmetro aceito pela função A for um parâmetro, como métodos relacionados à matriz, promessa, setTimeout
  2. Se a função A for chamada, o valor de retorno ainda é uma função, como a função de limitação antivibração

Currying de função: por meio da chamada de função, continue a retornar a função, realize o formulário de função que aceita parâmetros várias vezes

      // 函数柯里化
      function add(a) {
        return function (b) {
          return a + b;
        };
      }
      add(1)(2);

8. Ciclo de vida do componente React

8.1 Introdução ao ciclo de vida

 <div id='app'></div>
  <script type='text/babel'>
    class App extends React.Component{
      state = {
        opacity : 1
      }

      componentDidMount(){
        let {opacity} = this.state
        console.log(opacity);
        this.timer = setInterval(()=>{
          opacity -= 0.1;
          if(opacity<=0){
            opacity = 1
          }
          this.setState({opacity})
        },200)
      }

      render(){
        const {opacity} = this.state;
        return (
          <div>
            <p style={
   
   {opacity:opacity}}>React 太简单了,都是对勾</p>  
            <button onClick={()=>{ReactDOM.unmountComponentAtNode(document.getElementById('app'))}}>从入门到放弃</button>
          </div>
        )
      }

      componentWillUnmount(){
        clearInterval(this.timer)
      }
    }
    ReactDOM.render(<App/>,document.getElementById('app'))

8.2 Processo de montagem do ciclo de vida

A fase de inicialização é acionada por ReactDOM.render() — a primeira renderização

Se o processo 5 for acionado, a desinstalação do componente não aparecerá mais na página

  1. Processo de montagem do componente React 1-constructor constructor()
  2. Processo de montagem do componente React 2-O componente React está prestes a montar o componenteWillMount()
  3. Processo de montagem do componente React 3-render render()
  4. Processo de montagem do componente React 4-O componente React foi montado componentDidMount()
  5. Processo de montagem do componente React 5-O componente React está prestes a desmontar o componenteWillUnmount(), acionado por ReactDOM.unmountComponentAtNode(), o parâmetro é o nó pai da desmontagem do componente
 class App extends React.Component {
        // 挂载流程1 :constructor构造器
        constructor() {
          super();
          console.log("constructor 执行了");
        }

        // 挂载流程2 :React组件即将挂载
        componentWillMount() {
          console.log("componentWillMount执行了");
        }

        // 挂载流程3:React组件渲染
        render() {
          console.log("render 执行了");
          return (
            <div>
              <p>更新阶段 由组件内部this.setSate()或父组件重新render触发</p>
              <button
                onClick={() => {
                  ReactDOM.unmountComponentAtNode(
                    document.getElementById("app")
                  );
                }}
              >
                从入门到放弃
              </button>
            </div>
          );
        }

        // 挂载流程4:React组件已经完成挂载
        componentDidMount() {
          console.log(" componentDidMount执行了");
        }

        // 挂载流程5:React组件即将卸载 由ReactDOM.unmountComponentAtNode()触发,参数为组件从哪里卸载
        componentWillUnmount() {
          console.log(" componentWillUnmount执行了");
        }
      }
      ReactDOM.render(<App />, document.getElementById("app"));

8.3 Processo de atualização do ciclo de vida

Acionado por this.setSate() dentro do componente ou renderizado novamente do componente pai

  1. React componente update process 1-valve, que pode controlar a atualização do estado, a função render é suficiente para renderizar shouldComponentUpdate() deve retornar o valor booleano return true (render)/false (não renderizar); se false aqui, o seguinte processo 2-4 não acionará a execução

  2. Processo de atualização de componente React 2-componente atualizará componentWillUpdate(), this.forceUpdate() pode acionar atualização forçada

    Se o processo acionar uma atualização forçada, o processo anterior 1-shouldComponentUpdate() não terá efeito, não importa o que ele retorne

  3. Processo de atualização do componente React 3-render render()

  4. Processo de atualização do componente React Atualização de 4 componentes componentDidUpdate()

  5. Processo de atualização do componente React 5-O componente React está prestes a desmontar o componenteWillUnmount(), acionado por ReactDOM.unmountComponentAtNode(), o parâmetro é o nó pai da desmontagem do componente

class App extends React.Component {
        // 挂载流程1 :constructor构造器
        constructor() {
          super();
          console.log("constructor 执行了");
        }

        state = {
          count: 0,
        };

        // 挂载流程2 :React组件即将挂载
        componentWillMount() {
          console.log("componentWillMount执行了");
        }

        // 挂载流程3:React组件渲染
        render() {
          console.log("render 执行了");
          let { count } = this.state;
          return (
            <div>
              <h1>{count}</h1>
              <p>更新阶段 由组件内部this.setSate()或父组件重新render触发</p>
              <button onClick={() => {this.setState({count:++count})}}>+</button>
              <br />
              <button onClick={() => {this.forceUpdate()}}>强制更新</button>
              <button
                onClick={() => {
                  ReactDOM.unmountComponentAtNode(
                    document.getElementById("app")
                  );
                }}
              >
                从入门到放弃
              </button>
            </div>
          );
        }

        // 挂载流程4:React组件已经完成挂载
        componentDidMount() {
          console.log(" componentDidMount执行了");
        }
        //更新流程2:阀门,可以控制state更新后,render函数是否渲染
        shouldComponentUpdate() {
          console.log("---componentShouldUpdate执行了---");
          return true;
        }

        // 更新流程3:即将更新 this.forceUpdate()方法可以要求强制更新
        componentWillUpdate() {
          console.log("---componentWillUpdate执行了---");
        }

        // 更新流程4:更新已完成 
        componentDidUpdate(){
            console.log("---componentDidUpdate执行了---");
        }

        // 挂载流程5:React组件即将卸载 由ReactDOM.unmountComponentAtNode()触发,参数为组件从哪里卸载
        componentWillUnmount() {
          console.log(" componentWillUnmount执行了");
        }
      }

      ReactDOM.render(<App />, document.getElementById("app"));

8.4 Processo de atualização pai-filho do ciclo de vida

Adicionado recentemente ao processo de atualização do filho: componentWillReceiveProps()

  1. No processo de renderização inicial, o pai e o filho renderizam normalmente, e o processo de renderização filho não executará a função de vida acima;
  2. Posteriormente, desde que o componente pai seja renderizado novamente, essa função de ciclo de vida deve ser executada independentemente de aceitar ou não as props do componente pai, e todos os processos de atualização também devem ser executados
 class App extends React.Component {
        state = {
          weather: "hot",
          count: 0,
        };

        render() {
          let { weather ,count } = this.state;
          return (
            <div>
                <p>{weather},{count}</p>
                <button onClick={()=>{this.setState({weather:'cool'})}}>改变天气</button>
                <br/>
                <button onClick={()=>{this.setState({count:++count})}}>改变count</button>
                <p>我是父组件 我下边是子组件</p>
                <Son />
            </div>
            );
        }
        }
                


      class Son extends React.Component{
          render (){
              return (
                  <div>
                    <button onClick={()=>{ReactDOM.unmountComponentAtNode(document.getElementById('app'))}}>卸载组件</button>
                </div>
                     
              )
            }
            componentWillMount(){
                console.log("即将渲染了");
            }
    
            componentDidMount(){
                console.log("已经渲染了");
            }
    
            //此步骤:子组件渲染流程的时候是不执行的
            // 父组件只要重新渲染,无论是否接受父组件的props都要执行这个生命周期函数
            componentWillReceiveProps(){
                console.log('即将接受props');
            }
    
    
            shouldComponentUpdate(){
                console.log("---shouldComponentUpdate---");
                return false;
            }
    
            componentWillUpdate(){
                console.log("---componentWillUpdate---");
            }
    
            componentDidUpdate(){
                console.log('---componentDidUpdate---');
            }
    
            componentWillUnmount(){
                console.log('---componentWillUnmount---');
            }
        }
        ReactDOM.render(<App />, document.getElementById("app"));

9. DOM virtual e algoritmo de diferenciação de DOM

Algoritmo de Diferença

 /* 
      //旧
      <li key=0>laowang input</li>
      <li key=1>laozhang input</li>
      <li key=2>laojun input</li>

      //新
      <li key=4>laoyang input</li>
      <li key=0>laowang input</li>
      <li key=1>laozhang input</li>
      <li key=2>laojun input</li>
      
    
    
    
    
    */
    class App extends React.Component{
      state = {
        person:[

          {id:"001",name:"laowang"},
          {id:"002",name:"laozhang"},
          {id:"003",name:"laojun"}
        ]
      }
      render(){
        const {person}  = this.state
        return (
          <div>
            <button onClick={this.addPerson}>添加</button> 
            <ul>
              {
                person.map((item,index)=>{
                  return <li key={item.id}>{item.name} <input type="text"/></li>
                })
              }   
            </ul>
          </div>
        )
      }

      addPerson = () => {
        const {person} = this.state;
        person.unshift({id:"004",name:"laoyang"})
        this.setState({person})
      }
    }
    ReactDOM.render(<App/>,document.getElementById('app'))

10. Andaimes

10.1 useState

etapa:

  1. const [o nome da variável a ser salva, o nome do método para modificar a variável]=useState(conteúdo da variável)
  2. Expor com useContext para atingir o objetivo da entrega

10.2 useContext

etapa:

  1. componente pai createContext
  2. Use createContext() para criar o objeto de componente de instância correspondente e expô-lo ao mesmo tempo
  3. Coloque os subcomponentes para transferir dados na tag <nome do objeto do componente da instância.Provider><nome do objeto do componente da instância.Provider/>
  4. Existe um valor de atributo na tag do componente, você pode preencher os dados a serem passados ​​para o subcomponente value={ { }}
  5. Introduza useContext no subcomponente, use useContext (nome do objeto do componente da instância) para receber dados

10.3 useEffect

uso:

  1. useEffect função de efeito colateral geral, pode substituir componentDidMount, componentDidUpdate, componentWillUnmount no ciclo de vida
  2. O primeiro parâmetro aceito pelo useEffect é uma função. Caso não haja um segundo parâmetro, esta função será executada seja uma atualização ou uma montagem inicial
  3. useEffect aceita o segundo parâmetro como uma matriz, que pode limitar qual estado na matriz muda e, em seguida, executa a função useEffect. Se for uma matriz vazia, não importa como o estado é atualizado, ele não será executado novamente
  4. Você pode definir vários useEffects e também é recomendável que diferentes funções tenham diferentes useEffects
  5. useEffect retorna uma função que será chamada antes que o componente seja descarregado

10.4 Versão antiga do React-Router-DOM

10.4.1 Configuração básica

  • Aninhar um componente BrowserRouter fora do componente App
  • Toda a navegação usa o atributo to dentro do componente Link para definir o endereço de roteamento
  • A área de exibição de roteamento usa o componente Rota, e o caminho é usado para corresponder ao caminho. O atributo do componente é usado para determinar o componente

10.4.2 NavLink

  • Quando o componente de navegação clica e precisa mudar de estilo, você pode usar o componente NavLink para a navegação
  • O componente NavLink fornece o atributo activeClassName, que contém a classe que deve ser carregada após obter o foco

10.4.3 Componente de Link Personalizado

  • Personalize um componente Link, apenas passe o valor através de props
  • O conteúdo do rótulo do componente também está disponível em props.children

10.4.4 Componente do interruptor

  • Múltiplas Rotas podem ser colocadas em um componente Switch. Neste momento, desde que uma Rota seja correspondida, todo o Switch será encerrado.
  • Pode ter vários interruptores

10.4.5 Correspondência estrita

  • Existe um atributo exato no componente Route, o valor é um valor booleano, que é responsável por habilitar a correspondência estrita
  • Correspondência estrita: (to:/home/news) (caminho:/home) não pode ser correspondido neste momento
  • Geralmente não habilitamos correspondência estrita, caso contrário, a rota secundária não pode ser acessada

10.4.6 Redirecionar

  • redirecionar
  • Quando todas as rotas não forem correspondidas, o componente de redirecionamento será usado automaticamente e o componente de redirecionamento redirecionará o endereço para um endereço padrão predefinido

10.4.7 Particionamento de Componentes

  • Componentes de roteamento (páginas) e componentes gerais (componentes)
  • As props do componente geral é o valor que passamos
  • Os props do componente de roteamento são um objeto composto de objetos como correspondência de localização de histórico, que fornece muitos métodos para operar o roteamento

10.4.8 Roteamento secundário e terciário

  • Você pode escrever tão normal quanto no primeiro nível
  • Quando o roteamento é alternado, o padrão é criar e destruir componentes

10.4.9 parâmetros de roteamento de parâmetros

  • A navegação de roteamento escreve a variável /user/:id/:say que aceita parâmetros
  • Os dados /user/001/hello são necessários para unir o caminho no Link
  • Use props.match.params no componente de roteamento para obter os dados desejados

10.4.10 parâmetros de roteamento de pesquisa

  • Caminho de escrita normal da navegação de roteamento
  • Concatenar dados no caminho do link em uma string de consulta
  • Use props.location.search no componente de roteamento para obter a string de consulta desejada
  • Converter em objeto pela ferramenta qs

10.4.11 passagem de parâmetro de roteamento de estado

  • O atributo to da navegação de rota é escrito como um objeto {pathname: route path state: data}
  • Obtenha os dados desejados por meio de props.location.state no componente de roteamento

10.4.12 Navegação de Roteamento Programático

  • O link é convertido em um rótulo por padrão. Em muitos casos, um rótulo não é usado ou um salto de roteamento é necessário quando não há necessidade de clicar.
  • props.history.push(path, state) para navegação de roteamento programático

10.4.13 substituir

  • Na navegação de roteamento declarativa, use o atributo replace do componente Link como um valor booleano para determinar se deve substituir o registro do histórico
  • Use o método props.history.push/replace na navegação de roteamento programático para determinar se deve sair do histórico

10.4.14 Histórico para frente e para trás

  • Padrão props.history.go/goBack/goForward

10.4.15 com Roteador

  • Permite que componentes gerais tenham objetos props para componentes de roteamento
  • Ao expor o componente, coloque o nome do componente diretamente no método withRouter para expô-lo

10.5 React-Router-DOM v6 versão

10.5.1 NavegadorRoteador

  • BrowserRouterOs componentes são melhor colocados fora de todos os componentes de nível superior, de modo a garantir que os componentes internos não cometam erros ao usar o Link para saltos de roteamento (em comparação com a v5, não há alteração)

10.5.2 Comutador renomeado para Rotas

10.5.3 Redação básica

  • O componente Link é usado para definir opções
  • O componente Route é usado para definir a resposta (o componente carregado dentro da rota usa o valor do atributo do elemento como a tag do componente correspondente)
  • NavLink组件ou pode receber uma função, a função recebe um , e o estilo pode styleser ajustado de acordo com este parâmetroclassNameisActive参数
<NavLink
           to="/about"
           className={({ isActive }) => {
      			return isActive ? "list-group-item active" : "list-group-item";
      	}}
  >
      About
  </NavLink>
  <NavLink
           to="/home"
           className={({ isActive }) => {
      		return isActive ? "list-group-item active" : "list-group-item";
      	 }}
  >
      Home
  </NavLink>


  <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/home" element={<Home />} />
      <Route path="/about" element={<About />} />
  </Routes>

10.5.4 Passagem de parâmetro de roteamento

  • params passar parâmetros
    • O método de passagem de valor permanece inalterado
    • forma de receber o valor
  import { useParams } from "react-router-dom";
    console.log(useParams());
  • parâmetro de pesquisa
    • O método de passagem de valor permanece inalterado
    • forma de receber o valor
   import { useLocation } from "react-router-dom";
    console.log(useLocation());
  • passagem de parâmetro de estado
    • Navegar usando o roteamento programático
import { useNavigate } from "react-router-dom";
    <button
      onClick={() => {
        to("/list", { state: { say: "byebye" } });
      }}
    ></button>;

​ Forma de recebimento do valor

import { useLocation } from "react-router-dom";
    console.log(useLocation());
  • roteamento secundário
    • Escreva o caminho na Rota da rota de primeiro nível como:<Route path="/about/*" element={<About />} />
    • no roteamento secundário
 <h3>我是About的内容</h3>
    <Link to="/about/hello">hello</Link>
    <Link to="/about/world">world</Link>

    <Routes>
        <Route path="hello" element={<Hello />}></Route>
        <Route path="world" element={<World />}></Route>
    </Routes>

Regex:

O objeto regular chama o método de teste, passa uma string e retorna um valor booleano (veja se o caractere não atende aos requisitos regulares)

Corda:

Chame o método match com uma string, passe as regras normais e retorne um array de strings que atendam aos requisitos

Chame o método replace para substituir a palavra-chave

método de expressão regular

método de string

método de matriz

método de objeto

Acho que você gosta

Origin blog.csdn.net/weixin_66029924/article/details/127234686
Recomendado
Clasificación