Vue.js и как его понять

В своей работе, мне относительно недавно пришлось столкнуться с фреймворком Vue.js, т.к. до этого, я занимался в основном backend разработкой, пришлось со многим разбираться и многое было сложновато понять, особенно, когда раньше использовал только jQuery. В рамках данной статьи, я хочу помочь своему читателю разобраться с теми проблемами в понимании, с которыми столкнулся я. Конечно проблемы на этапе изучения чего-то нового у всех возникают разные, но и не мало тех, у кого они будут похожи, именно на это и будет направлена данная статья.

Я не буду проводить сравнение данного фреймворка с другими, думаю, что по этому поводу в интернете информации хватает, попытаемся разобраться именно с Vue.js и с “чем его едят?!”. В данном контексте будут рассматриваться примеры для сборки с помощью webpack или подобным системам. Примеры компонентного взаимодействия будут на примере однофайловых компонентов, поскольку они немного проще в понимании. Однако, принципы взаимодействия однофайловых и многофайловых компонентов ничем особо не отличаются.

Рассматриваемые аспекты


  • Разберемся в областях видимости переменных внутри одного и нескольких компонентов.
  • Рассмотрим возможности передачи переменных между компонентами.
  • Разберемся с общим взаимодействием компонентов друг с другом.

Итак, первое с чем приходится столкнуться новичкам и испытать определенные сложности — это не jQuery, и работает он иначе. Vue предоставляет реактивные связки своих переменных внутри компонентов и при взаимодействии с другими компонентами, что открывает существенно новые возможности. Да на jQuery это все можно организовать тоже, но более “толстым” кодом и кучей обработчиков, в которых можно запутаться. Если разобраться с Vue, на нем все это делается гораздо проще.

Сразу дам небольшой совет: “Не нужно пытаться провести аналогии написанного с jQuery!”, чем больше будет попыток провести аналогию, тем больше будет путаницы и непонимания.

Области видимости переменных


В официальной документации, конечно есть вся необходимая информация, но с ней сложновато разобраться, пока не попробуешь и не разберешься сам. Я попробую облегчить этот процесс.

В любом компоненте Vue имеется набор данных называемых “props”. Это объект содержащий в себе те данные, которые могут быть определены при вызове компонента или иметь значение по умолчанию.

Пример объявления свойств компонента:

/**------**/
props: {
   uuid: {
       type: String,
       default: '',
   },
},
/**------**/

В данном примере, мы указываем, что в нашем компоненте есть некий uuid, который является строкой и по умолчанию он является пустой строкой.

Кроме этого, в компоненте содержится объект data{}, который выполняет взаимодействие нашего компонента, с какими-либо другими, которые мы можем использовать в своем. В Vue является нормальной практикой, когда один компонент, может в себе совмещать несколько других, для их объединения. data, часто объявляется как функция, такую практику вы встретите наиболее часто на форумах и сообществах, обсуждающих реализацию на Vue

/**------**/
data() {
   return {
       dialog: false,
       indeterminate: false,
       loading: false,
       notifications: false,
       sound: true,
       widgets: false,
   }
},
/**------**/

Как видите, объект data не задает типы переменных, а сразу присваиваются значения. В своем приложении, мы можем менять это значение по определенным событиям, а в свою очередь другие компоненты вызванные в нашем, будут отслеживать изменение этих переменных и определенным образом реагировать на них. Это и будет реактивная связка компонентов с определенными переменными.

Кроме этого, в общем объекте компонента задаются методы (функции), для работы с этими переменными и событиями внутри компонента. В зависимости от того, где они вызываются, они должны располагаться в определенных объектах. Более подробно, про них, вы можете ознакомиться в официальной документации, там вопросов вроде бы не возникает. Мы же говорим об области видимости. Поэтому рассмотрим пример:

<template>
   <div id="inspire">
      <v-dialog v-model="alert" max-width="290">
         <v-toolbar
            color="primary"
            >
            <v-toolbar-title>Внимание</v-toolbar-title>
            <v-spacer></v-spacer>
            <div class="dialog-close-button" @click="alert=false">
               <i class="fas fa-times"></i>
            </div>
         </v-toolbar>
         <v-card>
            <v-card-text>{{ alertMessage }}</v-card-text>
         </v-card>
      </v-dialog>
   </div>
</template>

В данном примере, мы в своем компоненте создаем шаблон, в котором вызываем компонент Vuetify dialog

Для работы с ним, на понадобится модель alert, которая будет указывать на то открыто ли это окно сейчас или закрыто (соответственно true или false), а так же переменная alertMessage — которая будет в себе нести сообщение об ошибке или предупреждении. Каждому свойству, например color или max-width мы можем задать переменные, которые должны находиться в объекте data(){}, и с помощью своих методов изменять их. Но для простоты ограничимся двумя. Итак для управления этими свойствами, мы должны правильно распределить объекты внутри скрипта компонента.

<script>
    export default {
        data() {
            return {

                /**------------**/
                alert: false,
                alertMessage: 'У вас нет прав на это действие',
            }
        },
        methods: {
            deleteObject() {

                axios.delete(‘http: //example.com/’)
                        .then(response => {

                          /** ------- **/

                        })
                        .catch(error => {
                            this.alert = true;
                            this.alertMessage = “Что - то пошло не так”;
                        });

                    },

            },
            /**----------**/
</script>

На данном примере видно, что у нас есть некий метод deleteObject(), заданный в объекте methods, который делает запрос на удаление чего-то на сайте example.com, каким то образом обрабатывает ответ, а в случае провала выбрасывает исключение, в котором, уже мы вызываем наш компонент диалог, присваивая переменной alert значение true и присваиваем сообщение, которое будет выведено в шаблоне. Теперь обратите внимание, что в шаблоне, мы обращаемся к переменным в дате напрямую, просто указывая их название, а в методах, через объект this. Все методы, где бы они не были заданы, если они работают с data, они используют эти переменные через this. Если один метод, должен вызывать какой-то другой, определенный в объекте methods, он тоже вызывается через this.methodName().

Также обратите внимание на обработчик события клика в шаблоне:

<div class="dialog-close-button" @click="alert=false"><!--/**------**/ !--></div>

Здесь можно без метода изменить значение переменной alert в data, и поскольку она реактивно связана с моделью — компонент сразу отреагирует на ее изменение.

В данном случае, тем кто привык работать с классическими объектами можно запутаться, потому что связь выглядит немного нелогичной. Но на самом деле, никакой магии здесь нет. Когда мы вызываем экземпляр класса Vue и подключаем туда компоненты, он их интерпретирует через собственные объекты внутри js-фреймворка, именно поэтому у него образуется некое подобие собственной области видимости.

Передача данных между компонентами


Часто из нашего компонента, мы должны управлять состоянием других компонентов, вызванных внутри нашего. Как я уже писал выше, для этого существует объект `props`, а передача осуществляется путем присвоения этого значения, либо с помощью нашей переменной в data либо сразу присвоением значения этому свойству.

В нашем же примере, который я использовал выше уже это есть, для удобства, я продублирую его снова, и постараюсь объяснить:

<template>
   <div id="inspire">
      <v-dialog v-model="alert" max-width="290">
         <v-toolbar
            color="primary"
            >
            <v-toolbar-title>Внимание</v-toolbar-title>
            <v-spacer></v-spacer>
            <div class="dialog-close-button" @click="alert=false">
               <i class="fas fa-times"></i>
            </div>
         </v-toolbar>
         <v-card>
            <v-card-text>{{ alertMessage }}</v-card-text>
         </v-card>
      </v-dialog>
   </div>
</template>

Возьмем для примера, встроенный в наш шаблон компонент

<v-toolbar
           color="primary"
   >, <!-- /**------**/ !-->

В котором объявлено свойство color. Именно это свойство должно быть задано внутри скриптов компонента <v-toolbar>. В данном примере, мы присвоили ему определенное значение. Но мы его можем менять. Если нам требуется его динамически изменять, мы можем забиндить слежение этого свойства за нашей переменной, тогда в шаблон немного изменится:

 <v-toolbar
           :color="toolbarColor"
   >,<!-- /**------**/ !-->

В объекте data, мы должны объявить эту переменную, тогда мы сможем ее изменять методами нашего компонента, указанными в объекте methods:

<script>
    export default {
        data() {
            return {
                /*------*/
                toolbarColor: ’primary’,
            }
        },
        /** --- **/
</script>

Теперь мы можем объявить метод, и изменять переменную toolbarColor внутри него, используя конструкцию this.toolbarColor = “Значение”, и компонент <v-toolbar> будет на нее реагировать.

Таким образом, мы можем передавать значения в дочерние компоненты.

Для обратной связи, т.е. из дочернего компонента получить данные в родительский используются другие, чуть более сложные конструкции. В Vue есть встроенные методы, для этого, они хорошо описаны в официальной документации Vue, по ссылке,
поэтому я не буду подробно останавливаться на них. Проблема в том, что это не всегда удобный способ, и когда вы его подробно изучите, то сами убедитесь в этом. Он, так сказать, применим не во всех случаях.

Есть еще один хороший способ, использование библиотеки Vuex, которая создает некое хранилище для общих переменных, для управления состоянием приложения. На ней я тоже не буду подробно останавливаться, потому что, если вы поймете логику взаимодействия переменных внутри методов компонента и других компонентов, разобраться с Vuex, не должно составить труда. Кроме того, у них есть хорошая русскоязычная документация.

Для работы с Vuex, я прошу обратить особое внимание на то, как она правильно устанавливается, и что для доступа к данным, вам как минимум нужно использовать Мутации и Геттеры. Про них советую прочитать наиболее подробно. Я сначала пытался бегло понять суть и приступить к программированию, но столкнулся с множеством непонятных мне, на тот момент, проблем. Поэтому этим разделам уделите особое внимание.

Я обращу ваше внимание на саму систему взаимодействия. Она немного отличается от стандартного взаимодействия внутри Vue. Это как раз то, что я сначала упустил, а потом потратил много времени, чтобы разобраться. Возьму пример из официальной документации:

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  }
})

Здесь, мы объявляем сам store и getters методы для него. Обратите внимание, что метод внутри getters задан не совсем стандартно, но еще более нестандартно его использование в своем компоненте. В нашем компоненте, если мы хотим использовать переменную из store, мы должны вызвать ее с помощью новых переменных, и метод будем вызывать не как метод, а как свойство объекта store

this.$store.getters.doneTodos; 

И никаких скобок, поскольку это метод, который вернет готовый объект, он и вызывается как просто свойство объекта getters внутри $store.

С мутациями немножкуо проще, там сразу написано, что нужно использовать comit('methodName', ПЕРЕДАВАЕМЫЕ_В_МЕТОД_ПЕРЕМЕННЫЕ).

Более подробно про мутации здесь.

Заключение


Мы познакомились с областью видимости переменных внутри компонентов, узнали способы обмена данными между компонентами, отсюда уже должно сложиться общее понимание о взаимодействии компонентов друг с другом в Vue.js. От себя скажу, что система достаточно гибкая, и уже существует множество готовых компонентов и библиотек, расширяющих возможность Vue. Каждый желающий может присоединиться к развитию этой системы и облегчать жизнь другим разработчикам. Компонентная система позволяет легче обслуживать код, соединять готовые компоненты внутри других, и не дублировать код, что приближает нас к способом “красивой” разработки. Новичкам желаю терпения и успеха, в познании новых для себя областей.

P.S.


Ниже я добавил ссылки, с которых я использовал материалы для написания статей и примеров. Для библиотеки Vuetify я напишу две ссылки, на англоязычную и на русскоязычную документацию, поскольку русскоязычная на момент написания статьи переведена не полностью, и в ней может чего-то не быть. Но в англоязычной, вы сможете найти все что нужно знать об этой библиотеке. По работе с данной библиотекой, могу написать более подробно, если будут вопросы по ней или что-то станетне понятно.

Ссылки:


Русскоязычная документация по фреймворку Vue.js
Русскоязычная документация по библиотеке Vuex
Англоязычная документация по Vuetify
Русскоязычная документация по Vuetify

Similar posts

Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 15

    +7
    Всякий бэкендщик, который не понял «этот ваш гавеный джаваскрипт», лезет первее всех поучать хомячков, что хорошо во фронтенде, а что плохо. Особенно здоровски получается это у тех, кто когда-то кое-как вінужденно разобрался с jQuery и на этом, якобы, познал дзен джаваскрипт.
    Что же полезного нам довели до внимания?
    О, с официальной документацией, оказывается, «сложно разобраться»… Серьезно???? Чувак, ты видел документацию по Ангуляр5 ???.. вот где ад, а дока по Вью, — удивительно легка в сравнении с Ангуляром и Реактом, а тем более — очень большой объем русскоязычного перевода.
    Отдельная песня — фразы в стиле КО. Вот эта вот, к примеру: «В зависимости от того, где они вызываются, они должны располагаться в определенных объектах.» Спасибо, Кэп.
    Далее идет пример про обращение к внешнему ресурсу и упоминается экземпляр ошибки. Попробуйте прочитать этот текст от конца к началу, — уверяю, смысл не изменитсЯ, ибо это бредятина, вызванная какими-то веществами, которыми автор вряд-ли заделится, ибо в школу пора.
    Ага, автор поднял веки и дошел до передачи данных между компонентами. Но увы, его вялых сил хватило только на рерайт абзаца из документации о передачи данных в компонент через пропсы, а вот осветить самое интересное — возврат данных в родителя через ивенты, — автор не захотел. Достаточно просто написать «В Vue есть встроенные методы, для этого, они хорошо описаны в официальной документации», и хоба! — давайте писать статью дальше.
    О да, автор нашел в гугле, что в экосистеме Вью есть менеджер стейтов, и даже автор не поленился написать его название — Vuex. Честь и хвала автору.
    =======================
    Заключение. Систематически, в дни школьных каникул, на Хабре появляются разные новые статьи. Они хорошие и разные. К сожалению, разных в последнее время значительно больше, чем хороших. Остатся надежда, что когда-то это соотношение поменяется.
      0

      Это ни в коем случае не отменяет того, что жаваскрипт говеный

        +1
        И без него не работает ни один сайт (ну разве что какие-то говенные)
          –1
          только контент делает сайт хорошим или говеным, а не свистелки-перделки, сделанные криво на js, с десятками тонн кода и сотнями зависимостей
        0
        deivan скиньте пожалуйста ссылочку на свои статью про Vue.js, хочется посмотреть работу мастера.

        dastanaron_dev Спасибо за статью ))
          0
          Полностью согласен. Статья ни о чем. Чуть vue, чуть Vuex, мимоходом AJAX, а толку никакого. Пример с Аxios: если уж пользуете vuex, то работайте с AJAX в actions. А офф. дока по вью очень хорошая.
            +2
            Чувак, ты вроде бы понял, но как то не полностью. Да, я действительно backend — разработчик, которому время от времени приходится разбираться с фронтендом. И эта статья не призыв к действию или методика разработки. Я лишь пишу, с чем было сложно разобраться, мне как бекендщику, ибо таких как я довольно много. Если ты без проблем все понял, и прочитав две страницы официальной доки, флаг тебе и респект, но извини, фронт требует немного другого подхода и склада мысли, нежели бэк. Не для тебя просто эта статья, а унижать собрата своего по коду — это как минимум не вежливо. Не нравится статья, хорошо! Критика это всегда хорошо. Но вот про школьные каникулы и прочую лабуду — это пожалуй сильно лишнее. Да в ней нет много чего, про взаимодействие компонентов, но это и не тема данной статьи. Все в одну не упихаешь. У меня не было сложности разобраться с обратным обменом, от дочернего компонента, к родительскому, поэтому об этом я не писал, там сложного ничего нет, когда понимается сама суть работы либры, остальное не сложно понимается! За критику спасибо, но вот с излишествами не стоит!
              0
              ок, за школоту — приношу извинения, был взволнован.
            –1
            Значение всех этих Ангуляров сильно переоценено. Все что мне нужно я успешно пишу на jQuery и знаю кучу отличных проектов, работающих на чистой ваниле. С нетерпением жду, когда большие корпоративные заказчики найдут себе новый фетишь, а Реакт с Ангуляром будут просто экологично развиваться.
            Vue хотя бы попытку сдела вылезти из дебрей сверхусложнений простых вещей.
              0
              Мне вот тоже сложно представить, как я буду каждый раз переписывать свою CMS (с самописными редактором текста и файловым менеджером) под очередной модный фреймворк.
                0
                А зачем переписывать то, что работает на новый фреймворк? Новый фреймворк, для новых проектов!
                  0
                  Прямо уроки лукавства в малых дозах… Зачем современные фреймворки переписывают? Получается, нас все это время обманывали и они не работали?
                  Сорри, хотел ответить на предыдущий коммент.
              0
              del
                0
                Документация по Vue очень доступно написана, так что разобраться в самом фреймворке может любой за пару вечеров. Вероятно, «чистому» backend-разработчику будет сложно, потому как элементы привычного MVC несколько размазаны.
                Другой вопрос, что низкий порог вхождения может повредить самому фреймворку, поскольку из-за простоты на него начнут переходить с jquery «горе-кодеры». Я уже видел пару раз применение Vue в стиле jQuery.
                  0
                  При использовании компонетной системы Vue и сборки с помощью «Сборщиков» (например webpack), как на jquery работать не получится. Но в целом, вы правы. Если подключить его как облачное, и выводить переменные в глобальную область видимости, для переброса между компонентами, так и будет как в jQuery. Даже парочка примеров есть, которые я встречал на некоторых сайтов

                Only users with full accounts can post comments. Log in, please.