Алдыңғы жазбамда мен негізін салуға негіз салдым; енді «шынайы үшін» басталатын уақыт.
<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>
fun vue(todos: List<Todo>) = router { //1 GET("/vue") { ok().render("vue", mapOf("title" to "Vue.js", "todos" to todos)) //2-3 } }
Todo
нысандарының статикалық тізімін өткізіңіз
Егер сіз API әзірлеуге үйренген болсаңыз, body()
функциясымен таныссыз; ол пайдалы жүктемені тікелей қайтарады, мүмкін JSON пішімінде. render()
ағынды көру технологиясына береді, бұл жағдайда Thymeleaf. Ол екі параметрді қабылдайды:
/templates
және префикс .html
; бұл жағдайда Thymeleaf /templates/vue.html
мекенжайында көрініс күтеді
<script th:src="@{/webjars/axios/dist/axios.js}" src="//cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script> <!--1--> <script th:src="@{/webjars/vue/dist/vue.global.js}" src="//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>
Өткен аптадағы мақалада түсіндірілгендей, Thymeleaf артықшылықтарының бірі - ол статикалық файлдарды көрсетуге де, серверлік көрсетуге де мүмкіндік береді. Сиқырлы жұмыс істеу үшін мен клиенттік жолды, яғни src
және серверлік жолды, яғни th:src
жолын көрсетемін.
Todo
элементтерін көрсетуі керекTodo
орындалған құсбелгіні басқан кезде, ол completed
төлсипатты орнату/өшіру керекTodo
жоядыTodo
тізіміне Todo
қосуы керек:id
: барлық басқа идентификаторлардың максимумы ретінде сервер тарапынан есептелген идентификатор плюс 1label
: label
арналған Белгі өрісінің мәніcompleted
: false
мәніне орнатылды Бірінші қадам - фреймворкті жүктеу. Жоғарыдағы пайдаланушы vue.js
файлы үшін сілтемені орнатып қойғанбыз.
document.addEventListener('DOMContentLoaded', () => { //1 // The next JavaScript code snippets will be inside the block }
Келесі қадам - Vue-ге беттің бір бөлігін басқаруға мүмкіндік беру. HTML жағында біз Vue жоғарғы деңгейдің қай бөлігін басқаратынын шешуіміз керек. Біз ерікті <div>
таңдай аламыз және қажет болса, оны кейінірек өзгерте аламыз.
<div id="app"> </div>
JavaScript жағында біз алдыңғы HTML <div>
CSS селекторын өткізіп, қолданба жасаймыз.
Vue.createApp({}).mount('#app');
Келесі қадам Vue үлгісін жасау болып табылады. Vue үлгісі — Vue басқаратын кәдімгі HTML <template>
. Сіз Javascript-те Vue-ді анықтай аласыз, бірақ мен оны HTML бетінде жасағанды қалаймын.
<template id="todos-app"> <!--1--> <h1>{{ title }}</h1> <!--2--> </template>
title
қасиетін пайдаланыңыз; орнату керек
const TodosApp = { props: ['title'], //1 template: document.getElementById('todos-app').innerHTML, }
title
сипатын жариялаңыз
Vue.createApp({ components: { TodosApp }, //1 render() { //2 return Vue.h(TodosApp, { //3 title: window.vueData.title, //4 }) } }).mount('#app');
render()
функциясын күтедіh()
гиперскрипт үшін объект пен оның қасиеттерінен виртуалды түйін жасайдыtitle
сипатын инициализациялаңыз
Біріншіден, мен Todo
көрсететін кесте үшін жаңа кірістірілген Vue үлгісін қостым. Жазбаны ұзартпау үшін мен оны егжей-тегжейлі сипаттаудан аулақ боламын. Егер сізді қызықтырса, қараңыз.
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
идентификаторын көрсетіңізTodo
белгісін көрсетіңізcompleted
төлсипаты true
болса, құсбелгіні қойыңыз
Vue оқиғаны @
синтаксисі арқылы өңдеуге мүмкіндік береді.
<input type="checkbox" :checked="todo.completed" @click="check" />
Пайдаланушы желіні басқан кезде Vue шаблонның check()
функциясын шақырады. Бұл функцияны setup()
параметрінде анықтаймыз:
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
массивін қабылдаңызevent
өтеді
<button class="btn btn-warning" @click="cleanup">Cleanup</button>
TodosApp
нысанында біз аттас функцияны қосамыз:
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
- біз үлгіні сақтайтын жер
Vue семантикасында Vue үлгісі - біз реактивті болғымыз келетін деректердің айналасындағы орауыш. Реактивті көрініс пен модель арасындағы екі жақты байланысты білдіреді. Біз бар мәнді ref()
әдісіне беру арқылы реактивті ете аламыз:
Composition API ішінде реактивті күйді жариялаудың ұсынылатын жолы
ref()
функциясын пайдалану болып табылады.
ref()
аргументті қабылдайды және оны .value сипаты бар ref нысанына оралған күйде қайтарады.
Компонент үлгісіндегі сілтемелерге қол жеткізу үшін оларды құрамдастың
setup()
функциясынан жариялаңыз және қайтарыңыз.--
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
орнату жолын өзгертеміз. Бұл қажет емес, өйткені екі жақты байланыстыру жоқ - біз клиенттік тақырыпты жаңартпаймыз, бірақ мен өңдеуді барлық мәндер бойынша когерентті сақтауды қалаймынstate
атрибутталған нысанды теңшеңіз
Осы кезде бізде реактивті клиенттік үлгі бар.
<tbody> <tr is="vue:todo-line" v-for="todo in todos" :key="todo.id" :todo="todo"></tr> <!--1-2--> </tbody>
Todo
нысандарының тізімін айналдырыңызis
атрибуты браузердің HTML талдау әдісімен күресу үшін өте маңызды. Қосымша мәліметтер алу үшін қараңыз Енді біз жаңа мүмкіндікті іске асыра аламыз: клиенттен жаңа Todo
қосыңыз. Қосу түймешігін басқан кезде біз Label өрісінің мәнін оқимыз, деректерді API-ге жібереміз және модельді жауаппен жаңартамыз.
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()
функциясы дұрысTodo
тізіміне қосыңыз
HTML жағында біз түймені қосамыз және create()
функциясына байланыстырамыз. Сол сияқты, біз Label өрісін қосып, оны үлгіге байланыстырамыз.
<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()
функциясын HTML түймешігімен байланыстырады. Ол оны асинхронды түрде шақырады және қоңырау арқылы қайтарылған жаңа элементпен реактивті Todo
тізімін жаңартады. Белгіленген Todo
нысандарын жою үшін «Тазалау» түймесі үшін де солай істейміз.
Бұл постта мен Vue көмегімен SSR қолданбасын кеңейтудегі алғашқы қадамдарымды жасадым. Бұл өте қарапайым болды. Мен кездестірген ең үлкен мәселе Vue желісі үлгісін ауыстыру болды: мен құжаттаманы көп оқымадым және is
атрибутын жіберіп алдым.
Әрі қарай жүріңіз: