Oldingi postimda men qurilish uchun zamin yaratdim; endi "haqiqiy" boshlash vaqti.
Men juda ko'p Vue.js eshitdim. Bundan tashqari, ishlab chiquvchidan menejerga o'tgan do'stim menga Vue haqida yaxshi narsalarni aytib berdi, bu mening qiziqishimni yanada oshirdi. Men buni ko'rib chiqishga qaror qildim: bu men o'rganadigan birinchi "engil" JavaScript ramkasi bo'ladi - men yangi boshlovchi nuqtai nazaridan.
Men oxirgi postda WebJars va Thymeleafni tushuntirdim. Bu yerda sozlash, server va mijoz tomoni.
Men ikkalasini ham POMga qanday qilib birlashtiraman:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!--1--> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> <!--2--> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>webjars-locator</artifactId> <!--3--> <version>0.52</version> </dependency> <dependency> <groupId>org.webjars.npm</groupId> <artifactId>vue</artifactId> <!--4--> <version>3.4.34</version> </dependency> </dependencies>
Men Spring Boot tomonida Kotlin Router va Bean DSL-dan foydalanmoqdaman:
fun vue(todos: List<Todo>) = router { //1 GET("/vue") { ok().render("vue", mapOf("title" to "Vue.js", "todos" to todos)) //2-3 } }
Todo
ob'ektlarining statik ro'yxatini o'tkazing
Agar siz API-larni ishlab chiqishga odatlangan bo'lsangiz, siz body()
funksiyasi bilan tanishsiz; u to'g'ridan-to'g'ri foydali yukni qaytaradi, ehtimol JSON formatida. render()
oqimni ko'rish texnologiyasiga o'tkazadi, bu holda Thymeleaf. U ikkita parametrni qabul qiladi:
/templates
va prefiks .html
; bu holda, Thymeleaf /templates/vue.html
manzilida ko'rinishni kutadiMana HTML tomonidagi kod:
<script th:src="@{/webjars/axios/dist/axios.js}" src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script> <!--1--> <script th:src="@{/webjars/vue/dist/vue.global.js}" src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.js"></script> <!--2--> <script th:src="@{/vue.js}" src="../static/vue.js"></script> <!--3--> <script th:inline="javascript"> /*<![CDATA[*/ window.vueData = { <!--4--> title: /*[[${ title }]]*/ 'A Title', todos: /*[[${ todos }]]*/ [{ 'id': 1, 'label': 'Take out the trash', 'completed': false }] }; /*]]>*/ </script>
O'tgan haftadagi maqolada aytib o'tilganidek, Thymeleafning afzalliklaridan biri shundaki, u statik fayllarni va server tomonida ko'rsatish imkonini beradi. Sehrli ish qilish uchun men mijoz tomoni yo'lini, ya'ni src
va server tomonini, ya'ni th:src
belgilayman.
Keling, Vue kodiga o'taylik.
Biz bir nechta xususiyatlarni amalga oshirishni xohlaymiz:
Todo
elementlarini ko'rsatishi kerakTodo
tugallangan katakchani bosganingizda, u completed
atributni o'rnatishi/o'chirishi kerakTodo
o'chiradiTodo
ro'yxatiga quyidagi qiymatlar bilan Todo
qo'shishi kerak:id
: Server tomoni hisoblangan identifikatori boshqa barcha identifikatorlarning maksimali va 1label
: label
uchun Label maydonining qiymaticompleted
: false
o'rnatildi Birinchi qadam - bu ramkani yuklash. Yuqoridagi maxsus vue.js
faylimiz uchun havolani allaqachon sozlaganmiz.
document.addEventListener('DOMContentLoaded', () => { //1 // The next JavaScript code snippets will be inside the block }
Keyingi qadam Vue-ga sahifaning bir qismini boshqarishga ruxsat berishdir. HTML tomonida biz Vue qaysi yuqori darajadagi qismini boshqarishini hal qilishimiz kerak. Biz ixtiyoriy <div>
tanlashimiz va kerak bo'lganda uni keyinroq o'zgartirishimiz mumkin.
<div id="app"> </div>
JavaScript tomonida biz oldingi HTML <div>
ning CSS selektoridan o'tib, ilova yaratamiz.
Vue.createApp({}).mount('#app');
Shu nuqtada, sahifa yuklanganda biz Vue-ni ishga tushiramiz, lekin ko'rinadigan hech narsa sodir bo'lmaydi.
Keyingi qadam Vue shablonini yaratishdir. Vue shabloni bu Vue tomonidan boshqariladigan oddiy HTML <template>
. Siz Vue-ni Javascript-da belgilashingiz mumkin, lekin men buni HTML sahifasida qilishni afzal ko'raman.
Sarlavhani ko'rsatadigan ildiz shablonidan boshlaylik.
<template id="todos-app"> <!--1--> <h1>{{ title }}</h1> <!--2--> </template>
title
xususiyatidan foydalaning; uni o'rnatish kerak
JavaScript tomonida biz boshqaruv kodini yaratishimiz kerak.
const TodosApp = { props: ['title'], //1 template: document.getElementById('todos-app').innerHTML, }
title
xususiyatini e'lon qiling
Nihoyat, ilovani yaratishda biz ushbu ob'ektni o'tkazishimiz kerak:
Vue.createApp({ components: { TodosApp }, //1 render() { //2 return Vue.h(TodosApp, { //3 title: window.vueData.title, //4 }) } }).mount('#app');
render()
funksiyasini kutadih()
giperskript uchun ob'ekt va uning xususiyatlaridan virtual tugun yaratadititle
xususiyatini server tomonida yaratilgan qiymat bilan ishga tushiring
Ushbu nuqtada Vue sarlavhani ko'rsatadi.
Ushbu nuqtada, foydalanuvchi belgilash katakchasini bosganida amalni amalga oshirishimiz mumkin: u server tomonida yangilanishi kerak.
Birinchidan, men Todo
ko'rsatadigan jadval uchun yangi Vue shablonini qo'shdim. Xabarni uzaytirmaslik uchun uni batafsil tavsiflashdan qochaman. Agar qiziqsangiz, manba kodini ko'rib chiqing.
Mana boshlang'ich satr shablonining kodi, mos ravishda JavaScript va HTML:
const TodoLine = { props: ['todo'], template: document.getElementById('todo-line').innerHTML }
<template id="todo-line"> <tr> <td>{{ todo.id }}</td> <!--1--> <td>{{ todo.label }}</td> <!--2--> <td> <label> <input type="checkbox" :checked="todo.completed" /> </label> </td> </tr> </template>
Todo
identifikatorini ko'rsatingTodo
yorlig'ini ko'rsatingcompleted
atribut true
bo'lsa, katakchani belgilang
Vue @
sintaksisi orqali hodisalarni boshqarishga imkon beradi.
<input type="checkbox" :checked="todo.completed" @click="check" />
Foydalanuvchi chiziqni bosganida, Vue shablonning check()
funksiyasini chaqiradi. Biz ushbu funktsiyani setup()
parametrida aniqlaymiz:
const TodoLine = { props: ['todo'], template: document.getElementById('todo-line').innerHTML, setup(props) { //1 const check = function (event) { //2 const { todo } = props axios.patch( //3 `/api/todo/${todo.id}`, //4 { checked: event.target.checked } //5 ) } return { check } //6 } }
props
qatorini qabul qilingevent
o'tadiOldingi bo'limda men ikkita xatoga yo'l qo'ydim:
Biz buni keyingi xususiyatni, ya'ni tugallangan vazifalarni tozalash orqali amalga oshiramiz.
Endi biz Vue orqali voqealarni qanday boshqarishni bilamiz:
<button class="btn btn-warning" @click="cleanup">Cleanup</button>
TodosApp
ob'ektida biz bir xil nomdagi funktsiyani qo'shamiz:
const TodosApp = { props: ['title', 'todos'], components: { TodoLine }, template: document.getElementById('todos-app').innerHTML, setup() { const cleanup = function() { //1 axios.delete('/api/todo:cleanup').then(response => { //1 state.value.todos = response.data //2-3 }) } return { cleanup } //1 } }
state
- bu modelni saqlaydigan joy
Vue semantikasida Vue modeli biz reaktiv bo'lishni xohlaydigan ma'lumotlar atrofidagi o'rashdir. Reaktiv ko'rinish va model o'rtasidagi ikki tomonlama bog'lanishni anglatadi. Biz mavjud qiymatni ref()
usuliga o'tkazish orqali reaktiv qilishimiz mumkin:
Composition API'da reaktiv holatni e'lon qilishning tavsiya etilgan usuli
ref()
funktsiyasidan foydalanishdir.
ref()
argumentni oladi va uni .value xususiyatiga ega ref ob'ektiga o'ralgan holda qaytaradi.
Komponent shablonidagi referatlarga kirish uchun ularni komponentning
setup()
funksiyasidan e'lon qiling va qaytaring.
Keling buni bajaramiz:
const state = ref({ title: window.vueData.title, //1-2 todos: window.vueData.todos, //1 }) createApp({ components: { TodosApp }, setup() { return { ...state.value } //3-4 }, render() { return h(TodosApp, { todos: state.value.todos, //5 title: state.value.title, //5 }) } }).mount('#app');
title
o'rnatish usulini o'zgartiramiz. Bu shart emas, chunki ikki tomonlama bog'lanish yo'q - biz mijoz tomoni sarlavhasini yangilamaymiz, lekin men barcha qiymatlar bo'ylab ishlashni izchil saqlashni afzal ko'ramanstate
atributini sozlang
Ayni paytda bizda reaktiv mijoz modeli mavjud.
HTML tomonida biz tegishli Vue atributlaridan foydalanamiz:
<tbody> <tr is="vue:todo-line" v-for="todo in todos" :key="todo.id" :todo="todo"></tr> <!--1-2--> </tbody>
Todo
ob'ektlari ro'yxatini aylantiringis
atributi brauzer HTMLni tahlil qilish usulini engish uchun juda muhimdir. Qo'shimcha ma'lumot olish uchun Vue hujjatlariga qarangMen yuqorida tegishli shablonni tasvirlab berdim.
Endi biz yangi xususiyatni amalga oshirishimiz mumkin: mijozdan yangi Todo
qo'shing. Qo'shish tugmasini bosganimizda biz Label maydoni qiymatini o'qiymiz, ma'lumotlarni API ga yuboramiz va javob bilan modelni yangilaymiz.
Mana yangilangan kod:
const TodosApp = { props: ['title', 'todos'], components: { TodoLine }, template: document.getElementById('todos-app').innerHTML, setup() { const label = ref('') //1 const create = function() { //2 axios.post('/api/todo', { label: label.value }).then(response => { state.value.todos.push(response.data) //3 }).then(() => { label.value = '' //4 }) } const cleanup = function() { axios.delete('/api/todo:cleanup').then(response => { state.value.todos = response.data //5 }) } return { label, create, cleanup } } }
create()
funktsiyasi to'g'riTodo
ro'yxatiga qo'shing
HTML tomonida biz tugma qo'shamiz va create()
funksiyasiga bog'laymiz. Xuddi shunday, biz Label maydonini qo'shamiz va uni modelga bog'laymiz.
<form> <div class="form-group row"> <label for="new-todo-label" class="col-auto col-form-label">New task</label> <div class="col-10"> <input type="text" id="new-todo-label" placeholder="Label" class="form-control" v-model="label" /> </div> <div class="col-auto"> <button type="button" class="btn btn-success" @click="create">Add</button> </div> </div> </form>
Vue create()
funksiyasini HTML tugmasi bilan bog‘laydi. U uni asinxron tarzda chaqiradi va qo'ng'iroq orqali qaytarilgan yangi element bilan reaktiv Todo
ro'yxatini yangilaydi. Belgilangan Todo
obyektlarini olib tashlash uchun "Tozalash" tugmasi uchun ham xuddi shunday qilamiz.
E'tibor bering, men kodni kerak bo'lgandan ko'ra murakkablashtirmaslik uchun hech qanday xatolik kodini ataylab amalga oshirmaganman. Birinchi tajriba uchun yetarli tushunchaga ega bo‘lganimiz uchun shu yerda to‘xtayman.
Ushbu postda men Vue bilan SSR ilovasini ko'paytirish bo'yicha birinchi qadamlarimni qo'ydim. Bu juda oddiy edi. Men duch kelgan eng katta muammo Vue-ning chiziq shablonini almashtirishi edi: men hujjatlarni ko'p o'qimaganman va is
atributini o'tkazib yuborganman.
Biroq, men JavaScript-ning bir nechta qatorlarini yozishim kerak edi, garchi men HTTP qo'ng'iroqlarida yordam berish uchun Axios-dan foydalanganman va xatolarni boshqara olmaganman.
Keyingi postda men Alpine.js bilan bir xil xususiyatlarni amalga oshiraman.
Ushbu postning toʻliq manba kodini GitHub’da topish mumkin:
Oldinga boring: