Komponen Halaman Web SVG Untuk IoT Dan Pembuat (Bagian 1)
Diterbitkan: 2022-03-10Pasar IoT masih dalam tahap awal, tetapi mengumpulkan tenaga. Kami berada di puncak dalam sejarah IoT. Pasar meningkat empat kali lipat dalam kurun waktu lima tahun, 2015 hingga 2020. Untuk pengembang web, pertumbuhan IoT ini signifikan. Sudah ada permintaan besar untuk teknik web IoT.
Banyak perangkat akan tersebar secara geospasial, dan pemiliknya akan menginginkan kendali dan manajemen jarak jauh. Tumpukan web lengkap harus dibuat untuk membuat saluran untuk operasi jarak jauh. Selain itu, interaksi akan dilakukan dengan satu atau lebih perangkat IoT pada satu waktu. Interaksi harus dalam waktu nyata dari dunia fisik.
Diskusi ini menggali persyaratan antarmuka menggunakan Vue.js sebagai katalis dan mengilustrasikan satu metode komunikasi halaman web ke perangkat dari banyak substitusi.
Berikut adalah beberapa tujuan yang direncanakan untuk diskusi ini:
- Buat aplikasi web satu halaman SPWA yang menampung grup antarmuka manusia-mesin IoT (kami dapat menyebutnya "grup panel");
- Menampilkan daftar pengidentifikasi grup panel sebagai hasil dari kueri server;
- Menampilkan panel grup yang dipilih sebagai hasil kueri;
- Pastikan tampilan panel dimuat dengan lambat dan menjadi animasi dengan cepat;
- Pastikan panel disinkronkan dengan perangkat IoT.
IoT Dan Pertumbuhan Halaman Web yang Cepat
Penyajian grafik untuk visualisasi dan remote control perangkat keras bersama dengan sinkronisasi halaman web dengan proses fisik real-time berada dalam ranah pemecahan masalah halaman web yang melekat pada masa depan IoT ini.
Banyak dari kita mulai mencari teknik presentasi IoT, tetapi ada beberapa standar web bersama dengan beberapa teknik presentasi yang dapat kita mulai gunakan sekarang. Saat kita mengeksplorasi standar dan teknik ini bersama-sama, kita dapat bergabung dengan gelombang IoT ini.
Dasbor dan visualisasi data sangat dibutuhkan. Selain itu, permintaan untuk melampaui halaman web yang menyediakan formulir atau daftar tampilan atau konten tekstual tinggi. Dasbor untuk IoT harus piktografik, animasi. Animasi harus disinkronkan dengan proses fisik waktu nyata untuk memberikan pandangan yang benar tentang status mesin kepada pengguna. Status alat berat, seperti nyala api yang menyala atau tidak, mengalahkan status aplikasi dan memberikan informasi penting kepada operator, bahkan mungkin informasi keselamatan.
Dasbor membutuhkan lebih dari sekadar visualisasi data. Kita harus ingat bahwa bagian dari IoT adalah perangkat yang tidak hanya memiliki sensor tetapi juga antarmuka kontrol. Dalam implementasi perangkat keras, MCU diperluas dengan sakelar, sakelar ambang batas, pengaturan parameter, dan banyak lagi. Namun, halaman web dapat menggantikan komponen kontrol perangkat keras tersebut .
Tidak ada yang baru. Antarmuka komputer untuk perangkat keras telah ada sejak lama, tetapi pertumbuhan pesat penggunaan halaman web untuk antarmuka ini adalah bagian dari pengalaman kami saat ini. WebRTC dan Speech API berada di jalur pengembangan yang dimulai pada tahun 2012. WebSockets telah berkembang dalam kerangka waktu yang sama.
IoT sudah ada di pikiran kita sejak lama. IoT telah menjadi bagian dari dialog manusia sejak tahun 1832. Namun, IoT dan nirkabel seperti yang kita ketahui sekarang telah dibayangkan oleh Tesla sekitar tahun 1926. Forbes 2018 State of Iot memberi tahu kita fokus pasar saat ini untuk IoT. Yang menarik bagi pengembang web, artikel tersebut menyebutkan dasbor:
“Pengadopsi atau pendukung awal IoT memprioritaskan dasbor, pelaporan, kasus penggunaan IoT yang menyediakan aliran data yang tidak terpisahkan dengan analitik, visualisasi lanjutan, dan penambangan data.”
Pasar IoT sangat besar. Artikel Ukuran Pasar ini memberikan prediksi jumlah perangkat yang akan muncul: 2018: 23,14 miliar 2025: 75,44 miliar. Dan, ia mencoba untuk memasukkan angka keuangan di dalamnya: 2014: \$2,99 triliun 2020: $8,90 triliun. Permintaan akan keterampilan IoT akan menjadi yang paling cepat berkembang: IoT dalam Permintaan.
Saat kami mengembangkan antarmuka yang jelas untuk mengontrol dan memantau perangkat, kami menghadapi masalah baru untuk mengembangkan antarmuka kami. Semua miliaran perangkat akan dimiliki oleh banyak orang (atau organisasi). Juga, setiap orang dapat memiliki sejumlah perangkat. Mungkin bahkan beberapa perangkat akan dibagikan.
Antarmuka modern yang telah dibuat untuk kontrol mesin sering kali memiliki tata letak yang terdefinisi dengan baik khusus untuk mesin tertentu atau pemasangan beberapa mesin. Misalnya, di rumah pintar, sistem kelas atas akan memiliki LCD dengan panel untuk perangkat yang ditempatkan dengan hati-hati. Namun, seiring kami berkembang dengan IoT versi web, akan ada sejumlah panel untuk aliran perangkat yang dinamis dan bahkan seluler.
Pengelolaan panel untuk perangkat menjadi serupa dengan pengelolaan koneksi sosial di situs web sosial.
“Antarmuka pengguna kami harus dinamis dalam mengelola panel real-time yang sangat beranimasi yang harus ditampilkan pada satu waktu untuk setiap pengguna tertentu.”
Dasbor adalah aplikasi web satu halaman SPWA. Dan, kita bisa membayangkan database panel. Jadi, jika satu pengguna akan mengakses sejumlah panel dan konfigurasi untuk perangkatnya yang tersebar di planet ini, SPWA perlu mengakses komponen panel sesuai permintaan. Panel dan beberapa JavaScript pendukungnya harus dimuat dengan malas.
“Antarmuka kami harus bekerja dengan kerangka kerja halaman web yang memungkinkan penggabungan pengikatan komponen asinkron tanpa menginisialisasi ulang kerangka kerja mereka.”
Mari gunakan Vue.js, WebSockets, MQTT, dan SVG untuk melangkah ke pasar IoT.
Bacaan yang disarankan : Membangun Infografis Interaktif Dengan Vue.js
Arsitektur Tingkat Tinggi Untuk Aplikasi Web IoT
Saat mendesain antarmuka untuk halaman web IoT, seseorang selalu memiliki banyak opsi. Salah satu opsi mungkin untuk mendedikasikan satu halaman ke satu perangkat tunggal. Halaman bahkan mungkin dirender di sisi server. Server akan memiliki tugas untuk menanyakan perangkat untuk mendapatkan nilai sensornya dan kemudian menempatkan nilai tersebut ke tempat yang sesuai dalam string HTML.
Banyak dari kita yang akrab dengan alat yang memungkinkan templat HTML ditulis dengan penanda khusus yang menunjukkan di mana harus meletakkan nilai variabel. Melihat {{temperature}}
dalam template seperti itu memberi tahu kita dan mesin tampilan untuk mengambil suhu yang ditanyakan dari perangkat dan mengganti simbol {{temperature}}
dengannya. Jadi, setelah menunggu server menanyakan perangkat, perangkat merespons, merender halaman, dan mengirimkan halaman, pengguna akhirnya dapat melihat suhu yang dilaporkan oleh perangkat.
Untuk halaman ini per arsitektur perangkat, pengguna mungkin ingin mengirim perintah ke perangkat. Tidak masalah, dia bisa mengisi formulir HTML dan mengirimkannya. Server bahkan mungkin memiliki rute hanya untuk perangkat, atau mungkin sedikit lebih cerdik, rute untuk jenis perangkat dan ID perangkat. Server kemudian akan menerjemahkan data formulir menjadi pesan untuk dikirim ke perangkat, menulisnya ke beberapa penangan perangkat dan menunggu pengakuan. Kemudian, server akhirnya dapat menanggapi permintaan posting dan memberi tahu pengguna bahwa semuanya baik-baik saja dengan perangkat.
Banyak CMS bekerja dengan cara ini untuk memperbarui entri blog dan sejenisnya. Sepertinya tidak ada yang aneh tentang itu. Tampaknya HTML melalui HTTP selalu memiliki desain untuk mendapatkan halaman yang telah dirender dan untuk mengirim data formulir untuk ditangani oleh server web. Terlebih lagi, ada ribuan CMS yang bisa dipilih. Jadi, untuk meningkatkan sistem IoT kami, tampaknya masuk akal untuk menelusuri ribuan CMS itu untuk melihat mana yang tepat untuk pekerjaan itu. Atau, kami mungkin menerapkan satu filter pada CMS untuk memulai.
Kita harus mempertimbangkan sifat real-time dari apa yang kita hadapi. Jadi, meskipun HTML dalam bentuk aslinya cukup baik untuk banyak tugas perusahaan, HTML memerlukan sedikit bantuan untuk menjadi mekanisme pengiriman untuk manajemen IoT. Jadi, kami membutuhkan CMS atau server web khusus yang membantu HTML melakukan pekerjaan IoT ini. Kami juga dapat memikirkan server karena kami menganggap CMS menyediakan fungsionalitas server. Kita hanya perlu mengingat bahwa server harus menyediakan animasi yang digerakkan oleh peristiwa, sehingga halaman tidak dapat 100% dicetak statis.
Berikut adalah beberapa parameter yang mungkin memandu pilihan untuk halaman web kami yang terhubung dengan perangkat, hal-hal yang harus dilakukan:
- Menerima data sensor dan pesan status perangkat lainnya secara asinkron ;
- Render data sensor untuk halaman di klien (hampir secara wajar ke 1);
- Publikasikan perintah ke perangkat atau grup perangkat tertentu secara asinkron ;
- Opsional mengirim perintah melalui server atau melewatinya.
- Menjaga hubungan kepemilikan antara perangkat dan pengguna dengan aman;
- Kelola operasi perangkat penting dengan tidak mengganggu atau mengesampingkan.
Daftar itu muncul di benak ketika memikirkan hanya satu halaman yang bertindak sebagai antarmuka ke perangkat yang dipilih . Kami ingin dapat berkomunikasi dengan perangkat secara bebas dalam hal perintah dan data.
Untuk halaman, kita hanya perlu memintanya sekali ke server web. Kami berharap bahwa server web (atau aplikasi terkait) akan menyediakan jalur komunikasi yang aman. Dan, jalur tidak harus melalui server, atau mungkin harus menghindari server sama sekali karena server mungkin memiliki tugas prioritas yang lebih tinggi selain mengurus komunikasi satu halaman untuk data yang berasal dari sensor.
Faktanya, kita dapat membayangkan data yang masuk dari sensor sekali dalam satu detik, dan kita tidak akan mengharapkan server web itu sendiri untuk menyediakan detik yang konstan demi pembaruan kedua untuk ribuan aliran sensor individual dikalikan dengan ribuan pemirsa. Tentu saja, server web dapat dipartisi atau diatur dalam kerangka kerja penyeimbangan beban, tetapi ada layanan lain yang disesuaikan untuk pengiriman sensor dan menyusun perintah ke perangkat keras.
Server web perlu mengirimkan beberapa paket sehingga halaman dapat membuat saluran komunikasi yang aman dengan perangkat. Kita harus berhati-hati dalam mengirim pesan di saluran yang tidak menyediakan manajemen jenis pesan yang masuk. Harus ada pengetahuan tentang apakah perangkat berada dalam mode yang dapat diinterupsi atau mungkin ada permintaan untuk tindakan pengguna jika perangkat berada di luar kendali. Jadi, server web dapat membantu klien untuk mendapatkan sumber daya yang sesuai yang dapat mengetahui lebih banyak tentang perangkat. Pesan dapat dilakukan dengan sesuatu seperti server MQTT. Dan, mungkin ada beberapa layanan untuk menyiapkan server MQTT yang dapat dimulai saat pengguna memperoleh akses ke panelnya melalui server web.
Karena dunia fisik dengan persyaratan waktu nyata dan karena pertimbangan keamanan tambahan, diagram kami menjadi sedikit berbeda dari aslinya.
Kita tidak bisa berhenti di sini. Menyiapkan satu halaman per perangkat, meskipun responsif dan menangani komunikasi dengan baik, bukanlah yang kami minta. Kita harus berasumsi bahwa pengguna akan masuk ke akunnya dan mengakses dasbornya. Dari sana, dia akan meminta beberapa daftar proyek konten (kemungkinan besar proyek yang sedang dia kerjakan). Setiap item dalam daftar akan merujuk ke sejumlah sumber daya. Ketika dia memilih item dengan mengklik atau mengetuk, dia akan mendapatkan akses ke kumpulan panel, yang masing-masing akan memiliki beberapa informasi tentang sumber daya atau perangkat IoT tertentu.
Sejumlah panel yang dikirimkan sebagai respons terhadap kueri yang dihasilkan sebagai akibat dari tindakan antarmuka pengguna mungkin berupa panel yang berinteraksi dengan perangkat langsung. Jadi, segera setelah panel muncul, diharapkan untuk menunjukkan aktivitas waktu nyata dan dapat mengirim perintah ke perangkat.
Bagaimana panel terlihat pada halaman adalah keputusan desain. Mereka mungkin jendela mengambang, atau mereka mungkin kotak di latar belakang yang dapat digulir. Bagaimanapun tampilannya, panel akan menunjukkan waktu, suhu, tekanan, kecepatan angin, atau apapun yang bisa Anda bayangkan. Kami berharap panel dianimasikan dengan memperhatikan berbagai skala grafis. Suhu dapat disajikan sebagai termometer, kecepatan sebagai pengukur kecepatan setengah lingkaran, suara sebagai bentuk gelombang streaming, dan sebagainya.
Server web memiliki tugas mengirimkan panel yang tepat kepada pengguna yang tepat yang diberikan pertanyaan ke database panel dan mengingat bahwa perangkat harus tersedia secara fisik. Terlebih lagi, mengingat akan ada banyak jenis perangkat yang berbeda, panel untuk setiap perangkat kemungkinan akan berbeda. Jadi, server web harus dapat memberikan informasi piktografik yang diperlukan untuk merender panel. Namun, halaman HTML untuk dasbor tidak harus dimuat dengan semua panel yang memungkinkan. Tidak ada gambaran berapa banyak yang akan ada.
Berikut adalah beberapa parameter yang mungkin memandu pilihan untuk halaman dasbor kami, hal-hal yang harus dilakukan:
- Menyajikan cara memilih grup panel perangkat terkait;
- Memanfaatkan mekanisme komunikasi perangkat simultan untuk sejumlah perangkat;
- Aktifkan panel perangkat saat pengguna memintanya;
- Menggabungkan grafik yang dimuat dengan malas untuk desain panel yang unik;
- Manfaatkan token dan parameter keamanan sehubungan dengan setiap panel;
- Pertahankan sinkronisitas dengan semua perangkat di bawah inspeksi pengguna.
Kita dapat mulai melihat bagaimana permainan berubah, tetapi dalam dunia desain dasbor, permainan telah berubah sedikit di sana-sini selama beberapa waktu. Kami hanya perlu mempersempit diri ke beberapa alat pengembangan halaman terkini dan berguna untuk membuat diri kami bangkit dan maju.
Mari kita mulai dengan bagaimana kita bisa merender panel. Ini sudah tampak seperti pekerjaan besar. Kami membayangkan berbagai jenis panel. Tapi, jika Anda pernah menggunakan musik DAW, Anda akan melihat bagaimana mereka menggunakan grafik untuk membuat panel terlihat seperti perangkat analog yang digunakan oleh band dari dulu. Semua panel di DAW digambar oleh plugin yang beroperasi pada suara. Faktanya, banyak dari plugin DAW tersebut mungkin menggunakan SVG untuk merender antarmuka mereka. Jadi, kami membatasi diri untuk menangani antarmuka SVG, yang pada gilirannya dapat berupa grafik apa pun yang dapat kami bayangkan.
Memilih SVG Untuk Panel
Tentu saja, saya suka DAW dan akan menggunakannya sebagai contoh, tetapi SVG adalah standar halaman web. SVG adalah standar W3C. Ini untuk membawa gambar garis ke halaman web. SVG dulunya adalah warga kelas dua di halaman web, diharuskan untuk tinggal di iFrames. Tapi, sejak HTML5, ia telah menjadi warga negara kelas satu. Mungkin, ketika SVG2 keluar, itu akan dapat menggunakan elemen formulir. Untuk saat ini, elemen formulir adalah Objek Asing di SVG. Namun, hal itu tidak menghentikan kami untuk menjadikan SVG sebagai substrat untuk panel.
SVG dapat digambar, disimpan untuk ditampilkan, dan dapat dimuat dengan malas. Faktanya, saat kita menjelajahi sistem komponen, kita akan melihat bahwa SVG dapat digunakan untuk template komponen. Dalam diskusi ini, kita akan menggunakan Vue.js untuk membuat komponen untuk panel.
Menggambar SVG tidaklah sulit, karena ada banyak program menggambar garis yang mudah didapatkan. Jika Anda menghabiskan uang, Anda bisa mendapatkan Adobe Illustrator, yang mengekspor SVG. Inkscape telah menjadi goto untuk pembuatan SVG selama beberapa waktu. Ini adalah open source dan bekerja dengan baik di Linux, tetapi juga dapat dijalankan di Mac dan Windows. Kemudian, ada beberapa program pengeditan SVG halaman web yang bersifat open source, dan beberapa versi SaaS juga.
Saya telah mencari-cari editor SVG berbasis web open-source. Setelah melihat-lihat, saya menemukan SVG-Edit. Anda dapat memasukkannya ke dalam halaman web Anda sendiri, mungkin jika Anda membuat blog berbasis SVG atau semacamnya.
Saat Anda menyimpan pekerjaan Anda ke file, SVG-Edit mengunduhnya di browser Anda, dan Anda dapat mengambil file dari direktori unduhan Anda.
Gambar yang saya gambar menunjukkan gerbang AND yang mengendalikan integrator. Bukan itu yang biasanya diharapkan untuk dilihat di panel MCU. Panel mungkin memiliki tombol untuk memberi makan salah satu input gerbang AND, mungkin. Kemudian mungkin ada tampilan dari ADC yang membaca output dari integrator. Mungkin itu akan menjadi grafik garis pada sumbu waktu. Sebagian besar panel akan memiliki grafik yang memungkinkan pengguna untuk berhubungan dengan apa yang terjadi di dalam MCU. Dan, jika sirkuit kita akan hidup di mana saja, itu akan berada di dalam MCU.
Bagaimanapun, diagram elektronik kita dapat digunakan untuk membahas animasi. Apa yang ingin kita lakukan adalah melihat SVG dan melihat di mana kita bisa mendapatkan beberapa tag DOM yang ingin kita ubah dalam beberapa cara. Kami kemudian dapat menganimasikan SVG dengan menggunakan sedikit vanilla JavaScript dan timer. Mari kita buat gerbang AND berkedip dalam warna yang berbeda.
SVG yang kita cari ada di kotak kode berikut. Itu tidak terlihat sangat ramah untuk programmer, meskipun pengguna akan sangat senang. Namun demikian, masih ada beberapa petunjuk untuk menemukan elemen DOM mana yang ingin kita operasikan. Pertama, sebagian besar alat menggambar SVG memiliki cara untuk mendapatkan properti objek, khususnya atribut id
. SVG-Edit juga punya caranya. Di editor, pilih gerbang AND dan amati toolbar. Anda akan melihat bidang untuk id
dan class
CSS juga.
Jika Anda tidak dapat mengakses alat pengeditan karena alasan tertentu, Anda dapat membuka SVG di browser dan memeriksa DOM. Bagaimanapun, kami telah menemukan bahwa gerbang kami memiliki id
= “svg_1”.
<svg width="640" height="480" xmlns="https://www.w3.org/2000/svg" xmlns:svg="https://www.w3.org/2000/svg"> <g class="layer"> <title>Layer 1</title> <path d="m80.59881,87.020171l14.714795,0m-14.714793,-11.938687l14.714797,0.000004m-0.033867,-6.543869l0,24.758504c42.377882,2.221929 43.364812,-27.139117 0,-24.758504zm47.366321,12.333056l-15.303943,0m-48.188699,-6.489897l1.454753,0l0,1.454751l-1.454753,0l0,-1.454751zm-0.068425,11.869359l1.454753,0l0,1.454753l-1.454753,0l0,-1.454753zm63.545246,-6.089294l1.454751,0l0,1.454751l-1.454751,0l0,-1.454751z" fill="#FF0000" stroke="#000000"/> <path d="m48.58886,119.662231l18.234678,0l2.523043,-7.173309l4.128604,13.808613l4.587337,-13.987948l4.013933,13.808613l4.35797,-13.629278l4.35797,13.718944l2.408353,-6.72497l18.349357,0m-64.482612,-0.623112l1.515724,0l0,1.515728l-1.515724,0l0,-1.515728zm64.484275,-0.103111l1.515721,0l0,1.515728l-1.515721,0l0,-1.515728z" fill="#FF0000" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" transform="rotate(90.3367 80.0675 119.304)"/> <polygon cx="108.5" cy="79.5" edge="0" fill="#ffffff" orient="x" shape="regularPoly" sides="3" strokeWidth="null" strokecolor="#000000"/> <polygon cx="215.5" cy="192.5" edge="0" fill="#ffffff" orient="x" shape="regularPoly" sides="3" strokeWidth="null" strokecolor="none"/> <polygon cx="165.5" cy="164.5" edge="0" fill="#ffffff" orient="x" shape="regularPoly" sides="3" strokeWidth="null" strokecolor="none"/> <polygon cx="161.5" cy="138.5" edge="0" fill="#ffffff" orient="x" shape="regularPoly" sides="3" strokeWidth="null" strokecolor="none"/> <polygon cx="160.5" cy="161.5" edge="0" fill="#ffffff" orient="x" shape="regularPoly" sides="3" strokeWidth="null" strokecolor="none"/> <g> <path d="m225.016923,53.008793l0,3.419331m-4.558966,-1.709666l9.11791,0m10.303228,4.235512l-25.770656,0m-34.429182,0l24.544724,0m0.220544,-4.058194l1.543807,0l0,8.164451l-1.543807,0l0,-8.164451zm7.939567,-4.473673l1.543805,0l0,16.999955l-1.543805,0l0,-16.999955zm-34.176663,8.126854l1.474036,0l0,0.747515l-1.474036,0l0,-0.747515zm61.677552,0.018809l1.474038,0l0,0.747515l-1.474038,0l0,-0.747515z" fill="#FF0000" sides="3" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-width="null"/> <polygon cx="171.5" cy="159.5" edge="43.256342" fill="#ffffff" orient="x" points="223.47406005859375,91.5 186.01296997070312,113.128173828125 186.01296997070312,69.871826171875 223.47406005859375,91.5 " shape="regularPoly" sides="3" stroke="#000000" stroke-width="null" strokeWidth="null" strokecolor="#000000"/> <line fill="none" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-width="null" x1="171" x2="186" y1="103.5" y2="103.5"/> <path d="m130.801817,80.659041l15.333707,0l2.12165,-4.564833l3.47178,8.787299l3.857534,-8.901421l3.375353,8.787299l3.664657,-8.673176l3.664657,8.730237l2.025206,-4.279526l15.430142,0m-54.224016,-0.396526l1.274586,0l0,0.964554l-1.274586,0l0,-0.964554zm54.225414,-0.065616l1.274584,0l0,0.964554l-1.274584,0l0,-0.964554z" fill="none" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-width="null"/> <line fill="none" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-width="null" x1="171.5" x2="171.5" y1="103.75" y2="135.388167"/> <line fill="none" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-width="null" x1="177.75" x2="177.75" y1="58.75" y2="80.255951"/> <line fill="none" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-width="null" x1="223.75" x2="266.854524" y1="91.75" y2="91.75"/> <line fill="none" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-width="null" x1="241.75" x2="241.75" y1="59.75" y2="91.754167"/> <line fill="none" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-width="null" x1="168.25" x2="180.75" y1="135.75" y2="135.75"/> <line fill="none" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-width="null" x1="169.75" x2="179.25" y1="138.5" y2="138.5"/> <line fill="none" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" x1="171" x2="179.75" y1="141.25" y2="141.25"/> </g> </g> </svg>
Yang kita butuhkan sekarang adalah sedikit JavaScript. Kami perhatikan terlebih dahulu bahwa atribut elemen "isi" ada. Kemudian hanya ada program sederhana sebagai berikut:
<html> <head> </head> <body> <!-- ALL THE SVG FROM ABOVE GOES HERE --> </body> <html> </svg> <script> // Set up a timer interval flash the color. var gateElement = document.getElementById("svg_1"); if ( gateElement ) { setInterval( () => { var fillC = gateElement.getAttribute("fill"); gateElement.setAttribute("fill", (fillC == "#00FF00") ? "#FF0000" : "#00FF00" ); }, 2000 ) } </script>
Perhatikan bahwa yang kita miliki adalah halaman HTML minimal. Anda dapat memotong dan menempelkan kode ke editor favorit Anda. Dan, jangan lupa untuk memotong dan menempelkan SVG untuk menggantikan komentar. Versi Chrome saya mengharuskan halaman menjadi HTML untuk memiliki bagian JavaScript. Jadi, itulah salah satu browser yang masih memperlakukan SVG sebagai sesuatu yang terpisah. Tapi, ini masih jauh dari hari-hari <iframe>
.
Jika Anda memotong dan menempel dengan benar, Anda dapat membuka halaman dan melihat gerbang AND berubah dari merah menjadi hijau berulang-ulang.
Bacaan yang disarankan : Dekomposisi Lingkaran SVG Ke Jalur
Membangun Panel Dari Komponen VUE
Kami sudah dalam perjalanan untuk membuat satu panel menjadi hidup, tetapi jika kami ingin mengelola banyak koleksi panel dengan cara yang masuk akal, pekerjaan kami akan cocok untuk kami. Itu terutama akan terjadi jika kita hanya membangun contoh pertama kita.
Sementara contoh pertama menunjukkan kepada kita bagaimana kita dapat mengubah tampilan objek secara asinkron, itu tidak menunjukkan kepada kita cara mengikat tampilan ke status objek data apa pun, apalagi objek yang mengelola mesin. Kita tentu dapat memahami bagaimana demonstrasi setInterval
dapat digantikan oleh penangan fetch
, tetapi kita bahkan mungkin tidak mendapatkan status mesin dari server web yang menyajikan halaman yang berisi SVG. Juga, ketika kami mendapatkan data, program kami sekarang diminta untuk mengetahui tentang struktur DOM dari halaman yang diberikan.
Untungnya, kerangka kerja seperti Vue telah menjadi populer, dan mereka dapat menghemat banyak pekerjaan.
Sangat mudah untuk mengetahui tentang Vue. Dokumentasi Vue sangat mudah diakses. Jadi, jika diskusi ini melompat terlalu jauh, maka Anda dapat meluangkan waktu untuk mempelajari Vue di situs webnya sendiri. Tapi, ada diskusi yang sangat bagus di dalam halaman Smashing. Krutie Patel menulis artikel yang menakjubkan tentang membuat infografis. Souvik Sarkar memberi tahu kami cara membuat dasbor cuaca dengan Vue.
Seleksi Grup Panel Terkait
Untuk langkah pertama, kita harus membahas pencarian grup panel. Salah satu alasan untuk melakukan ini pertama adalah bahwa itu berada pada tingkat kerangka kerja interaksi manusia kita.
Pengguna mencari sesuatu yang dia minati. Mungkin dia tertarik dengan semua perangkat di lokasi di satu kota. Mungkin dia memiliki banyak batch produk cair dan dia ingin mempersempit ke satu jenis produk dengan setiap batch diatur oleh kumpulan kecil perangkat IoT. Jadi, pengguna akan mencari terlebih dahulu untuk mendapatkan daftar kecil.
Berikut adalah prosesnya:
- Cari grup panel berdasarkan fitur/parameter.
- Lihat daftar ikon yang mewakili grup.
- Pilih ikon (klik/ketuk).
- Mulai gunakan panel yang diidentifikasi dengan ikon saat muncul.
Alasan lain mengapa ini adalah langkah pertama yang baik adalah karena kita dapat menggunakan Vue dalam bentuknya yang paling sederhana. Tidak perlu membangun alat. Kami hanya akan menyertakan vue.js
dengan tag skrip dalam HTML. Bahkan, kita bahkan tidak perlu mengunduhnya. Ada situs tempat salinan kerja vue.js
disajikan.
Yang kita butuhkan hanyalah tag berikut:
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
Saya menyalin tag skrip langsung dari dokumentasi Vue tentang instalasi.
Sekarang, kita membutuhkan halaman web yang dapat memuat ikon dan membuatnya menjadi sesuatu yang dapat diklik. Vue membuatnya sangat mudah. Sebenarnya, saya baru saja menulis aplikasi kecil untuk mengelola daftar Twitter menggunakan Vue. Itu hanya mengelola bidang teks. Karena ini sedikit lebih sederhana daripada SPWA yang menggunakan ikon, kita dapat melihatnya dan kemudian mengubahnya menjadi kerangka kerja aplikasi satu halaman yang kita inginkan.
Berikut adalah bagian dari tampilan halaman:
Ini terlihat seperti halaman yang cukup sederhana. Setiap entri numerik luar adalah slot waktu dengan satu atau dua tweet di dalamnya. Tweet kedua adalah opsional. Jika Anda mengedit tweet, mekanisme Vue memperbarui objek JavaScript. Halaman ini menyerahkannya kepada pengguna untuk mengklik tombol "perbarui entri" untuk memberi tahu server bahwa ada sesuatu yang berubah, melalui fungsi pengendali tombolnya.
Agar pengendali tombol dapat menyampaikan data ke server, ia harus mengubah objek data Vue menjadi string JSON. Sekarang, Anda mungkin bertanya-tanya betapa sulitnya menerjemahkan objek Vue ke JSON nantinya. Ternyata menjadi satu baris kode. Anda dapat menemukan baris dalam kode sumber berikut, tetapi jika Anda ingin menemukannya lebih cepat, baris ini disorot di paragraf setelah kode sumber.
Halamannya terlihat sederhana. Penampilan bisa menipu. Tentu saja, halamannya terlihat sederhana, tetapi apakah kodenya sederhana? Ya, memang begitu! Menggunakan Vue, halaman mengelola konten bidang hampir secara ajaib. Berikut kodenya:
<!DOCTYPE html> <html lang="en" prefix="og: https://ogp.me/ns#"> <!-- define microdata scope and type --> <head itemscope itemtype="https://schema.org/Article"> <title>Tweet Keeper</title> <style> body { margin: 2em; } .entryart { border: solid 1px navy; width: 80%; padding: 2px; padding-left: 6px; margin-bottom: 3px; background-color: #EEF4EE; } </style> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> </head> <body onload="GetTweets()"> <!-- some old fashioned handling --> <!-- The Vue app starts here. This is the HTML part of the Vue object --> <div> <!-- Recognize the name from the Vue doc --> <div itemscope itemtype="https://schema.org/Article"> <h1 itemprop="name">mangage tweets</h1> <p itemprop="description">My personal Tweet engine. This page accesses a personal tweet page that belongs to {{tweetOwner}}.</p> <!-- {{tweetOwner}} is in the data model. --> <button>Update Entries</button> </div> <!-- Here is a Vue loop for generating a lit --> <ol> <li v-for="tweet in tweets"> <!-- here is the first tweet represented as an object with a lable and tweet text --> <div class="entryart"> <input v-model="tweet.def[0].label" /> <input v-model="tweet.def[0].tweet" /> </div> <!-- here is the second tweet in the slot. But, notice that it is optional. --> <div class="entryart" v-if="tweet.def.length > 1"> <input v-model="tweet.def[1].label"/> <input v-model="tweet.def[1].tweet"/> </div> </li> </ol> </div> <script> var twtApp = new Vue({ el: '#tweetAppDiv', data: { tweets: [ // Where is the data? Still on the server.s ], tweetOwner : "Lucky Dude" // picked a name for demo } }); </script> </body> </html> <script> // Notice that you don't have to do everything in the Vue framework. // Here we are using some native API calls var gDefaultPostInfo = { // there server is beyond simple - an example from node.js docs method: 'POST', // or 'PUT' mode: "cors", // no-cors, cors, *same-origin cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached credentials: "same-origin", // include, *same-origin, omit redirect: "follow", // manual, *follow, error referrer: "no-referrer", // no-referrer, *client body: "", headers:{ 'Content-Type': 'application/json' } } // // // recall the "onload" function GetTweets(event) { var url = "https://localhost:8080/twitlist1.json" // We have a fixed file name. fetch(url).then((response) => { // this is now browser native response.text().then((text) => { var newData = JSON.parse(text); // DATA UPDATE! This is it. twtApp.tweets = newData // the page update right away with new data. }); }); } function sendTweets() { // recall the button up above. This is not a Vue style button, but still in the Vue app. var url = "https://localhost:8080/" var data = twtApp.tweets; // GET THE DATA OUT OF VUE. That's all folks. // // so happens that Vue pulls out the right data and stringifies it. var jdata = JSON.stringify(data); // data can be `string` or {object}! // gDefaultPostInfo.body = jdata; // that's for fetch - not Vue related // fetch(url,gDefaultPostInfo).then(res => { // We use fetch to POST as well as GET res.json() }).then(response => { console.log('Success:', JSON.stringify(response)) // promises }).catch(error => { console.error('Error:', error) }); } // // // </script>
Jadi, hanya untuk menyoroti garis luar biasa yang berbicara tentang kekuatan kerangka kerja, mari kita ulangi di sini:
A. Ini menarik data keluar.
postOptionsObject.body = JSON.stringify(twtApp.tweets);
B. Ini memasukkan data ke dalam Vue dan melihat pembaruan layar:
twtApp.tweets = JSON.parse(text) // text is the server response
Berapa banyak pekerjaan itu?
Sepertinya akan ada cara yang bagus untuk mengungkapkan bagaimana data akan memperbarui panel untuk IoT.
Sekarang, mari kita ubah tweet menjadi ikon yang dapat diklik yang dirancang untuk mengambil komponen dari server web.
Dari Tweet ke Ikon Pengambilan Panel
Orang suka menggunakan SVG untuk ikon. Mereka lebih suka penggunaan itu untuk SVG daripada untuk hal-hal lain sejauh yang saya tahu. Saya hanya membahas sejumlah situs web yang menjual atau memberikan ikon yang dibuat dalam SVG. Nilai jualnya adalah grafik garis memiliki byte lebih sedikit daripada gambar. Dan, jika saya akan meminta daftar gambar dengan perilaku seperti tombol, saya mungkin telah mengambil PNG atau JPEG pada hari-hari SVG berada di iframe. But, we can even find libraries in the Vue contributor lists that help us to a serving of icons.
We can turn the tweets page into an icon list returned as a search result. Just a little code has to be changed. Of course, there are a few things to be careful about if we want SVG icons to be loaded as buttons. Vue provides mechanisms for putting HTML into the application. These mechanisms have to be used or DOM elements fetched from the server don't get interpreted.
Here is the kind of rendering you can get from view if you follow your first impulse in creating a handlebars style variable location in the application DOM.
Here is the code that produces the result in the picture:
<div> <div class="entryart"> <span class="oneItem" v-for="icon in iconList"> {{icon}} </span> </div> </div> <script> var iconApp = new Vue({ el: '#iconAppTry', data: { iconList: [ // Where is the data? Still on the server. ], queryToken : "Thermo Batches" // picked a name for demo } }); </script>
Notice that we have gone from looping over tweets to looping over icons. tweet in tweets
changed into icon in iconList
. Our twtApp
hooks into the DOM element #tweetAppDiv
, while our iconApp
hooks into the DOM element #iconAppTry
. Within the Vue option object, the data
subobject has a tweets
in the first app, and iconList
in the second. The fields are both empty arrays that receive data when the fetch
routine does its job.
But, we have imitated our tweet app too closely. In the code above, the iconList is an array, and the server is expected to send an array of strings. So, let's say the server has sent us HTML, and we have it properly decoded with the array assigned to data.iconList
. Then, the picture above can be seen.
Now, let's change the code just a little. In this revised code, we can see the following:
v-html="icon">
Vue responds to the v-html syntax by putting in the DOM of the icon
element. Notice that the syntax is included after the loop directive as another attribute to the span
tag.
By removing the handlebars
syntax and using v-html
, our picture changes to something more comprehensible:
<div> <div class="entryart"> <span class="oneItem" v-for="icon in iconList" v-html="icon"> </span> </div> </div> <script> var iconApp = new Vue({ el: '#iconAppTry2', data: { iconList: [ // Where is the data? Still on the server. ], queryToken : "Thermo Batches" // picked a name for demo } }); </script>
While v-html
is a quick way to do things, the Vue team recommends using components to get the desired HTML into the page. That seems like a good idea, and we shall soon set about doing that.
But, let's use the v-html
syntax for our next example.
It's time to set up our working example for fetching SVG icons. Let's have those icons be responsive to a button click. Once those are working, we can get the panels associated with an icon.
Let's suppose that the SVG required for icons is stored in a database. For our example, we can just fetch a JSON file from the server. The grown-up version of the icon server would store many such files in a database, and deliver them to the page with the same mechanisms.
Also, it's best if the SVG arrives on the page URL encoded since we will be using JSON parse. The SVG can be decoded by calling JavaScript's decodeURIComponent
function.
In order to simulate the response to searching, we can make use of several JSON files. The page can have one button for each file. Here is the code for the page:
<!DOCTYPE html> <html lang="en" prefix="og: https://ogp.me/ns#"> <!-- define microdata scope and type --> <head itemscope itemtype="https://schema.org/Article"> <title>Search Bar</title> <style> body { margin: 2em; } div { margin: 6px; } .entryart { border: solid 1px navy; width: 80%; padding: 2px; padding-left: 6px; margin: 2px; margin-bottom: 3px; background-color: #EEF4EE; } .oneItem { background-color: #EEFFFF; margin: 2px; padding: 4px; border: solid 1px purple; } </style> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> </head> <body> <!-- some old fashioned handling --> <!-- The Vue app starts here. This is the HTML part of the Vue object --> <div> <!-- Recognize the name from the Vue doc --> <div> <h2 itemprop="name">Request MCU Groups</h2> <p itemprop="description">These are groups satistfying this query: {{queryToken}}.</p> <!-- {{tweetOwner}} is in the data model. --> <button>Find All</button> <button>Find 5 Point</button> <button>Find 6 Point</button> </div> <!-- Here is a Vue loop for generating a lit --> <div class="entryart"> <button v-for="iconEntry in iconList" @click="goGetPanel(iconEntry.name)" > <div v-html="iconEntry.icon"> </div> </button> </div> </div> <script> var iconApp = new Vue({ el: '#iconAppTry', data: { iconList: [ // Where is the data? Still on the server. ], queryToken : "Thermo Batches" // picked a name for demo }, methods : { goGetPanel: (pname) => { // `this` inside methods points to the Vue instance alert('Hello ' + pname + '!') } } }); </script> </body> </html> <script> // // recall the "onclick" on the <buttons> function GetIcons(points) { // special file names instead of search parameters // var url = (points == 11) ? "https://localhost:8080/batchQuery-all.json" : ((points == 5) ? "https://localhost:8080/batchQuery-five.json" : "https://localhost:8080/batchQuery-six.json") fetch(url).then((response) => { // this is now browser native response.text().then((text) => { var newData = JSON.parse(text); // DATA UPDATE! This is it. newData = newData.map(obj => { obj.icon = decodeURIComponent(obj.icon); return(obj) }); iconApp.iconList = newData; // the page update right away with new data. }); }); } </script>
Here is one display of icons that have been fetched from the server:
The data being sent is an array with the following kind of structure:
{ "style" : { "color" : "red", "backgroundColor" : "yellow" }, "icon" : svg1, "name" : "thermos" },
Di sini, svg1
adalah SVG yang diambil dari sebuah file. Tentu saja, server yang benar akan mengambil struktur dari database, di mana SVG akan disimpan dalam struktur.
Berikut adalah cuplikan dari kode di atas. Ini adalah kode yang mengambil JSON dan menempatkan array struktur ke dalam aplikasi Vue. Anda dapat melihat struktur janji dari fetch
yang digunakan. Teks diuraikan, dan di baris berikutnya, SVG yang disandikan didekodekan. Satu baris lagi, dan Vue memperbarui halaman. Jumlah tombol di bilah tombol akan sama dengan panjang larik JSON.
fetch(url).then((response) => { // this is now browser native response.text().then((text) => { var newData = JSON.parse(text); // DATA UPDATE! This is it. newData = newData.map(obj => { obj.icon = decodeURIComponent(obj.icon); return(obj) }); // the page update right away with new data. iconApp.iconList = newData; }); });
Sekarang, tinggal dua cuplikan lagi. Aplikasi Vue. Pembaca akan melihat bahwa @click
directive telah disertakan pada tombol. Elemen data, iconEntry.name
, diteruskan ke metode dalam tanda kutip.
Metode ini didefinisikan dalam aplikasi Vue:
<div class="entryart"> <button v-for="iconEntry in iconList" @click="goGetPanel(iconEntry.name)" > <div v-html="iconEntry.icon"> </div> </button> </div> </div>
Berikut adalah cuplikan untuk definisi metode. Objek methods
ditambahkan tepat setelah objek data
di dalam objek parameter aplikasi:
, methods: { goGetPanel: (pname) => { // `this` inside methods points to the Vue instance alert('Hello ' + pname + '!') } }
Pembaca harus menemukan definisi goGetPanel
, dan penggunaannya ditunjukkan untuk penangan @click
. Dalam aplikasi terakhir kami, panggilan alert
dapat diganti dengan fungsi yang mengambil panel dari server.
Pustaka Komponen Untuk Panel IoT
Kita dapat memutuskan bahwa panel yang kita ambil dari server dapat berupa gambar HMTL atau SVG saja, tetapi jika akan ada banyak jenis panel, kami berharap pekerjaan membuat panel dapat disederhanakan dengan memiliki perpustakaan komponen untuk Pilih dari. Kita dapat membayangkan bahwa editor SVG dapat ditingkatkan untuk memungkinkan komponen perpustakaan dijatuhkan ke gambar sebagai bagian dari pengeditan. Kemudian, jika editor SVG dapat menampilkan versi gambar dengan tag komponen, maka penggunaan Vue akan memungkinkan gambar dibuat sambil memastikan bahwa otomatisasi JavaScript dan animasi terjalin dengan rapi. Untuk diskusi kami, beberapa pengeditan tangan dapat membantu kami sampai di sana.
Jika kita ingin membuat panel dari komponen Vue, maka sebaiknya kita mencari cara untuk membuat komponen dan kemudian mengumpulkannya menjadi sesuatu yang berguna. Kita harus beralih menggunakan alat baris perintah yang disediakan oleh Vue dan mengatur alur kerja kita.
Komponen
Dokumentasi Vue menunjukkan bahwa bagian data
komponen (subobjek) dari definisi komponen harus berupa fungsi yang mengembalikan data. Alasannya adalah karena Vue perlu memisahkan data di antara instance. Jadi, dalam beralih dari inisialisasi aplikasi Vue ke definisi komponen, ada perubahan kode kecil lainnya.
Dalam potongan kode pertama ini, aplikasi Vue sedang diinisialisasi:
var iconApp = new Vue({ el: '#iconApp', data: { // this is the data field that can be easily updated }, methods : { ... } });
Dalam potongan kode baru ini, sebuah komponen sedang didefinisikan dan didaftarkan. Pertama, perhatikan bahwa alih-alih membuat instance new Vue
, komponen bernama iconic
sedang didaftarkan. Kemudian, bidang data
mengembalikan data khusus untuk setiap instance iconic
yang dibuat oleh aplikasi Vue. Akhirnya, bidang template
ada di akhir pendaftaran komponen. Setiap HTML yang mungkin telah ditulis pada halaman web untuk menampilkan komponen dapat menjadi bagian dari template
.
Vue.component('iconic', data: () => { var instanceData = { // data fields named for the // variables appearing in the template onevar : "test" } return(instanceData); }, methods : { ... }, template: '<div>This appears in every instance {{onevar}}</div>' });
Jadi, kita bisa membayangkan sebuah panel dengan termometer. Jadi, jika seseorang menyediakan komponen thermometer
, kita akan mengharapkan definisi komponen di suatu tempat dalam kode kita. Dengan demikian:
Vue.component('thermometer', data: () => { var instanceData = { // data fields named for the // variables appearing in the template temperature : 0 } return(instanceData); }, methods : { ... }, template: '<div>Some SVG will go here</div>' });
Kami mencoba membuat sesuatu yang terlihat seperti ini:
Komponen termometer sangat mirip dengan komponen pertama yang akan Anda temukan di tutorial Vue. Tapi, agak sulit untuk mengetahui cara memperbaruinya. Ada cara yang lebih baik untuk mendefinisikan komponen untuk reaktivitas menggunakan properti. Dan, itu adalah sebagai berikut:
Vue.component('thermometer', { props: ['temperature'], computed : { y: function() { var t = this.temperature/100; var h = 54.724472; var y_bar = 41.176476 // starts near the top // pretend the scale is 1 to 100, so that the temperature is a precentage return((1 - t)*h + y_bar) }, height : function() { var t = this.temperature/100; var h = 54.724472; // as high as the whole range var y_bar = 41.176476 // pretend the scale is 1 to 100, so that the temperature is a precentage return(t*h) } }, template: '#thermometer-template' })
Jadi, alih-alih mewakili suhu sebagai elemen data. Ini direpresentasikan sebagai properti di bawah props
. Kemudian, ada bagian baru, computed , yang menyediakan variabel yang merupakan fungsi dari properti. Kita melihat this.temperature
digunakan untuk y
dan height
. Variabel yang dihitung ini digunakan dalam SVG sebagai atribut untuk persegi panjang.
Di SVG, y
tumbuh dari atas ke bawah. Jadi, ketika kita ingin persegi panjang menjadi kecil di bagian bawah termometer, y
kotak merah harus lebih rendah, dan tingginya harus dikurangi sehingga ( y + height
) tetap pada termometer nol.
Perhatikan bidang template
dalam definisi komponen. Sebenarnya, ini adalah ID elemen dokumen. Elemen yang dirujuk adalah bagian skrip dengan tipe khusus: type="text/x-template"
. Elemen skrip adalah tempat SVG untuk termometer berada. Dan, SVG menggunakan variabel Vue dan istilah kontrol sehingga reaktivitas dapat didefinisikan.
Berikut beberapa SVGnya:
<script type="text/x-template"> <svg xmlns:svg="https://www.w3.org/2000/svg" xmlns="https://www.w3.org/2000/svg" width="20" height="70" version="1.1" > <g transform="translate(0,-180)"> <g transform="matrix(2.0111869,0,0,1.0489665,-215.11053,144.5592)"> <rect stroke-linecap="null" stroke-linejoin="null" width="2.9665921" height="54.724472" x="111.90748" y="41.176476" /> <rect stroke-linecap="null" stroke-linejoin="null" width="2.9665921" x="111.90748" :height="height" :y="y" /> <g transform="matrix(0.76503813,0,0,1,26.586929,0)"> <line y2="57.306953" y1="57.306953" x2="113.15423" x1="107.22105" stroke-linejoin="null" stroke-linecap="null" /> <line y2="74.408356" y1="74.408356" x2="113.15423" x1="107.22105" stroke-linejoin="null" stroke-linecap="null"
Pembaca dapat menemukan id="thermometer-template"
di bagian atas, dan melihat lebih jauh ke bawah ke elemen rect
, variabel yang dihitung dapat ditemukan.
Di sini penggunaan variabel dipisahkan. Sintaks singkatan Vue untuk v-bind
sedang digunakan, dengan :height="height"
dan sama untuk y
:
x="111.90748" :height="height" :y="y"
Ketika induk dari elemen SVG menetapkan variabel yang bertindak sebagai masukan ke temperature
properti termometer , Vue menghitung ulang height
dan y
. Akibatnya, posisi dan ketinggian kotak merah berubah.
Ini membantu untuk memiliki daftar aplikasi Vue yang menggunakan termometer.
<body> <!-- The Vue app starts here. This is the HTML part of the Vue object --> <div> <!-- Recognize the name from the Vue doc --> <div> <h2 itemprop="name">Set Temperature</h2> <p itemprop="description">These are groups satistfying this query: {{queryToken}}.</p> <!-- {{tweetOwner}} is in the data model. --> <button @click="updateTemp(50,50)">mid</button> <button @click="updateTemp(20,80)">low</button> <button @click="updateTemp(80,20)">high</button> </div> <thermometer :temperature="temp1" ></thermometer> <thermometer :temperature="temp2" ></thermometer> </div> <script> var thermoApp = new Vue({ el: '#thermoApp', data: { temp1 : 30, temp2 : 60, queryToken : "HEAT" }, methods : { updateTemp: function (tval1,tval2) { this.temp1 = tval1; this.temp2 = tval2; } } }); </script> </body>
Itulah semuanya. Ada tiga tombol yang memanggil metode updateTemp
dari aplikasi thermoApp
Vue. Bagian data memiliki dua variabel suhu. Dan, setiap thermometer
memperbarui suhunya ketika nilainya berubah.
Kode untuk dua termometer yang disebutkan di bawah ini dapat ditemukan pada HTML yang ditetapkan untuk aplikasi Vue.
<thermometer :temperature="temp1" ></thermometer> <thermometer :temperature="temp2" ></thermometer>
Perhatikan bahwa aplikasi menggunakan formalisme function
untuk definisi metode. Mendefinisikan updateTemp
dengan cara ini updateTemp: function (tval1,tval2)
memungkinkan variabel instan this
untuk diakses.
Juga, mendefinisikan updateTemp
dengan cara ini updateTemp: (tval1,tval2) =>
menetapkan this
ke struktur data internal yang tidak bereaksi dan memperbarui tampilan.
Merakit Panel
Setiap panel IoT dapat menjadi komponen. Vue menyediakan cara untuk mendefinisikan komponen dengan subkomponen. Atau, ada mekanisme slot yang dapat digunakan untuk menghasilkan komponen yang dapat membungkus konten HTML apa pun.
Dalam beberapa paragraf berikut, mari kita lihat membuat panel dari subkomponen. Ada dua bentuk yang mengikuti dengan cepat dari contoh kita. Dalam satu kasus, termometer dapat menjadi subkomponen yang dipanggil dalam JavaScript. Dalam kasus lain, komponen didefinisikan secara independen tetapi disebutkan dalam HTML.
Dalam kedua kasus, HTML yang sama dapat digunakan untuk template. Berikut adalah panel kami sebagai template:
<script type="text/x-template"> <div> <thermometer :temperature="temp1" ></thermometer> <thermometer :temperature="temp2" ></thermometer> </div> </script>
Satu-satunya perbedaan antara perincian pertama aplikasi adalah bahwa elemen div
mengelilingi kedua termometer. Vue akan membuat kesalahan jika template tidak memiliki elemen DOM tingkat atas. div
melewati persyaratan Vue, dan beberapa elemen dapat dimasukkan di dalamnya.
Sekarang, kita dapat melihat dua termometer berdampingan. Melewati suhu dari atas ke termometer akhir memiliki nilai yang mengalir ke bawah. Di tingkat atas, panel bergabung dengan aplikasi saat satu baris disertakan dalam DOM aplikasi.
<themo-panel :temp1="temp1" :temp2="temp2" ></themo-panel>
Template untuk panel, meskipun sederhana, tampaknya menunjukkan bahwa panel dapat dengan mudah dirancang dari segi komponen. Seolah-olah bahasa hanya untuk komponen IoT saja yang memungkinkan.
Sekarang, definisi template untuk panel cukup sederhana. Ini dia dengan subkomponen yang didefinisikan secara independen:
Vue.component('thermo-panel', { props: ['temp1','temp2'], template: '#thermo-panel-template' });
Itu kira-kira sebanyak yang diperlukan untuk membuat panel berfungsi. Memang benar bahwa versi ini bergantung pada daftar panjang properti untuk menentukan nilai yang akan diperbarui saat pesan masuk ke halaman. Tapi, ini adalah awal yang baik. Memperbarui objek data
di tingkat atas melakukan tugas menghidupkan termometer. Namun, karena panel menjadi rumit, mungkin perlu ada metode lain untuk menunjukkan perubahan.
Setelah menyebutkan cara lain untuk menentukan subkomponen, untuk panel, kita harus melihatnya. Ini dia:
Vue.component('thermo-panel', { props: ['temp1','temp2'], template: '#thermo-panel-template', components: { // a sub component for the labels 'thermometer': { props: { temperature: Number, }, template: '#thermometer-template', computed : { y: function() { var t = this.temperature/100; var h = 54.724472; var y_bar = 41.176476 // starts near the top // pretend the scale is 1 to 100, so that the temperature is a precentage return((1 - t)*h + y_bar) }, height : function() { var t = this.temperature/100; var h = 54.724472; // as high as the whole range var y_bar = 41.176476 // pretend the scale is 1 to 100, so that the temperature is a precentage return(t*h) } } } } });
Tentu ada lebih banyak kode, tetapi itu karena JavaScript untuk komponen thermometer
termasuk dalam daftar komponen thermo-panel
. Kedua pendekatan melakukan pekerjaan yang sama, tetapi mereka menawarkan cara yang berbeda untuk definisi komponen pengemasan.
Saat ini, preferensi saya adalah untuk cara pertama. Seharusnya jauh lebih mudah untuk merevisi panel dan membuatnya diambil secara dinamis jika hanya mengubah template dan properti yang diperlukan. Untuk tujuan ini, komponen yang didefinisikan secara independen membentuk pustaka komponen. Namun, meskipun tampaknya lebih baik, berikut ini menjadi lebih nyaman untuk menggunakan cara kedua, yang tampaknya lebih bertele-tele.
Mengingat bahwa kita dapat membuat panel responsif dari komponen dengan cara yang jelas, saya akan menjelaskan bagaimana kita dapat mengelolanya sebagai database yang dapat membuat kueri sederhana di bagian selanjutnya dari artikel saya.