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
-
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')
-
Promise tem três métodos de protótipo de então, pegar e finalmente
-
Existem seis métodos estáticos em Promise: all, allSettled, race, any, rejeitar e resolver
-
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
-
A instanciação de promessa recebe uma função de retorno de chamada como parâmetro
-
A função de retorno de chamada Promise aceita dois parâmetros, reslove e rejeitar (ambos são funções)
-
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.
-
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
. -
O estado do objeto de instância Promise só pode mudar de pendente para outros estados
1.3 Objeto de instanciação de promessa
-
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
-
-
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
- 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
- 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
- As funções de retorno de chamada no método then são todas executadas de forma assíncrona
- 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
- Por padrão, um objeto de promessa com status de sucesso é retornado e o valor é o valor retornado
- 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
- Se então retorna um objeto de promessa, o valor de retorno é vinculado ao objeto de promessa
- 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
- Consistente com a segunda função de callback de então
- 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
- 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
- a função de retorno de chamada de finalmente não aceita nenhum parâmetro
2.3.2 finalmente retorna o valor:
-
Penetração direta por padrão
-
Se ocorrer uma exceção em finalmente, um objeto de promessa com falha será retornado, cujo valor é a informação da exceção
-
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()
- retorna um objeto de promessa
- 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
- 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()
- retorna um objeto de promessa
- O objetivo principal é detectar se todos os objetos de promessa são executados (seja com sucesso ou com falha)
- 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()
- retorna um objeto de promessa
- O objeto de promessa retornado é conectado ao primeiro objeto de promessa no parâmetro que muda de estado
3.4 método any()
- retorna um objeto de promessa
- O objeto de promessa retornado está vinculado ao objeto de promessa mais rápido e bem-sucedido no parâmetro
- 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()
- 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)
- 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 ()
- 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)
- 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
- função assíncrona retorna um objeto de promessa
- 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)
- 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
- 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
- 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:
- 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:
-
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
-
Simplificando, o navegador usa diretamente seu próprio cache sem fazer nenhuma solicitação
-
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:
- O cliente envia uma solicitação ao servidor, solicitando um determinado arquivo de recurso
- 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
- 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
- Quando o cliente solicitar o recurso novamente, ele carregará os campos if-none-match e if-modified-since
- 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
-
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)
-
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
-
A tarefa de macro é iniciada pelo host: incluindo o script de código geral, setTimeout, setInterval, etc.
-
O mecanismo js executa código assíncrono. As microtarefas serão executadas primeiro e, em seguida, as macrotarefas serão executadas
-
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'
-
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
-
-
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)
-
carregador: carregador
- O carregador permite que o webpack processe esses arquivos não JavaScript (o próprio webpack só pode analisar JavaScript)
-
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
-
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
- 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
- css-loader: Converte CSS para JS (saída css para o arquivo js empacotado)
- style-loader: monte o código JS contendo conteúdo CSS na tag de estilo da página
- CSS precisa ser introduzido no arquivo de entrada (import'./css/main.css')
- configuração do carregador: use: ['style-loader', 'css-loader']
- 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
-
less-loader: carregador para empacotar menos
-
corresponder ao sufixo
-
Configuração do carregador: use:['style-loader','css-loader','less-loader']
-
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
- react.js: biblioteca principal do React.
- react-dom.js: fornece uma biblioteca de extensão de reação para manipular o DOM.
- 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:
-
A essência é um objeto do tipo Object (objeto geral)
-
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.
-
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
-
Ao definir o DOM virtual, não escreva aspas
-
Para misturar expressões js na estrutura do rótulo , você precisa usar {} para dividir, ou seja: {js expression}
-
Ao especificar o nome da classe do rótulo, use className
-
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
-
Só pode haver uma tag raiz
-
a etiqueta deve estar fechada
-
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
-
string e número: inserir diretamente
-
nulo, indefinido, verdadeiro, falso: diretamente vazio
-
Array : Coloque os valores do array no DOM virtual em ordem
-
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:
- Se não houver retorno no construtor ou um tipo de dados básico for retornado, a função retornará um objeto instanciado
- 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 :
- Ao definir uma função de componente, a primeira letra do nome da função deve ser maiúscula
- A função do componente deve ter um valor de retorno e o valor de retorno é geralmente um DOM virtual
- 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 :
- O this inside é indefinido (no modo estrito do babel)
- sem ciclo de vida
- Sem status
O processo de usar componentes de função:
- Encontre a declaração do componente e confirme se o tipo de componente é um componente de função
- 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)
- A chamada do componente retorna um DOM virtual e o coloca na posição definida
- 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:
- Use class para declarar um componente de classe, herdando React.Component
- Deve haver um método de renderização no componente de classe para retornar um DOM virtual
método de renderização:
- O método render é definido no componente de classe e pertence ao método no objeto protótipo do componente de classe
- Quando o componente de classe é usado, o método render será chamado
O processo de usar componentes de classe:
- Encontre a declaração do componente e confirme se o tipo de componente é um componente de classe
- Instanciar o componente de classe para obter um objeto instanciado (instância do componente)
- 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
- 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
- estado é o atributo mais importante do objeto componente e o valor é um objeto (pode conter várias combinações de valor-chave)
- state representa o estado do componente atual, que contém os dados exigidos pelo componente atual
- Se o DOM virtual usar os dados no estado, modifique os dados no estado e o DOM virtual será atualizado de acordo
- 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:
- O estado não pode ser modificado diretamente, você precisa usar o método setState da instância do componente
- 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:
- O nome é nomeado usando o método small hump e colocado no rótulo encadernado
- A função vinculada está localizada na área js{} de jsx
- 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:
- Passar parâmetros quando a instanciação é necessária
- 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:
- evento onput: acionado quando o conteúdo do formulário muda
- evento onchange: acionado quando o conteúdo do formulário muda e perde o foco
- O evento onChange do React é acionado quando o conteúdo do formulário atual muda
Objeto de evento de reação:
- O objeto de evento pode ser obtido diretamente
- Você não pode usar return false para evitar o evento padrão, você precisa usar preventDefault() diretamente para evitar o evento padrão
- 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:
- É usado principalmente para transferir valores de fora para dentro do componente
- O método de escrita é escrever o atributo na tag do componente
- Componentes que aceitam props, o objeto props pode ser acessado na instância do componente
- 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:
- Importar pacotes de terceiros
- 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:
- Determine o tipo de componente e confirme se é um componente funcional
- Depois de julgar como um componente funcional, chame a função
- 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:
- Gerenciar foco, seleção de texto ou reprodução de mídia
- desencadear animação forçada
- Integrar a biblioteca DOM de terceiros
6.1 Método de string de refs - Método 1:
Passos Básicos: Caminho da Corda
- Refs é usado principalmente pelo React para manipular o DOM
- 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
- 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
- Defina o atributo ref para o DOM buscado
- O valor do atributo ref é uma função (função de seta)
- 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
- 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
- Primeiro, use o método React.createRef() para criar um contêiner
- Forneça este contêiner ao atributo ref do nó DOM a ser buscado
- 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
- Se o parâmetro aceito pela função A for um parâmetro, como métodos relacionados à matriz, promessa, setTimeout
- 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
- Processo de montagem do componente React 1-constructor constructor()
- Processo de montagem do componente React 2-O componente React está prestes a montar o componenteWillMount()
- Processo de montagem do componente React 3-render render()
- Processo de montagem do componente React 4-O componente React foi montado componentDidMount()
- 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
-
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
-
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
-
Processo de atualização do componente React 3-render render()
-
Processo de atualização do componente React Atualização de 4 componentes componentDidUpdate()
-
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()
- 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;
- 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:
- 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)
- Expor com useContext para atingir o objetivo da entrega
10.2 useContext
etapa:
- componente pai createContext
- Use createContext() para criar o objeto de componente de instância correspondente e expô-lo ao mesmo tempo
- 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/>
- Existe um valor de atributo na tag do componente, você pode preencher os dados a serem passados para o subcomponente value={ { }}
- Introduza useContext no subcomponente, use useContext (nome do objeto do componente da instância) para receber dados
10.3 useEffect
uso:
- useEffect função de efeito colateral geral, pode substituir componentDidMount, componentDidUpdate, componentWillUnmount no ciclo de vida
- 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
- 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
- Você pode definir vários useEffects e também é recomendável que diferentes funções tenham diferentes useEffects
- 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
BrowserRouter
Os 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 podestyle
ser ajustado de acordo com este parâmetroclassName
isActive参数
<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
- Escreva o caminho na Rota da rota de primeiro nível como:
<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