От автора: вот несколько приемов, которые я узнал при работе за последний год. Для многих разработчиков Vue js примеры, приведенные мной, будут полезны.
1. Используйте функции стрелок внутри компонентов
ES6 представил новый способ определения функций. Хотя он короче и быстрее вводится, его функционал зависит от того, как он определяет область действия. При использовании старого способа определения функции this диапазон мог не работать так, как мы намеревались. Например:
1 2 3 4 5 6 7 8 9 |
function Person () { this.age = 0; setInterval(function growUp () { // `this.age` is undefined // this function has declared its own scope // different from the Person scope this.age += 1; }, 1000) } |
Функция growUp определяет собственный диапазон, поэтому она не ссылается на объект Person. Вы можете получить желаемое поведение, сохранив экземпляр объекта в переменной или связав область действия с родительским контейнером.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// store the `this` scope in // a variable to reuse function Person () { var that = this; that.age = 0; setInterval(function growUp () { that.age += 1; }, 1000) } // bind the function's `this` function Person () { this.age = 0; setInterval(function growUp () { this.age += 1; }.bind(this), 1000) } |
Или вместо этого мы могли бы просто использовать функцию стрелки. Поскольку она автоматически связывает свой диапазон с родительским, нет необходимости в дополнительных «исправлениях».
1 2 3 4 5 6 |
function Person () { this.age = 0; setInterval(() => { this.age += 1; }, 1000) } |
Более лаконично, правда!?
2. Используйте компоненты Single File
Компоненты Single File — одна из моих любимых функций Vue.js. Она позволяет нам определять повторно используемые шаблоны и отдельные части нашего приложения. Для использования компонентов Single File необходимы инструменты сборки. Существует несколько способов определения компонентов Vue. Например:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Vue.component('my-counter', { data () { return { count: 0 } }, methods: { add () { this.count += 1; } }, template: `<div> <div>{{ count }}</div> <button @click="add()">Increment</button> </div>` } }); |
Теперь тот же компонент, в качестве компонента Single File:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<template lang="html"> <div> <div>{{ count }}</div> <button @click="add()">Increment</button> </div> </template> <script> export default { data () { return { count: 0 } }, methods: { add () { this.count += 1; } } } </script> |
Для небольших компонентов преимущества могут быть не столь очевидными, но с самого начала мы получаем подсветку синтаксиса для структуры шаблона, и нам легче будет визуально сканировать и находить то, что мы ищем.
3. Глобальные плагины
В более крупных приложениях мы, вероятно, повторно используем те же самые методы, вычисленные свойства или даже компоненты. Вместо того, чтобы переписывать методы и импортировать компоненты Single File внутри каждого компонента, мы можем определить их один раз и установить в качестве глобального плагина. Мы могли бы определить все компоненты и помощники в одном компоненте:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<template lang="html"> <div> <user-container v-for="u in users"> <p>{{ sayHello(u.name) }}</p> </user-container> </div> </template> <script> import UserContainer from './UserContainer' export default { components: { UserContainer, }, methods: { sayHello (name) { return `Hello ${name}!` } }, computed: { users () { return this.$store.getters['users']() } } } </script> |
Или мы могли бы создать плагин и установить его:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
import UserContainer from './UserContainer' const Plugin = { install (Vue, options) { // <g-user-container> component will be globally available Vue.component('GUserContainer', UserContainer) Vue.mixin({ computed: { // `users` will be available globally users () { return this.$store.getters.users }, } }) // $sayHello is available within components Vue.prototype.$sayHello = function (name) { return `Hello ${name}!` } } } // as easy as import Vue from 'vue' Vue.use(Plugin) new Vue({ //... }) |
Определенно хороший вариант, когда мы видим, что копируем и вставляем несколько раз. Не забудьте придерживаться DRY
4. Используйте Vuex для управления состояниями
Современные веб-приложения управляют и обновляют большие наборы данных. Подход, который я вижу довольно часто, заключается в хранении и управлении всеми данными внутри компонента. В этом подходе нет ничего плохого, когда совместное использование данных между компонентами не требуется.
Заманчиво передавать данные в качестве prop для компонентов и использовать сообщения Event Bus для обработки обновлений, но при таком подходе код быстро становится раздутым и трудно поддерживаемым.
Vuex подходит для сценариев, когда нам нужно использовать несколько компонентов, которые все хотят использовать одно и то же состояние. Вместо того, чтобы передавать все данные через prop дочерних компонентов, Vuex может хранить все состояния и предоставлять доступ к ним для всех компонентов.
С помощью Vuex мы можем определить состояния (данные), геттеры, действия и мутации, которые могут позволить нам делать что угодно.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { movies: [], actors: [] }, getters: { movies: state => { return state.movies }, actors: state => { return state.actors } }, actions: { getMovies (context) { axios.get('/api/movies') .then((movies) => { context.commit('setMovies', movies) }) }, getActors (context) { axios.get('/api/actors') .then((actors) => { context.commit('setActors', actors) }) } }, mutations: { setMovies (state, movies) { state.movies = movies }, setActors (state, actors) { state.actors = actors } } }) new Vue({ el: '#app', store, render: h => h(App) }) |
Используйте Vuex в компоненте:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<template lang="html"> <div> <div v-for="m in movies"> <p>{{ m.name }}</p> <p>{{ m.description }}</p> </div> <div v-for="a in actors"> <p>{{ a.firstName }} {{ a.lastName }}</p> </div> </div> </template> <script> export default { mounted () { this.$store.dispatch('getMovies') this.$store.dispatch('getActors') }, computed: { movies () { this.$store.getters.movies }, actors () { this.$store.getters.actors } } } </script> |
Мы также можем определить дополнительные действия и мутации для продолжения обновления данных. Кроме того, он поддерживает реактивность, которая является отличительной особенностью Vue.js.
Заключение
С Vue.js может быть очень интересно работать с учетом того, что у вас есть некоторые знания, лучшие практики и полезные инструменты. Хотя в настоящее время мне нравится работать с Vue.js, это не всегда было так.
Автор: Jesus Galvan
Источник: //itnext.io/
Редакция: Команда webformyself.