Maison > interface Web > js tutoriel > Utilisation de MiniSearch dans React : recherche avancée et filtrage simplifiés

Utilisation de MiniSearch dans React : recherche avancée et filtrage simplifiés

Patricia Arquette
Libérer: 2024-11-29 04:26:09
original
247 Les gens l'ont consulté

Chapitre un
Qu'est-ce que MiniSearch et comment améliore-t-il le filtrage JavaScript ?

MiniSearch est une bibliothèque JavaScript légère pour la recherche en texte intégral dans des ensembles de données petits à moyens. Il indexe les données et permet des fonctionnalités de recherche avancées telles que la correspondance floue, les recherches de préfixes, le classement par pertinence et la pondération des champs.

Et par correspondance floue, la correspondance floue signifie trouver des mots ou des parties de mots même s'ils ne sont pas tapés exactement correctement. Par exemple, si vous tapez « wlf » au lieu de « loup », une recherche floue trouvera toujours des résultats incluant « loup ».

Et par recherche de préfixe, la recherche de préfixe recherche des mots ou des parties au début de quelque chose. Ainsi, si vous recherchez « voiture », une recherche par préfixe trouvera également « chariot » ou « gazéifié ».

Ces fonctionnalités que nous offre miniSearch nous aident à trouver ce que nous recherchons même s'il n'est pas parfaitement saisi. Ainsi, cela rend les résultats de recherche plus précis et utiles.

Et pourquoi en avons-nous besoin ?

Le premier avantage que cela nous offre est les fonctionnalités de recherche avancées :
Le filtrage traditionnel correspond généralement à des valeurs exactes ou à des modèles de base. MiniSearch fournit une correspondance de texte plus sophistiquée. Ces fonctionnalités de recherche avancées peuvent deviner vos erreurs, par exemple si vous tapez « bak » au lieu de « back », MiniSearch sait ce que vous voulez dire.

Un autre avantage par rapport au filtrage/recherche traditionnel est le classement par pertinence :
MiniSearch classe les résultats en fonction de leur pertinence, améliorant ainsi l'expérience utilisateur dans les applications gourmandes en recherche. Cela garantit que les résultats les plus pertinents apparaissent en premier. Par exemple, si vous recherchez « JavaScript », le système donne la priorité aux documents ou aux éléments qui mentionnent « JavaScript » de manière visible ou fréquente, améliorant ainsi l'expérience de recherche globale.

Maintenant que cela est réglé, créons une application React.js de base et voyons comment nous utilisons MiniSearch côté client.

Chapitre deux
Comment configurer une application React avec MiniSearch :

Ok, mettons en place notre projet. Et pour que nous puissions mettre en place le projet, j'utiliserai le vite fiable. L'éditeur de texte ou IDE que j'utiliserai est le méchant, l'éditeur de code Visual Studio.

Je vais configurer Vite avec ces invites dans le terminal. Et je dois dire que j'ai déjà créé ces dossiers auparavant :

Pour accéder au dossier visual_testing :

PS C:\Users\vawkei\Documents> cd .\visual_testing\
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Pour accéder au dossier building-in-public-slack :

PS C:\Users\vawkei\Documents\visual_testing> cd .\building-in-public-slack\
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Pour accéder au dossier minisearch :

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack> cd .\minisearch\
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Pour accéder au dossier frontend :

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch> cd .\frontend\
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ensuite, dans le dossier frontend, je vais installer Vite, car c'est là que nous voulons qu'il soit, dans notre dossier frontend.

Je vais l'installer avec cette ligne de code :

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm create vite@latest .
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ensuite, cela me donne le choix parmi des options, j'utiliserai Javascript et React ici. React comme framework et Javascript comme variante.

Une fois terminé. Je serai accueilli par ceux-ci :

PS C:\Users\vawkei\Documents> cd .\visual_testing\
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ensuite, j'installerai le package minisearch et le package react-router-dom. Bien que je n'aurai pas besoin du package React-Router dans ce tutoriel :

PS C:\Users\vawkei\Documents\visual_testing> cd .\building-in-public-slack\
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Installera également scss en exécutant ce code :

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack> cd .\minisearch\
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Maintenant, cela n’aura pas de backend. Au lieu de cela, je placerai les données à l'extérieur, quelque part. Nous en reparlerons plus tard.

Donc, si nous démarrons maintenant notre petite application en exécutant npm run dev dans le terminal, nous obtiendrons une réponse comme celle-ci dans le terminal :

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch> cd .\frontend\
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Il faudra suivre le lien (ctrl clic) là-dessus :

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm create vite@latest .
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Si on ctrl clique sur :

Done. Now run:

 npm install
 npm run dev
Copier après la connexion
Copier après la connexion

Nous allons être accueillis par une page qui ressemble à ceci dans le navigateur :

Using MiniSearch in React: Advanced Search and Filtering Made Easy

Chapitre trois
Nettoyage de l'App.jsx":

L'App.jsx ressemblerait initialement à ceci :

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm install minisearch react-router-dom
Copier après la connexion
Copier après la connexion

Et c'est ce qui est responsable du logo React et du logo Vite que nous avons vu sur la photo ci-dessus. Cependant, nous ne voulons pas travailler avec le contenu actuel d'App.jsx, nous devons donc le nettoyer. Après l'avoir nettoyé, le contenu devrait ressembler à ceci :

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm install sass
Copier après la connexion
Copier après la connexion

Cela nous laissera avec un écran vide dans notre navigateur.

Chapitre quatre
Préparation du projet : création d'une base de données simulée :

Normalement, je devrais obtenir des données à partir d'une base de données, d'une superbase, d'une firebase ou autre. Ou même une API quelque part. Je vais récupérer mes données à partir d'un fichier json. Je vais l'appeler, db.json. Le fichier vivra dans un dossier appelé data, qui devrait être à la racine de notre application. Le contenu du fichier db ressemblerait à ceci :

 VITE v5.4.11  ready in 332 ms

 ➜  Local:   http://localhost:5173/
 ➜  Network: use --host to expose
 ➜  press h + enter to show help
Copier après la connexion
Copier après la connexion

Ouais ! Votre pote est un joueur.???. Et juste pour vous dire que je meurs d'envie de jouer à ces titres.
Maintenant, laissez-moi parcourir le fichier très rapidement.

Le fichier contient un objet JSON avec un tableau d'entrées de blog. Chaque objet représente un jeu vidéo et possède les champs suivants :

titre :Le nom du jeu vidéo.

texte : Une brève description du jeu.

auteur : La personne qui a écrit l'entrée du blog.

id : Un identifiant unique pour chaque article de blog. par exemple : "1", "2", "3"

Chapitre cinq
Configuration d'un backend simulé avec un serveur JSON :

Pour que la base de données soit opérationnelle, nous devrons nous rendre sur notre terminal. Nous pouvons ouvrir un autre port dans le terminal et exécuter cette commande dans le terminal :

http://localhost:5173/
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

La réponse que nous obtiendrons est la suivante :

http://localhost:5173/
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Cela signifie que notre serveur/base de données fictif est prêt à l'action.

Chapitre six
Construire le frontend : création du composant BlogList :

Très bien ! Maintenant, je vais aller dans le dossier src et y créer un dossier de composants. Dans le dossier du composant, je vais créer un autre dossier, appelé blog. Dans le dossier blog, je vais créer un autre dossier appelé blog-list. Et dans ce dossier liste de blogs, je vais créer deux fichiers. BlogList.jsx et BlogList.module.scss. Je n’aborderai pas ce dernier ici.

Ensuite, définissez le composant BlogList comme ceci :

PS C:\Users\vawkei\Documents> cd .\visual_testing\
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Chapitre sept
Routage dans React : rendu de la liste de blogs dans App.jsx :

Maintenant que nous avons construit la structure de base de notre BlogList, nous devons la connecter à App.jsx afin qu'elle puisse être rendue sur l'écran/le navigateur. Pour ce faire, plongeons dans le fichier App.jsx et écrivons ce code :

PS C:\Users\vawkei\Documents\visual_testing> cd .\building-in-public-slack\
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Je n'ai pas abordé la mise en page, car elle n'est pas utile ici.

Ensuite, dans le main.jsx, nous y configurerons le routeur du navigateur comme ceci :

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack> cd .\minisearch\
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Donc, avec tout cela en place, tout ce qui se passe dans notre App.jsx serait désormais visible dans notre navigateur/écran.

Chapitre huit
Retour à BlogList.jsx :
Configuration du blog et des états de chargement dans BlogList.jsx

Ici, je vais créer des états avec lesquels travailler et je récupérerai également les données du blog de notre serveur local qui s'exécute sur localhost:8000.

Le premier état que je vais créer est destiné aux blogs. Il commencera comme un tableau vide lors du rendu de l'application et sera ensuite mis à jour lorsque nous recevrons les données de notre blog du serveur fictif.

Ensuite, le deuxième état que je créerai sera celui du chargement. Il permettra de savoir si les données sont toujours en cours de chargement. Il commence par false et peut être défini sur true lors de la récupération des données.

Soooooooooooooooo :

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch> cd .\frontend\
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Chapitre neuf
Affichage des données que nous avons récupérées :
Construire le Jsx :

Tout d'abord, je vais créer le composant jsx. Et pour cela, je vais écrire ceci ci-dessous dans la partie retour :

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm create vite@latest .
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Chapitre dix
Affichage des données que nous avons récupérées :
Voici useEffect :

Cela ne fait pas grand chose. Même si nous obtenons les données dans notre console, elles n'apparaissent pas à l'écran. Et pour que cela apparaisse à l'écran, nous aurons besoin de l'aide d'un des méchants de React, useEffect.

Qu'est-ce que useEffect ?
Selon NetNinja, "ce hook exécute une fonction à chaque rendu du composant. N'oubliez pas que le composant s'affiche initialement lors de son premier chargement, et cela se produit également lorsqu'un état change. Il restitue le DOM afin qu'il puisse se mettre à jour. cet état (l'état modifié) dans le navigateur".

Soooooooooooooooo
La fonction que nous avons écrite plus tôt pour fetchBlogs, nous la mettrons dans useEffect :

PS C:\Users\vawkei\Documents> cd .\visual_testing\
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Vous ressemblez au film Inception ? Calmez-vous, je vais vous expliquer sous peu. Pas le film Omen, mais Oh ! Hommes! c'est le Christopher Nolan de Mern {M.E.R.N} ici même.???

Puis dans le Jsx, on codera ça là :

PS C:\Users\vawkei\Documents\visual_testing> cd .\building-in-public-slack\
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Chapitre douze
À quoi tout cela ressemble avec MiniSearch :

Ok, nous pouvons maintenant afficher les blogs sur notre écran. Utilisons maintenant MiniSearch. L'ensemble du code ressemblera à ceci :

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack> cd .\minisearch\
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ce code crée une nouvelle instance de MiniSearch pour activer la recherche en texte intégral. Voici ce que ça fait :

champs : Spécifie quels champs (titre, auteur, texte) dans les données seront indexés pour la recherche.

storeFields : Définit quels champs seront inclus dans les résultats de recherche. Ces champs sont stockés à côté des données indexées pour une récupération facile.

Puis ceci :

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch> cd .\frontend\
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ce code nous donne le nombre total de documents qui ont été indexés par miniSearch après le rendu de la page.

Maintenant, allons plus loin. La page s'affiche, et lors du rendu, l'état du blog est initialement vide. Nous pouvons voir cela grâce à ceci dans notre code :

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm create vite@latest .
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion


 

Après quoi, nous récupérons nos données en utilisant la fonction fetchBlogs. Il y a des données là-bas pour de vrai, nous savons qu'il y a des données en recherchant ce code :

Done. Now run:

 npm install
 npm run dev
Copier après la connexion
Copier après la connexion

Maintenant ce code :

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm install minisearch react-router-dom
Copier après la connexion
Copier après la connexion

Ceci est utilisé pour supprimer tous les éléments précédemment indexés. Ceci est utile si vous devez réindexer de nouvelles données ou effacer l'index de recherche actuel. Nous voulons avoir une table rase, alors nous l'utilisons.

Puis ceci :

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm install sass
Copier après la connexion
Copier après la connexion

La méthode miniSearch.addAll(data) ajoute tous les éléments du tableau de données à l'index MiniSearch.

Ainsi, après avoir obtenu les données, nous mettons à jour les blogs, en exécutant ce code :

 VITE v5.4.11  ready in 332 ms

 ➜  Local:   http://localhost:5173/
 ➜  Network: use --host to expose
 ➜  press h + enter to show help
Copier après la connexion
Copier après la connexion

Une fois que nous avons mis à jour l'état des blogs, le tableau vide des blogs est rempli de nos données.

Dans le processus, nous nettoyons notre instance miniSearch pour laisser de la place à l'indexation de nouvelles données avec ce code :

http://localhost:5173/
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Et on y ajoute les données reçues en exécutant ce code :

http://localhost:5173/
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Avec tout cela qui a eu lieu, notre instance miniSearch devrait être chargée de données, oui. Si vous consultez cette ligne de code :

import { useState } from "react";
import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";
import "./App.css";

function App() {
  const [count, setCount] = useState(0);

  return (
    <>
           {" "}
      <div>
               {" "}
        <a href="https://vite.dev" target="_blank">
                    <img src={viteLogo} className="logo" alt="Vite logo" />     
           {" "}
        </a>
                <a href="https://react.dev" target="_blank">
                   {" "}
          <img src={reactLogo} className="logo react" alt="React logo" />     
           {" "}
        </a>     {" "}
      </div>
            <h1>Vite + React</h1>      <div className="card">
               {" "}
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}       {" "}
        </button>
                <p>
          Edit <code>src/App.jsx</code> and save to test HMR        {" "}
        </p>     {" "}
      </div>      <p className="read-the-docs">Click on the Vite and React logos to learn more       </p>
    </>
  );
}
export default App;
Copier après la connexion

Cela montre qu'il y a des données indexées là-bas. Cependant, lors du nouveau rendu de la page, nous perdons les données car miniSearch se réinitialise. Nous le savons grâce à ce code :

function App() {
  return <>     </>;
}

export default App;
Copier après la connexion

Et regardez ci-dessous, voici le contenu réel de notre console.log lors de l'exécution du code lors de son rendu.

{
 "blogs": [
 {
 "title": "Wolfenstein",
 "text": "Wolfenstein is a groundbreaking video game series that pioneered the first-person shooter genre. Debuting in 1981, it gained fame with Wolfenstein 3D (1992), placing players in World War II as an Allied spy battling Nazis. Known for its intense gameplay, alternate history, and stealth-action elements, the series continues to evolve with modern reboots and thrilling narratives.",
 "author": "voke",
 "id": "1"
 },
 {
 "title": "Bioshock",
 "text": "BioShock is a critically acclaimed video game series blending first-person shooting with deep storytelling. Set in dystopian worlds like the underwater city of Rapture and floating Columbia, it explores themes of power, morality, and free will. Known for its immersive environments, philosophical depth, and plasmid abilities, BioShock redefined narrative-driven gaming since its debut in 2007.",
 "author": "ese",
 "id": "2"
 },
 {
 "id": "3550",
 "author": "jite",
 "title": "Doom",
 "text": "Doom is a legendary first-person shooter series that revolutionized gaming with its 1993 debut. Players battle demons from Hell across Mars and Earth, armed with iconic weapons like the shotgun and BFG. Known for its fast-paced action, heavy metal soundtrack, and gory visuals, Doom remains a cornerstone of the FPS genre and a cultural phenomenon."
 }
 ]
}
Copier après la connexion

Chapitre quatorze
La solution : persister dans MiniSearch à l'aide de useRef :

Pour empêcher miniSearch de se réinitialiser à chaque rendu, nous le déplaçons vers un useRef afin que la même instance persiste dans tous les rendus. Voici comment :

PS C:\Users\vawkei\Documents> cd .\visual_testing\
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ce bloc de code garantit qu'une seule instance de MiniSearch persiste dans les rendus utilisant useRef. miniSearchRef crée et stocke l'instance MiniSearch.

Avec ce code useRef, nous devrions être à la maison et au sec.

Explication de la fonction handleSearch :

PS C:\Users\vawkei\Documents\visual_testing> cd .\building-in-public-slack\
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

La fonction handleSearch prend en compte tous les types d'utilisateur, elle met à jour la requête d'état avec la saisie de l'utilisateur. (événement.cible.valeur). Si l'entrée est vide, elle efface l'état des résultats et arrête la poursuite du traitement. Ensuite, il utilise miniSearch pour rechercher des données indexées avec une correspondance floue (permet de légères disparités). Ensuite, il met à jour l'état des résultats.

Chapitre quinze
Code final :
Notre code final dans BlogList ressemblerait donc à ceci :

importer { useEffect, useRef, useState } depuis "react" ;
importer des classes depuis "./BlogList.module.scss" ;
importer MiniSearch depuis "minisearch" ;

const BlogList = () => {
  //crée le blog et l'état isLoading.
  const [blogs, setBlogs] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  //crée la requête et l'état des résultats.
  const [requête, setQuery] = useState("");
  const [résultats, setResults] = useState([]);

  // vérifie si l'état du blog a été rempli
  console.log(blogs);

  const miniSearchRef = useRef(
    nouvelle MiniRecherche({
      champs : ["titre", "auteur", "texte"], // Champs sur lesquels effectuer la recherche
      storeFields : ["titre", "auteur", "texte"], // Champs à renvoyer
    })
  );
  const miniSearch = miniSearchRef.current;
  console.log("Blogs indexés après rendu :", miniSearch.documentCount);

  //récupération des blogs depuis notre base de données fictive :
  const fetchBlogs = async () => {
    setIsLoading(true);

    essayer {
      const réponse = wait fetch("http://localhost:8000/blogs");

      si (!response.ok) {
        lancer une nouvelle erreur ();
      }

      const data = attendre réponse.json();
      console.log(données);

      miniSearch.removeAll();

      miniSearch.addAll(données);
      console.log("Blogs indexés :", miniSearch.documentCount);

      setBlogs(données);
    } attraper (erreur) {
      message constant =
        erreur instance d'erreur ? error.message : "Quelque chose s'est mal passé";
      console.log(message);
    } enfin {
      setIsLoading(faux);
    }
  } ;

  // la fonctionnalité de recherche :
  const handleSearch = (événement) => {
    setQuery(event.target.value);

    if (event.target.value.trim() === "") {
      return setResults([]);
    }

    console.log(event.target.value);

    const searchResults = miniSearch.search(event.target.value, { fuzzy : 0,5 });
    console.log("searchResults:", searchResults);
    setResults(searchResults);
  } ;

  // Affichage conditionnel ou recherche de résultats ou de blogs
  const displayPosts = results.length > 0 ? résultats : blogs ;

  useEffect(() => {
    récupérerBlogs();
  }, []);

  retour (
    <div>
            <h2>BlogList</h2>
      {isLoading && <p>Loading...</p>}     {" "}
      <div className={classes.search}>
               {" "}
        <input placeholder="search" value={query} onChange={handleSearch} />     {" "}
      </div>
            <div className={classes.blogs}>
        {displayPosts.map((blog) => {
          // {blogs.map((blog) => {
          retour (
            <div
              clé={blog.id}
              className={classes.blog}
             >



<p><strong>Chapitre seize</strong><br>
<strong>Je le teste :</strong><br>
Maintenant, si je tape wolfenst, voici ce qui s'affiche :</p>

<p><img src="https://img.php.cn/upload/article/000/000/000/173282557470183.jpg" alt="Using MiniSearch in React: Advanced Search and Filtering Made Easy"></p>

<p>Vous pouvez voir qu'il n'a même pas attendu que je l'épele complètement avant de le filtrer.</p>

<p><em>Essayons de taper le mot critique :</em></p>

<p><img src="https://img.php.cn/upload/article/000/000/000/173282557528617.jpg" alt="Using MiniSearch in React: Advanced Search and Filtering Made Easy"><br>
Critical n'est pas un nom de titre, mais il recherche dans notre texte et fait ressortir chaque contenu contenant le mot critique. Et on peut dire sans se tromper que Bioshock est le seul contenu qui contient des éléments critiques.</p>

<p><strong>Pensées finales</strong><br>
Merci d'être resté à mes côtés tout au long de ce voyage MiniSearch ! J'apprécie vraiment votre temps et votre patience, et j'espère que ce guide vous a été utile pour naviguer et comprendre comment intégrer efficacement MiniSearch dans votre projet Reactjs.</p>

<p><strong>À propos de l'auteur</strong><br>
Voke Bernard est un développeur M.E.R.N passionné et motivé, spécialisé dans la création d'applications dynamiques React.js et Express.js. Il cherche toujours à collaborer sur de nouveaux projets. N'hésitez pas à nous contacter si vous souhaitez travailler avec lui.</p>


          

            
        
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal