Cum se configurează căutarea UI receptivă în Vue.js

Vă gândiți să construiți ceva minunat cu unul dintre cadrele moderne populare de acum, dar nu știți cum să începeți?

Dacă da, atunci această postare vă va ajuta să începeți și să creați ceva minunat.

Ce vom construi?

Vom construi o căutare receptivă a celor 7 minuni ale lumii cu următoarele caracteristici:

  1. Căutare text și filtre bazate pe evaluări și aprecieri.
  2. 2 articole pe rând pentru tabletă și desktop , 1 articol pe rând pentru mobil .
  3. Preluarea datelor asincron de la API-ul extern din partea clientului.
  4. Vizualizare receptivă așa cum se arată mai jos:

Demo live : //vue-responsive-search.herokuapp.com

Cod sursă : //github.com/honey93/VueSearchExample

Arhitectură tehnică

Vom lucra cu următoarele tehnologii:

  1. Vue.js : Cadrul JavaScript progresiv
  2. BootstrapVue : oferă una dintre cele mai cuprinzătoare implementări ale componentelor Bootstrap V4 și a sistemului de rețea disponibil pentru Vue.js 2.5+, completat cu un marcaj de accesibilitate WAI-ARIA extins și automatizat.
  3. Vue Cli 3 : Instrumente standard pentru dezvoltarea Vue.js

Structura proiectului

Pentru a începe cu proiectul nostru Vue, trebuie să configurăm multe lucruri precum Vue, Bootstrap, Vue Router, Vuex etc.

Vue Cli ne oferă comanda pentru a crea proiectul cu majoritatea configurațiilor necesare.

npm install -g @vue/cli vue create project-name

Pentru restul de lucruri, cum ar fi BootstrapVue, vue-star-rating, etc, putem folosi comanda npm install.

Proiectul implicit creat folosind vuecli are următoarea structură:

/Root Folder Public/ src/ assets/ /* Static assets like images goes here */ components/ /* Small part of a view */ views/ /* View represents a page composed of several components*/ App.vue /* The main view inside which the routing logic goes */ main.js /* App initialisation happens here */ router.js /* Router logic is defined here */ store.js /* Optional state management library Vuex */ package.json /* It consist of all the dependencies of the project. */ ......

Lucrurile de mai sus sunt acolo pentru a vă explica arhitectura proiectului și modul de inițializare a acestuia.

Putem începe prin clonarea depozitului și scrierea următoarelor comenzi:

npm install npm run serve 

Unele componente importante au explicat:

components / Header.vue

Antetul a fost creat sub forma unei singure componente independente, astfel încât să poată fi reutilizat pe pagini, evitând duplicarea codului.

/* Vue style of writing component: template, script and style*/  Responsive Search  export default { name: "Header" };   .header { display: flex; flex-flow: row wrap; justify-content: space-between; } 

components / Main.vue

Această componentă constă din întreaga logică de căutare / filtre și afișarea rezultatelor preluate din API.

Această componentă folosește antetul de mai sus, importându-l în script.

 Total Likes: {{likes.count}} Hits: {{likes.hit}}  Ratings: {{wonder.place}} {{wonder.likes}} 
{{wonder.place}}

{{wonder.description}}

/* Importing Header to use in this component */ import Header from "@/components/Header.vue"; /* Importing axios for async REST calls */ import axios from "axios"; export default { name: "Main", /* mounted gets called when the component gets mounted. AJAX calls are preferred in mounted lifecycle method */ mounted() { this.hover_flag = false; var inside = this; axios .get("//www.mocky.io/v2/5c7b98562f0000c013e59f07") .then(function(response) { //console.log(response); inside.wonders_data_actual = response.data.data; response.data.data.map(function(wonder) { inside.likes.count += wonder.likes; }); inside.wonders_data_actual = inside.wonders_data_actual.map(function( wonder ) { wonder.active_like = false; return wonder; }); inside.wonders_data = response.data.data; }) .catch(function(error) { // console.log(error); }); }, /* All the data variable declaration are done here: */ data() { return { hover_flag: false, wonders_data_actual: [], wonders_data: [], active_id: 0, options: [ { value: null, text: "Sort By" }, { value: "a", text: "Ratings" }, { value: "b", text: "Likes" } ], search: { filter: null, text: "" }, likes: { count: 0, hit: 0 } }; }, /* Methods are defined here */ methods: { show_hover(flag, active_id) { this.hover_flag = flag; this.active_id = active_id; }, sort() { //console.log(this.search.filter); this.search.filter == "b" ? this.wonders_data.sort(function(a, b) { return b.likes - a.likes; }) : this.wonders_data.sort(function(a, b) { return b.ratings - a.ratings; }); }, search_text() { //console.log(this.search.text); var inside = this; this.wonders_data = this.wonders_data_actual.filter(function(wonder) { if ( wonder.place .toLowerCase() .indexOf(inside.search.text.toLowerCase()) != "-1" ) { return wonder; } }); }, check_active(id) { var flag = false; this.wonders_data_actual.map(function(wonder) { if (wonder.id == id) { flag = wonder.active_like; } }); return flag; }, make_active(id) { this.likes.hit++; this.wonders_data_actual = this.wonders_data_actual.map(function(wonder) { if (wonder.id == id) { wonder.active_like = !wonder.active_like; wonder.active_like ? wonder.likes++ : wonder.likes--; } return wonder; }); var inside = this; inside.likes.count = 0; this.wonders_data_actual.map(function(wonder) { inside.likes.count += wonder.likes; }); } }, components: { Header } }; /* Styles are scoped to this component only.*/ /* Style for Desktop/Tablet */ .search-parent { display: flex; flex-flow: row wrap; justify-content: space-between; background-color: lightgray; } .card-inner { position: relative; overflow: hidden; box-shadow: 2px 2px 8px grey; } .card-img { width: 100%; } .card-bottom { position: absolute; bottom: 0; left: 0; height: 30px; width: 100%; background-color: white; opacity: 0.7; display: flex; justify-content: space-between; } .card-hover { position: absolute; right: 15px; left: 15px; top: 15px; bottom: 15px; background-color: white; opacity: 0.7; display: flex; flex-flow: column wrap; justify-content: center; align-items: center; } .absolute-star { position: absolute; top: 10px; right: 10px; } .card-hover p { font-size: 10px; text-align: center; } .bold { font-weight: 500; } .rating-div { width: 200px; } .search-bar { position: relative; } .search-bar input { padding-left: 30px; } .search-icon { position: absolute; top: 8px; left: 8px; } /* For Mobile Device, we will be going with column wrap approach */ @media screen and (max-width: 550px) { .search-parent { display: flex; flex-flow: column wrap; justify-content: center; align-items: center; background-color: lightgray; } .search-parent div { width: 100%; text-align: center; } }

Sper să înțelegeți mai bine cum să începeți cu Vue și să creați ceva minunat.

Dacă vi s-a părut util acest lucru, bateți mai jos, dați stele repo-ului proiectului și împărtășiți și prietenilor dvs.