Pull to refresh

4 совета по работе с Vue.js

Reading time 4 min
Views 49K
Original author: Jesus Galvan

Вот несколько советов по работе с Vue.js которые я выработал за последний год.


Используйте стрелочные функции в компонентах


ES6 подарил нам новый способ объявления функций с удобным биндингом текущей области видимости. При использовании старого способа, this может ссылаться не на то что вы ожидаете.


Например:


function Person () {
    this.age = 0;    
    setInterval(function growUp () {
          // `this.age` здесь равен undefined
        // эта функция создает новую область видимости
        // отличную от области видимости функции Person
        console.log(this.age);
    }, 1000)
}

const Developer = new Person();

Функция growUp определила свою область видимости и this внутри нее не ссылается на объект Person. Добиться желаемого поведения, можно сохранив область видимости в переменной, или используя функцию .bind(context)


// Сохраняем контекст в переменной that
function Person () {
    var that = this;
    that.age = 0;
    setInterval(function growUp () {
        console.log(that.age);
    }, 1000)
}

// или используем функцию bind
function Person () {
    this.age = 0;
    setInterval(function growUp () {
        console.log(this.age);
    }.bind(this), 1000)
}

Но самым удобным вариантом будет простое использование стрелочной функции. Она автоматически привязывает область видимости функции к родительской области видимости


function Person () {
    this.age = 0;
    setInterval(() => {
        console.log(this.age);
    }, 1000)
}

Так лучше, не правда ли?


Используйте однофайловые компоненты


Однофайловые компоненты (.vue) — одна из моих любимых фич в Vue.js
Они позволяют нам определять многократно используемые шаблоны и отдельные части нашего приложения и переиспользовать их. Но для их использования понадобятся соответствующие инструменты сборки.


(прим. пер. всё это уже настроено и готово к работе в консольной утилите Vue-cli).


Есть два способа создания Vue компонентов.
Например:


Vue.component('my-counter', {
    data () {
        return {
            count: 0
        }
    },
    methods: {
        add () {
            this.count += 1;
        }
    },
    template: `<div>
        <div>{{ count }}</div>
        <button @click="add()">Increment</button>
    </div>`
    }
});

Теперь тоже самое, но используя .vue файл


<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>

На небольшом компоненте преимущества не так очевидны, но при установке соответствующих расширений в ваш редактор — вы получите отличную подсветку синтаксиса, а так же вам станет легче найти нужный кусок компонента (сверху вниз идут шаблон, js, стили).


Глобальные плагины


При разработке больших приложений вам вы повсюду будете использовать функциональность одних компонентов внутри других и что бы каждый раз не импортировать .vue компонент внутрь каждого, где нужен его функционал — лучше один раз написать его и использовать как глобальный плагин.


Мы можем сделать один компонент со всей нужной нам функциональностью:


<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>

Или мы можем создать плагин и использовать его:


import UserContainer from './UserContainer'

const Plugin = {
    install (Vue, options) {
        // <g-user-container> будет доступен глобально во всем приложении
        Vue.component('GUserContainer', UserContainer)

        Vue.mixin({
            computed: {
                // `users` так же будет доступен везде
                users () {
                    return this.$store.getters.users
                },
            }
        })

        // $sayHello is available within components
        Vue.prototype.$sayHello = function (name) {
            return `Hello ${name}!`
        }
    }
}

// И используем наш плагин
import Vue from 'vue'
Vue.use(Plugin)

new Vue({
    //...
})

Используйте этот подход, когда видите, что повторяете одинаковый функционал внутри своих компонентов. Don't repeat yourself


Используйте Vuex для хранения состояния


Современные веб-приложения используют большое количество данных на клиенте и управляют ими. Я видел как люди просто хранят все данные внутри компонентов. Это нормальный подход в случае, когда вам не нужен доступ к данным одного компонента из другого.


Очень заманчиво использовать props для передачи данных в компоненты, или использовать библиотеки для подписки на события (Pub—Sub), что бы управлять данными в приложении, но со временем это приводит к раздуванию кода, и становится сложно поддерживать ваше приложение.


Vuex пригодится, когда вашим компонентам понадобиться доступ к одному и тому же состоянию. Вместо того что бы превращать ваш код в ад, прикидывая все данные через props, Vuex позволит хранить в себе всё состояние приложения, и предоставлять к нему доступ нужным компонентам.


С помощью Vuex мы можем определить state (данные), геттеры, экшены и мутации, которые позволят нам манипулировать данными как нам необходимо.


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 внутри компонента:


<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 в своём новом проекте

Tags:
Hubs:
+11
Comments 9
Comments Comments 9

Articles