Основы Vue.js — шпаргалка
Привет, мир не стоит на месте и технологии развиваются, так происходит и c JS. Все помнят когда вышел Jquery какой бум он произвел в среде JS разработке, но технологии не стоят на месте и вот на смену пришел vue.js. С помощью данного фреймворка можно сделать достойный проект в котором будет ООП если вы его даже не знаете. В этой статье речь пойдет основах VUE и с течением моих знаний будет пополняться данная статья.
Установка и настройка
Скачать фреймворк можно на оф. сайта. Я использую для подключения CDN:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- Подключаем VUE.JS--> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> </body> </html>
Для работы Vue нужно также указать блок, который вуе будет обрабатывать, а также свойство data.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- Тут указываем блок, с которым работает VUE --> <div id="app"> </div> <!-- Подключаем VUE.JS--> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script> const app = new Vue({ el: "#app"//el зарезервировано data:{//data зарезервировано // тут уже любые свойства } }) </script> </body> </html>
Все установку и настройку мы закончили, можно переходить к использованию фреймворка.
Методы
Тут будем указывать наши методы (те же самые функции).
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- Тут указываем блок, с которым работает VUE --> <div id="app"> <p>{{name}}</p> <p>{{sayHello}}</p> </div> <!-- Подключаем VUE.JS--> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script> const app = new Vue({ el: "#app",//el зарезервировано data:{//data зарезервировано // тут уже любые свойства name:'Антон', }, methods:{//methods зарезервировано sayHello(){ return `Привет, ${this.name}`; }, } }) </script> </body> </html>
Добавляем ссылку
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- Тут указываем блок, с которым работает VUE --> <div id="app"> <p>{{name}}</p> <p>{{sayHello}}</p> <a :href="link">Яндекс</a> </div> <!-- Подключаем VUE.JS--> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script> const app = new Vue({ el: "#app",//el зарезервировано data:{//data зарезервировано // тут уже любые свойства name:'Антон', link: 'https://ya.ru' }, methods:{ sayHello(){ return `Привет, ${this.name}`; }, } }) </script> </body> </html>
Указываем двоеточие перед href, тем самым сообщаем, что link теперь свойство data, а не строка.
Для того чтобы взять любое значение из data для любого атрибута в верстке, нужно перед атрибутом поставить двоеточие.
Работа с кнопкой
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- Тут указываем блок, с которым работает VUE --> <div id="app"> <p>{{name}}</p> <p>{{sayHello}}</p> <a :href="link">Яндекс</a> <button v-on:click="counter++">Increase</button> <p>{{counter}}</p> </div> <!-- Подключаем VUE.JS--> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script> const app = new Vue({ el: "#app",//el зарезервировано data:{//data зарезервировано // тут уже любые свойства name:'Антон', link: 'https://ya.ru', counter: 0 }, methods:{ sayHello(){ return `Привет, ${this.name}`; }, } }) </script> </body> </html>
v-on — регистрация события. Вместо v-on можно использовать символ @.
В примере используется событие click. Есть также событие с названием submit, если использовать его, то страничка будет перезагружать после нажатия на кнопку, чтобы это избежать нужно добавить submit.prevent. prevent – отменяет действие по дефолту, т.е. перезагрузку страници.
Функции
Также можно передавать функции из блока методов.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- Тут указываем блок, с которым работает VUE --> <div id="app"> <p>{{name}}</p> <p>{{sayHello}}</p> <a :href="link">Яндекс</a> <button @click=Increase(3)>Increase</button> <p>{{counter}}</p> </div> <!-- Подключаем VUE.JS--> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script> const app = new Vue({ el: "#app",//el зарезервировано data:{//data зарезервировано // тут уже любые свойства name:'Антон', link: 'https://ya.ru', counter: 0 }, methods:{ sayHello(){ return `Привет, ${this.name}`; }, Increase(step){ this.counter+=step; } } }) </script> </body> </html>
Event
Также можно передать событие с помощью $event.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- Тут указываем блок, с которым работает VUE --> <div id="app"> <p>{{name}}</p> <p>{{sayHello}}</p> <a :href="link">Яндекс</a> <button @click=Increase(3, $event)>Increase</button> <p>{{counter}}</p> </div> <!-- Подключаем VUE.JS--> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script> const app = new Vue({ el: "#app",//el зарезервировано data:{//data зарезервировано // тут уже любые свойства name:'Антон', link: 'https://ya.ru', counter: 0 }, methods:{ sayHello(){ return `Привет, ${this.name}`; }, Increase(step,e){ this.counter+=step; console.log(e); } } }) </script> </body> </html>
Тернарные операторы
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- Тут указываем блок, с которым работает VUE --> <div id="app"> <p>{{name}}</p> <p>{{sayHello}}</p> <a :href="link">Яндекс</a> <button @click=Increase(3, $event)>Increase</button> <p>{{counter}}</p> <p>{{ counter > 10 ? "больше 10" : "Меньше 10" }}</p> // Тернарный оператор </div> <!-- Подключаем VUE.JS--> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script> const app = new Vue({ el: "#app",//el зарезервировано data:{//data зарезервировано // тут уже любые свойства name:'Антон', link: 'https://ya.ru', counter: 0 }, methods:{ sayHello(){ return `Привет, ${this.name}`; }, Increase(step,e){ this.counter+=step; console.log(e); } } }) </script> </body> </html>
If … else
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- Тут указываем блок, с которым работает VUE --> <div id="app"> <!-- IF ELSE --> <p v-if="show">Показать</p> <p v-else="show">Не показывать</p> <button @click='show = !show'>GO</button> </div> <!-- Подключаем VUE.JS--> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script> const app = new Vue({ el: "#app",//el зарезервировано data:{//data зарезервировано // тут уже любые свойства show: false } }) </script> </body> </html>
Mausemove
Mausemove — движение курсора мышки.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- Тут указываем блок, с которым работает VUE --> <div id="app"> <p @mausemove="getCorordinates()">Lorem, ipsum dolor. {{ x }} / {{ y }} <span @mausemove.stop> не пересчитывать координаты на этом элементе</span> </p> </div> <!-- Подключаем VUE.JS--> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script> const app = new Vue({ el: "#app",//el зарезервировано data:{//data зарезервировано // тут уже любые свойства x: 0, y: 0 } methods:{ getCorordinates(){ //получать текущие координаты мышки this.x = event.clientX; this.y = event.clientX; } } }) </script> </body> </html>
Если в теге указать собитие @mausemove.stop, то пересчет координат не будет учитываться, т.е. мы это событие выключаем в этом теге.
V-model
Этот метод связывает значение с объектом data. Т.е. допустим есть объект data со свойством name: “Anton” и есть инпут, мы указали в атрибутах v-model=”name” теперь в инпуте при рендеренге будет отображаться Anton. Если ввести что-то другое в инпуте, то и свойство name в объекте data поменяет свое значение с “Anton” на то что вы ввели.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- Тут указываем блок, с которым работает VUE --> <div id="app"> <p>{{ name }}</p> <input type="text" v-model="name"> </div> <!-- Подключаем VUE.JS--> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script> const app = new Vue({ el: "#app",//el зарезервировано data:{//data зарезервировано // тут уже любые свойства name: "Anton" } }) </script> </body> </html>
В выше приведеном примере изменения будут меняться в режиме онлайн, а можно сделать, так, чтобы изменения вступали всилу после того, как пропадет фокус с инпута. Для этого укажите v-modal.lazy=”name”.
V-html
Вставляет в нутрь тега свойство объекта data. В качестве свойства может выступать что угодно, буть то целый готовый блок див или просто число.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- Тут указываем блок, с которым работает VUE --> <div id="app"> <p v-html="htmlLink"></p> </div> <!-- Подключаем VUE.JS--> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> let app = new Vue({ el: "#app", //el зарезервировано data:{//data зарезервировано // тут уже любые свойства htmlLink: "<a href='https://ya.ru'>Яндекс</a>" } }) </script> </body> </html>
V-for
Цикл for поможет обойти маасив и вывести найденое в верстке.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- Тут указываем блок, с которым работает VUE --> <div id="app"> <div v-for="item of product"> <ul> <li>{{ item.title }}</li> <li>{{ item.price }} руб.</li> <li>{{ item.quantity }} шт.</li> </ul> </div> </div> <!-- Подключаем VUE.JS--> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> let app = new Vue({ el: "#app", //el зарезервировано data:{//data зарезервировано // тут уже любые свойства product: [ { title: "Хлеб", price: 35, quantity: 1 }, { title: "Масло", price: 135, quantity: 2 }, { title: "Икра", price: 3500, quantity: 1 }, ] } }) </script> </body> </html>
Mounted
Это свойство которое запускаем в первую очередью. Т.е. тут можно размещать функции, которые нужно выполнить заранее.
Компоненты
Выше в примерах, все делалось в одном файле, что крайне удобно при разработке больших приложений. Теперь же мы будем делить код приложения на блоки. Создадим тестовое приложения. Погнали.
index.html
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> <!-- выводим компонент --> <mycomp></mycomp> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="comp.js"></script> <script src="main.js"></script> </body> </html>
main.js
const app = new Vue({ el: '#app' })
comp.js
//используем класс Vue и статический компонент, укажем два основных параметра //название компонента и второе объект, в котором есть свойство template Vue.component('mycomp', { template: '<p>Привет из компонента</p>' })
На выходе получим параграф с текстом “Привет из компонента”.
В компоненте помимо свойства template, еще есть свойство data, указывается в виде метода. Из этого свойства можно обращаться к любому созданному вами свойству объекта data.
Vue.component('mycomp', { data() { return { name: 'Антон', age: 34 } }, template: ` <div> <p>Привет, {{ name }}. Твой возраст {{ age }}.</p> </div> ` })
Также можно выводить в основном компоненте другие компоненты, вложенные.
//используем класс Vue и статический компонент, укажем два основных параметра //название компонента и второе объект, в котором есть свойство template Vue.component('mycomp', { data() { return { name: 'Антон', age: 34 } }, template: ` <div> <p>Привет, {{ name }}. Твой возраст {{ age }}.</p> <inner-comp></inner-comp> </div> ` }) Vue.component('inner-comp', { data() { return { counter: 0 } }, template: ` <div> <button @click='increase'>Push</button> <span>{{ counter }}</span> </div> `, methods: { increase() { this.counter++; } } })
Т.е. был создан еще один компонент inner-comp, и вызывается он через основной компонент.
Вложенность может быть любая, ограничений нет.
Вы можете вызывать вложенные компоненты через основной компонент или через вложенные, или через вложенные-вложенные, ограничений нет.
В template допускается один корневой тег, т.е. делаем один див и туда пихаем всю остальную верстку. Несколько главных дивов быть не может.
Переброс данных из шаблона index.html в компонент comp.js
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> <!-- выводим компонент --> <mycomp>123</mycomp> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="comp.js"></script> <script src="main.js"></script> </body> </html>
Для того чтобы вывести 123 нужно в comp.js указать в tempate тег slot.
//используем класс Vue и статический компонент, укажем два основных параметра //название компонента и второе объект, в котором есть свойство template Vue.component('mycomp', { data() { return { name: 'Антон', age: 34 } }, template: ` <div> <p>Привет, {{ name }}. Твой возраст {{ age }}.</p> <slot></slot> </div> ` })
Передаем данные из main.js в index.html -> comp.js с помощью атрибутов
Добавим атрибуты в index.html
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> <!-- выводим компонент --> <mycomp :name="name" :age ="age" x="1" title="test"></mycomp> <mycomp :name="name2" :age ="age2"></mycomp> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="comp.js"></script> <script src="main.js"></script> </body> </html>
Если перед атрибутом стоит :, то это значит брать данные из main.js.
Vue.component('mycomp', { props:[name, name2, age, age2,x,title], data() { return { name: 'Антон1', age: 341 } }, template: ` <div> <p>Привет, {{ name }}. Твой возраст {{ age }}.</p> <slot></slot> </div> ` })
В данном примере уже есть локальные переменные с name и age, но данные будут тянуться из main.js. Для того чтобы данные брались из локальных переменных, необходимо обращаться к ним через $data:
Vue.component('mycomp', { props:[name, name2, age, age2,x,title], data() { return { name: 'Антон', age: 34 } }, template: ` <div> <p>Привет, {{ $data.name }}. Твой возраст {{ $data.age }}.</p> <slot></slot> </div> ` })
Передаём атрибуты из основного компонента во вложенный, с помощью props.
Index.html
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> <!-- выводим компонент --> <mycomp></mycomp> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="comp.js"></script> <script src="main.js"></script> </body> </html>
main.js
const app = new Vue({ el: '#app', data:{ name: 'Антон', name2: 'Слава', age: 34, age2: 23, } })
comp.js
Vue.component('mycomp', { template: ` <div> <iner-comp :x=10></iner-comp> </div> ` }) Vue.component('iner-comp', { props:['x'], template: ` <div> <p>{{ x }}.</p> </div> ` })
Все тоже самое но намного проще с помощью $parent и $root.
$parent — обращение к родительскому компоненту из дочернего. Если компонент всего один, то с помощью $parent обращаемся к свойствам main.js.
$root — обращение к свойствам main.js.
Vue.component('mycomp', { template: ` <div> <p>Привет, {{ $parent.name }}. Ваш возраст {{ $parent.age2 }}</p> </div> ` })
Обращаемся из вложеноого компонента к main.
Vue.component('mycomp', { template: ` <div> <p>Привет, {{ $parent.name }}. Ваш возраст {{ $parent.age }}</p> <iner-comp></iner-comp> </div> ` }) Vue.component('iner-comp', { template: ` <div> <p>Привет, {{ $parent.$parent.name2 }}. Ваш возраст {{ $parent.$parent.age2 }}</p> </div> ` })
или так
Vue.component('mycomp', { template: ` <div> <p>Привет, {{ $root.name }}. Ваш возраст {{ $root.age }}</p> <iner-comp></iner-comp> </div> ` }) Vue.component('iner-comp', { template: ` <div> <p>Привет, {{ $root.name2 }}. Ваш возраст {{ $root.age2 }}</p> </div> ` })
Если указать во вложенном компоненте $parent.name, то обратимся к локальной переменой name главного компонента, если она есть.
$refs
Можно обращатся к методом из другого компанента через ref атрибут. Допустим у нас есть index.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> <alert></alert> <cart ref="cart" ></cart> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="alert.js"></script> <script src="cart.js"></script> <script src="main.js"></script> </body> </html>
Указываем в нем наши компонент, обратите внимание на компанент cart, у него появился тег ref. Создаем сам компонент cart:
Vue.component('cart', { data() { return { counter: 0 } }, template: ` <div> <span>{{ counter }}</span> </div> `, methods: { increase() { this.counter++; } } })
Создаем компонент alert:
Vue.component('alert', { template: ` <div> <button @click="$root.$refs.cart.increase()"> GO </button> </div> ` })
Ну и main:
const app = new Vue({ el: '#app' })
Мы обратились из компанента alert к компаненту cart посреством $root.$refs.cart.increase().