Cara mengatur carian UI responsif di Vue.js

Adakah anda berfikir untuk membina sesuatu yang hebat dengan salah satu kerangka kerja moden yang popular di luar sana sekarang, tetapi tidak tahu bagaimana untuk memulakannya?

Sekiranya ya, maka catatan ini akan membantu anda memulakan dan membina sesuatu yang hebat.

Apa yang akan kita bina?

Kami akan membina carian sisi pelanggan yang responsif terhadap 7 keajaiban dunia dengan ciri-ciri berikut:

  1. Carian & Penapis Teks berdasarkan Penilaian dan Suka.
  2. 2 item setiap baris untuk Tablet dan Desktop , 1 item setiap baris untuk Mudah Alih .
  3. Mengambil data secara tidak segerak dari API luaran di pihak pelanggan.
  4. Paparan responsif seperti gambar di bawah:

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

Kod Sumber : //github.com/honey93/VueSearchExample

Senibina Teknikal

Kami akan bekerjasama dengan teknologi berikut:

  1. Vue.js : Kerangka JavaScript Progresif
  2. BootstrapVue : Ini menyediakan salah satu implementasi komponen Bootstrap V4 dan sistem grid yang paling komprehensif yang tersedia untuk Vue.js 2.5+, lengkap dengan markup aksesibilitas WAI-ARIA yang luas dan automatik.
  3. Vue Cli 3 : Perkakas Piawai untuk Pembangunan Vue.js

Struktur Projek

Untuk memulakan projek Vue, kita perlu menyiapkan banyak perkara seperti Vue, Bootstrap, Vue Router, Vuex, dll.

Vue Cli memberi kami arahan untuk membuat projek dengan sebilangan besar konfigurasi yang diperlukan.

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

Untuk baki perkara seperti BootstrapVue, penilaian vue-star, dan lain-lain, kita boleh menggunakan perintah pemasangan npm.

Projek lalai yang dibuat menggunakan vuecli mempunyai struktur berikut:

/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. */ ......

Perkara-perkara di atas ada untuk menjelaskan seni bina projek kepada anda dan cara memulakannya.

Kita boleh memulakan dengan mengklon repositori dan menulis arahan berikut:

npm install npm run serve 

Beberapa komponen penting dijelaskan:

komponen / Header.vue

Header telah dibuat dalam bentuk komponen bebas tunggal sehingga dapat digunakan kembali di seluruh halaman, mengelakkan pertindihan kod.

/* 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; } 

komponen / Main.vue

Komponen ini terdiri dari keseluruhan logik pencarian / penapis dan paparan hasil yang diambil dari API.

Komponen ini menggunakan Header di atas dengan mengimportnya dalam skrip.

 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; } }

Saya harap anda mempunyai pemahaman yang lebih baik mengenai cara memulakan Vue dan mencipta sesuatu yang hebat.

Sekiranya anda menganggap ini berguna, tepuk tangan di bawah, berikan bintang ke repo projek dan kongsi juga dengan rakan anda.