Versi Rusia
Vuecket adalah kerangka kerja web yang mengintegrasikan VueJS di sisi klien dan Apache Wicket di sisi server. Ini mengambil yang terbaik dari keduanya dan membuat pengembangan aplikasi tumpukan penuh menjadi lebih cepat dan mudah. Tentu saja, ini semua adalah kata-kata besar, karena Vuecket saat ini (Agustus 2020) berusia kurang dari sebulan, dan belum lulus baptisan server produksi "api dan darah". Tapi itu sudah termasuk semua yang terbaik yang telah kami kembangkan selama pengembangan produk utama kami Sumber Terbuka Orienteer (platform untuk pengembangan cepat aplikasi bisnis). Dan justru karena usianya yang masih muda itulah Vuecket membutuhkan bantuan Anda: tolong bagikan apa yang Anda suka, apa yang tidak terlalu baik, di mana perbaikan diperlukan, dll.
Prinsip dasar yang memandu kami saat membangun Vuecket adalah:
- Menjadi deklaratif bukanlah keharusan. Vuecket tidak menentukan persyaratan kode khusus apa pun. Ini dapat diterapkan dengan cukup cepat dan mudah ke proyek Vue.JS atau Apache Wicket yang ada.
- Ikuti prinsip Pareto. Vuecket harus menyediakan 80% fungsionalitas yang Anda inginkan di luar kotak, tetapi harus ada titik ekstensi yang baik dan nyaman untuk 20% sisanya.
Sangat mudah untuk melihat bahwa prinsip-prinsip ini juga berlaku untuk Vue.JS dan Apache Wicket.
Jadi bagaimana tepatnya kita akan memulai dengan Vuecket? Saya sarankan membuat obrolan / papan tamu dengan dukungan penurunan harga. Saya tidak akan terlalu menyiksa: aplikasi yang sudah selesai ada di sini , dan kodenya ada di sini .
Kami membuat proyek
Mari buat proyek kita melalui `mvn archetype: generate`. Untuk melakukan ini, Anda dapat menggunakan, misalnya, perintah berikut:
mvn archetype:generate -DarchetypeGroupId=org.apache.wicket -DarchetypeArtifactId=wicket-archetype-quickstart -DarchetypeVersion=8.9.0 -DgroupId=com.mycompany -DartifactId=mychat -DarchetypeRepository=https://repository.apache.org/ -DinteractiveMode=false
Vuecket belum memiliki template proyek Maven sendiri. Mungkin kedepannya kami akan menambahkan ini juga. Sekarang mari hubungkan Vuecket itu sendiri. Tambahkan dependensi berikut ke proyek `pom.xml`:
<dependency>
<groupId>org.orienteer.vuecket</groupId>
<artifactId>vuecket</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
Mengeluarkan teks dalam penurunan harga
Proyek Wicket sudah berisi halaman selamat datang Wicket secara default. Mari tambahkan beberapa kode untuk memastikan Vuecket sudah berfungsi. Sebagai contoh, mari kita tampilkan Hello World, tetapi dalam penurunan harga, dan teks itu sendiri disetel di sisi server dalam komponen Apache Wicket. Kami akan menggunakan perpustakaan vue-markdown untuk membuat penurunan harga .
Di HomePage.html, sebagai ganti salam Gawang, tambahkan:
<div wicket:id="app">
<vue-markdown wicket:id="markdown">This will be replaced</vue-markdown>
</div>
Dan di HomePage.java kode berikut:
public HomePage(final PageParameters parameters) {
super(parameters);
add(new VueComponent<String>("app")
.add(new VueMarkdown("markdown", "# Hello World from Vuecket")));
}
Tapi di mana kelas VueMarkdown? Dan kami akan mendefinisikannya sebagai berikut:
@VueNpm(packageName = "vue-markdown", path = "dist/vue-markdown.js", enablement = "Vue.use(VueMarkdown)")
public class VueMarkdown extends Label {
public VueMarkdown(String id) {
super(id);
}
public VueMarkdown(String id, Serializable label) {
super(id, label);
}
}
Perhatikan anotasi @VueNpm. Diperlukan untuk mengaktifkan Vuecket pada komponen Wicket ini, yang akan memuat semua yang diperlukan dari NPM untuk membantu browser merender komponen Vue yang sudah ada untuk Penurunan harga dengan benar.
Jika Anda melakukan semuanya dengan benar, maka setelah memulai proyek melalui `mvn jetty: run` Anda akan melihat sesuatu seperti ini di http: // localhost: 8080
Jadi apa yang terjadi di sini dan mengapa berhasil?
- Kami menandai halaman dengan menambahkan 2 komponen Vue padanya: untuk aplikasi dan untuk output penurunan harga
- Kami telah menggabungkan komponen Vue dengan komponen Wicket di sisi server (di HomePage.java)
- Kami memberi tahu Vuecket library Vue.JS mana yang perlu dirender 'vue-markdown'
- Dan kemudian semuanya sederhana: Wicket, saat merender halaman ke browser, menggunakan baris "# Hello World from Vuecket", yang kami setel saat menambahkan komponen Wicket, dan Vuecket membantu browser memuat pustaka VueJS yang diperlukan, meluncurkan aplikasi VueJS dan memberikan salam yang sudah dirender Markdown
Github berkomitmen untuk membantu
Memasukkan pesan dan mempratinjaunya
Pada langkah ini, kami akan memperumit aplikasi kami: kami akan membuat input dan pratinjau pesan.
Mari tambahkan textarea ke HomePage.html untuk memasukkan pesan, serta ikat bidang ini dan vue-markdown ke variabel "teks" VueJS.
<div wicket:id="app">
<textarea v-model="text" style="width:100%" rows="5"></textarea>
<vue-markdown wicket:id="markdown" :source="text">Will be replaced</vue-markdown>
</div>
Kita sudah menggunakan variabel "text", tapi sekarang kita perlu menambahkannya ke komponen data Vue. Ada beberapa cara untuk melakukan ini di Vuecket, tetapi mari kita lakukan yang paling lama:
- Buat aplikasi VueComponent for Vue Anda sendiri
- Mari kita asosiasikan dengan file * .vue kita
- Mari tulis logikanya di file * .vue: untuk saat ini, hanya kolom "teks"
Berikut beberapa perubahan yang akan kami lakukan:
//HomePage.java:
public HomePage(final PageParameters parameters) {
super(parameters);
add(new ChatApp("app")
.add(new VueMarkdown("markdown")));
}
//ChatApp.java:
@VueFile("ChatApp.vue")
public class ChatApp extends VueComponent<Void> {
public ChatApp(String id) {
super(id);
}
}
Nah, ChatApp.vue sendiri:
<script>
module.exports = {
data: function() {
return {
text : ""
}
}
}
</script>
Akibatnya, saat Anda memulai `mvn jetty: run` dan memasukkan beberapa teks, Anda dapat melihat berikut ini
Di bab ini, kita telah mempelajari cara: membuat file * .vue yang familiar dan mengaitkannya dengan komponen Apache Wicket
GitHub komit untuk membantu
Tampilkan daftar pesan dan tambahkan yang baru
Tidak akan ada Vuecket atau Wicket yang spesifik di chapter ini: VueJS murni bersinar.
Jika kita menguraikan tugas, maka kita perlu melakukan hal berikut:
- Tambahkan kotak daftar ke aplikasi Vue kami untuk menyimpan pesan
- Tambahkan metode untuk menambahkan pesan baru ke daftar
- Tampilkan daftar pesan dan jangan lupa tentang penurunan harga
Pertama, mari kita ubah ChatApp.vue kita dan menambahkan logika yang diperlukan: field `messages` baru dengan daftar pesan dan metode Κ»addMessage` untuk menambahkan pesan baru. Dan jangan lupa bahwa saat menambahkan pesan ke daftar, sebaiknya kosongkan bidang masukan asli. Untuk pesan, kami tidak hanya akan menyimpan teks, tetapi juga tanggal penambahan / pengiriman. Di masa mendatang, dimungkinkan untuk memperluas dengan bidang tambahan, misalnya, siapa yang mengirim pesan ini, prioritas, penyorotan yang diperlukan, dll.
<script>
module.exports = {
data: function() {
return {
text : "",
messages: []
}
},
methods: {
addMessage : function() {
this.messages.push({
message: this.text,
date: new Date()
});
this.text = "";
}
}
}
</script>
Kami juga akan mengubah HomePage.html, menambahkan tampilan daftar pesan dan menambahkan panggilan ke metode addMessage kami saat menekan Ctrl-Enter.
<div wicket:id="app">
<div v-for="(m, index) in messages">
<h5>{{ index }}: {{ m.date }}</h5>
<vue-markdown :source="m.message"></vue-markdown>
</div>
<textarea v-model="text"
style="width:100%"
rows="5"
@keyup.ctrl.enter="addMessage"
placeholder="Enter message and Ctrl-Enter to add the message">
</textarea>
<vue-markdown wicket:id="markdown" :source="text">Will be replaced</vue-markdown>
</div>
Ketika Anda menjalankan `mvn jetty: run` dan memasukkan beberapa pesan, Anda akan melihat sesuatu seperti ini
Dalam bab ini, kami hanya mengajarkan aplikasi yang menggunakan VueJS untuk menambahkan pesan ke daftar dan menampilkan yang terakhir.
GitHub berkomitmen untuk membantu
Aktifkan kolaborasi
Jika sebelumnya konten buku tamu kami unik untuk setiap pengunjung halaman, maka dalam bab ini kami akan mengaktifkan komunikasi dengan server dan memungkinkan sinkronisasi dengan semua pengunjung. Untuk ini kita memerlukan Vuecket Data Fibers, solusi yang memungkinkan objek sisi browser disinkronkan dengan objek sisi server. Dan yang paling menarik adalah kami tidak perlu melakukan apa pun untuk ini di sisi klien! Terdengar keren? Ayo kode! Meskipun ... Hanya ada dua baris baru di komponen ChatApp.java kami:
private static final IModel<List<JsonNode>> MESSAGES = Model.ofList(new ArrayList<JsonNode>());
public ChatApp(String id) {
super(id);
addDataFiber("messages", MESSAGES, true, true, true);
}
Apa yang terjadi disini:
- Kami telah membuat model MESSAGES yang tersedia untuk semua orang, karena ini dibuat sebagai final statis.
- Menambahkan data-fiber, yang mengikat objek pesan di sisi klien dan objek di dalam model MESSAGES di sisi server.
- , data-fiber 3 : load, observe, refresh. Load β , Observe β , Refresh β .
-
GitHub commit
Pada bab sebelumnya, saya sedikit menipu dengan memberikan akses baca / tulis ke kumpulan pesan kepada semua pengunjung situs sekaligus. Sangat tidak disarankan untuk melakukan ini, karena kemudian, melalui serat data, pengirim mana pun dapat menimpa semua pesan di server dengan sesuatu miliknya atau bahkan menghapusnya. Serat data sebaiknya hanya digunakan untuk menautkan objek sisi browser khusus ke objek data sisi server milik pengguna yang sama. Ini berarti tidak ada model atau data statis!
Bagaimana kita bisa memperbaiki situasi? Untuk ini kita harus:
- Singkirkan serat data, yang berfungsi di seluruh papan, dan hanya menggunakannya untuk memuat daftar pesan pada awalnya.
- Gunakan metode sisi server untuk menambahkan pesan baru ke daftar.
Karenanya, setiap orang hanya dapat menambahkan pesan baru ke daftar umum, tetapi mereka tidak dapat menghapus atau mengubah yang sudah ada. Mari kita juga memperumit sisi server sedikit: kita tidak hanya akan menyimpan JSON yang diterima dari klien, tetapi kelas Pesan khusus dengan bidang yang diperlukan, metode, dll. untuk bekerja dengan data di sisi server.
Mari kita mulai dengan kelas Pesan untuk menyimpan pesan pengguna. Ngomong-ngomong, ini mungkin beberapa kelas JPA yang memungkinkan Anda menyimpan data ke database.
public class Message implements IClusterable {
@JsonProperty("message")
private String text;
private Date date;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
Perhatikan @JsonProperty. Jadi, kami telah mengalihkan bidang JSON "pesan" ke bidang "teks" Java kami.
Selanjutnya, mari kita ubah ChatApp.java untuk melakukan apa yang dijelaskan di atas: tambahkan metode vuecket untuk menyimpan pesan. Juga dalam kode, Anda dapat melihat pemotongan daftar pesan menjadi hanya 20 (pengguna Habr sangat rajin), tetapi ketika Anda menghapus pesan, itu masih disimpan selamanya di log server.
@VueFile("ChatApp.vue")
public class ChatApp extends VueComponent<Void> {
private static final Logger LOG = LoggerFactory.getLogger(ChatApp.class);
private static final int MAX_SIZE = 20;
private static final IModel<List<Message>> MESSAGES = Model.ofList(new ArrayList<Message>());
public ChatApp(String id) {
super(id);
addDataFiber("messages", MESSAGES, true, false, false);
}
@VueMethod
public synchronized void addMessage(Context ctx, Message message) {
List<Message> list = MESSAGES.getObject();
list.add(message);
trimToSize(list, MAX_SIZE);
IVuecketMethod.pushDataPatch(ctx, "messages", list);
}
private void trimToSize(List<Message> list, int size) {
//It's OK to delete one by one because in most of cases we will delete just one record
while(list.size()>size) LOG.info("Bay-bay message: {}", list.remove(0));
}
}
Lihat metode anotasi @VueMethod? Di dalamnya kami menerima pesan baru, menyimpannya dalam daftar, memotongnya dan mengirim daftar yang sudah diperbarui ke klien. Perhatikan juga bahwa serat data telah dikonfigurasi ulang untuk hanya meminta data saat aplikasi Vue melakukan boot.
Kita juga perlu mengubah logika di ChatApp.vue sehingga alih-alih bidang "pesan" lokal, kirim pesan baru ke server dalam mode asinkron (vcInvoke)
module.exports = {
data: function() {
return {
text : "",
messages: []
}
},
methods: {
addMessage : function() {
this.vcInvoke("addMessage", {
message: this.text,
date: new Date()
});
this.text = "";
}
}
}
Apa yang kami pelajari dari bab ini:
- Cara Membuat Metode Sisi Server untuk Vuecket
- Cara memanggil metode di server dari browser
- Bagaimana cara mengirim perubahan yang diperlukan ke klien
Untuk pengunjung yang taat hukum, tidak ada yang berubah, tetapi peretas tidak dapat lagi dengan mudah mengubah daftar umum pesan di server
GitHub berkomitmen untuk membantu
Kesimpulan
Pada hari ini, izinkan saya mengakhiri. Ada lebih banyak perbaikan yang dapat dilakukan pada kode kami, tetapi saya akan menyerahkannya kepada Anda, para pembaca yang budiman. Jika Anda butuh bantuan, tulis, kami akan membantu!
Apakah Anda menyukai kerangka kerjanya? Silakan bagikan pendapat Anda. Bagaimanapun, menurut Anda Open Source hidup dan berkembang.
Spoiler perbaikan Vuecket mendatang
- WebSocket' .
- , .
- data-fiber' .
- Vuecket/Wicket , VueJS , , Markdown