Vue.js – это популярная среда JavaScript для создания пользовательских интерфейсов, которая в последние годы приобрела большую популярность. Одной из его новейших функций является Composition API, который позволяет разработчикам писать логику своих компонентов более гибко и выразительно. В этой статье мы рассмотрим некоторые функции Composition API, которые делают Vue.js мощной платформой для создания веб-приложений, а также приведем примеры кода, помогающие проиллюстрировать каждый пункт.

  1. Реактивное состояние. Composition API позволяет создавать реактивное состояние для вашего компонента с помощью функции reactive. Эта функция принимает объект и возвращает реактивную версию этого объекта, что позволяет легко отслеживать изменения и реагировать на них. В следующем примере состояние компонента становится реактивным, а затем используется для отображения сообщения.
<template>
 <div>
   <p>{{ message }}</p>
 </div>
</template>
<script>
import { reactive } from 'vue'
export default {
 setup() {
   const state = reactive({
   message: 'Hello Vue.js!'
   })
   return {
     …state
   }
 }
}
</script>

2. Ссылки: Composition API позволяет создавать ссылки с помощью функции `ref`, которая позволяет получить прямой доступ к значению и отслеживать его изменения. В следующем примере создается ссылка для отслеживания значения элемента ввода:

<template>
  <div>
    <input v-model="inputValue" ref="input" />
    <p>{{ inputValue }}</p>
  </div>
</template>
<script>
import { ref } from 'vue'export default {
  setup() {
    const inputValue = ref('')
    onMounted(() => {
      console.log(`Input value: ${inputValue.value}`)
    })
    return {
      inputValue
    }
  }
}
</script>

3. Вычисляемые: Composition API также позволяет создавать вычисляемые свойства с помощью функции computed. Эта функция принимает функцию, определяющую вычисляемое свойство, и возвращает объект, который отслеживает реактивные зависимости и автоматически обновляется. В следующем примере определяется вычисляемое свойство, возвращающее обратное состояние сообщения.

<template>
  <div>
    <p>{{ message }}</p>
    <p>{{ reversedMessage }}</p>
  </div>
</template>

<script>
import { reactive, computed } from 'vue'

export default {
  setup() {
    const state = reactive({
      message: 'Hello Vue.js!'
    })
    const reversedMessage = computed(() => state.message.split('').reverse().join(''))
    return {
      ...state,
      reversedMessage
    }
  }
}
</script>

4. Методы: Composition API позволяет создавать методы для вашего компонента с помощью функции настройки. Методы позволяют вам определять поведение вашего компонента и могут использоваться для обновления состояния или выполнения других операций. В следующем примере определен метод для обновления состояния сообщения новым значением.

<template>
  <div>
    <p>{{ message }}</p>
    <button @click="updateMessage">Update Message</button>
  </div>
</template>
<script>
import { ref } from 'vue'

export default {
  setup() {
    const message = ref('Hello Vue.js!')
    const updateMessage = ()=> {
      message.value = 'New message'
    }
    return {
      message,
      updateMessage
    }
  }
}
</script>

5. Наблюдатели: Composition API также позволяет создавать наблюдатели для реактивных свойств с помощью функции watch. Наблюдатели позволяют вам выполнять действие всякий раз, когда изменяется реактивное свойство. В следующем примере определен наблюдатель, который регистрирует новое значение состояния сообщения каждый раз, когда оно изменяется.

<template>
  <div>
    <p>count : {{ state.counter }}</p>
    <button @click="increaseCounter">+</button>
  </div>
</template>
<script>
import { reactive, watch } from 'vue'
export default {
  setup() {
    const state = reactive({
      counter: 1
    })
    const increaseCounter = () => {
      return state.counter++
    }
    watch(() => state.counter, (newValue) => {
      console.log(newValue)
    })
    return {
      state,
      increaseCounter
    }
  }
}
</script>

6. Крючки жизненного цикла. Composition API позволяет использовать хуки жизненного цикла, такие как например `onMounted`, `onUpdated` и `onUnmounted`, для запуска логики в определенные моменты жизненного цикла компонента.

<template>
  <div>
    <p>{{counter}}</p>
    <button @click="counter++">+</button>
  </div>
</template>
<script>
import { ref , onBeforeMount ,onMounted , onBeforeUpdate , onUpdated ,
 onBeforeUnmount, onUnmounted } from 'vue'

export default {
  setup() {
    const counter = ref(0)
    onBeforeMount(() => {
      console.log('Component will mount run first')
    }),
    onMounted(() => {
      console.log('Component mounted run second')
    }),
    onBeforeUpdate(() => {
      console.log('Component will update run third when before counter change')
    }),
    onUpdated(() => {
      console.log('Component updated run fourth when after counter change ')
    }),
    onBeforeUnmount(() => {
      console.log('Component will unmount run fifth when before component unmounted')
    })
    onUnmounted(() => {
      console.log('Component unmounted run sixth when after component unmounted')
    })
    return { counter }
  }
}
</script>

7. Контекст: Composition API позволяет вам получить доступ к контексту компонента, который содержит такие свойства, как «props», «emit» и «slots». В следующем примере доступ к props компонента осуществляется для отображения сообщения:

<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>
<script>
import { toRefs } from 'vue'

export default {
  props: {
    message: {
      type: String,
      default: 'Hello World',
      required: true
    }
  },
  setup(props) {
    return {
      ...toRefs(props)
    }
  }
}
</script>

8. Эффекты: Composition API позволяет создавать эффекты с помощью функции `effect`, которая используется для создания эффекта, который наблюдает и реагирует на изменения в состоянии компонента или реквизитах. В качестве первого аргумента он принимает функцию обратного вызова, которая вызывается всякий раз, когда изменяются наблюдаемые значения. Функция обратного вызова может выполнять любой побочный эффект, например делать сетевой запрос или обновлять DOM.

<template>
  <div>
    <p>{{ JSON.stringify(data) }}</p>
    <button @click="idData++">+</button>
  </div>
</template>
<script>
import { defineComponent,ref, effect } from 'vue'

export default defineComponent({
  setup() {
    const data = ref(null)
    const idData = ref(1)
    effect(() => {
      async function fetchData() {
        const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${idData.value}`)
        const json = await response.json()
        data.value = json
      }
      fetchData()
    }, [idData.value])
    return {
      data,
      idData
    }
  }
})
</script>

В этом примере функция эффекта наблюдает за изменениями идентификатора компонента и отправляет сетевой запрос на получение данных при изменении идентификатора.

9. EffectScope: effectscope — это объект, который передается в функцию обратного вызова функции effect. Он содержит ряд свойств и методов, которые можно использовать для управления поведением эффекта, например stop и refresh.

<template>
  <div>
    <p>{{ JSON.stringify(data) }}</p>
  </div>
</template>
<script>
import { defineComponent,ref, effect,effectScope } from 'vue'

export default defineComponent({
  setup() {
    const data = ref(null)
    const updateCount = ref(1)
    const scope = effectScope()
    scope.run(() => {
      effect(() => {
        async function fetchData() {
          const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${updateCount.value}`)
          const json = await response.json()
          data.value = json
          console.log('effect', scope)
          updateCount.value += 1
          if (updateCount.value >= 3) {
            scope.stop()
          }
        }
        fetchData()
      }, [updateCount.value])
    })
    return {
      data,
    }
  }
})
</script>

В этом примере метод stop области effect используется для остановки эффекта после того, как он был вызван 3 раза.

10. watchEffect: стоит отметить, что функция watchEffect также является более упрощенной версией функции effect, где она используется только для наблюдения за реактивными переменными и не имеет параметров, которые предоставляет функция effect.

<template>
  <div>
    <p>{{ message }}</p>
    <input v-model="inputValue" />
  </div>
</template>

<script>
import { defineComponent, reactive, watchEffect,toRefs } from 'vue'

export default defineComponent({
  setup() {
    const state = reactive({
      inputValue: '',
      message: ''
    })

    watchEffect(() => {
      state.message = `Input value is: ${state.inputValue}`
    })

    return {
      ...toRefs(state)
    }
  }
})
</script>

В приведенном выше примере мы используем функцию watchEffect для наблюдения за изменениями в состоянии inputValue компонента и соответствующим образом обновляем состояние message компонента. Функция watchEffect принимает в качестве аргумента функцию обратного вызова, которая вызывается всякий раз, когда реактивные значения считываются внутри функция обратного вызова изменена.

11. Провайдеры: Composition API позволяет создавать провайдеров с помощью функций `provide` и `inject`, что позволяет вам обмениваться состоянием и методами между компонентами. В следующем примере поставщик определяется в родительском компоненте и внедряется в дочерний компонент:

<template>
  <div>
    <parent-component>
      <child-component />
    </parent-component>
  </div>
</template>
<script>
import { provide, inject } from 'vue'
// Parent component
const userName = 'John'
const userAge = 25
export const ParentComponent = {
  setup() {
    provide('user', { name: userName, age: userAge })
    return {}
  }
}
// Child component
export const ChildComponent = {
  setup() {
    const user = inject('user')
    return {
      user
    }
  }
}
export default {
  components: {
    ParentComponent,
    ChildComponent
  }
}
</script>

12. Порталы (или «Телепорт») : Composition API позволяет использовать компонент «Телепорт» для рендеринга компонента в определенный целевой элемент за пределами родительского дерева компонента. Это позволяет создавать модальные окна, диалоговые окна и другие компоненты, которые отображаются вне иерархии основных компонентов.

<template>
  <div>
    <button @click="openModal = true">Open Modal</button>
    <teleport to="#modal-container">
      <div v-if="openModal">
        <h1>Modal Title</h1>
        <p>Modal Content</p>
        <button @click="openModal = false">Close Modal</button>
      </div>
    </teleport>
  </div>
</template>

<script>
import { defineComponent, ref } from 'vue'

export default defineComponent({
  setup() {
    const openModal = ref(false)
    return {
      openModal
    }
  }
})
</script>

В приведенном выше примере мы используем компонент Teleport для рендеринга содержимого модального окна в определенное место в DOM, указанное реквизитом to. Содержимое модального окна видно только тогда, когда для переменной openModal установлено значение true. Нам нужен контейнер в HTML с идентификатором 'modal-container' для отображения модального окна.

13. Поддержка TypeScript: Vue.js имеет встроенную поддержку TypeScript при использовании API композиции. Вы можете использовать аннотации типов и интерфейсы TypeScript для определения структуры свойств, состояния и методов вашего компонента. Вот пример компонента Vue, написанного на TypeScript с использованием API композиции:

<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive, toRefs } from 'vue'
import { PropType } from 'vue'

interface Props {
  message: string
}

export default defineComponent({
  props: {
    message: {
      type: String as PropType<string>,
      required: true
    }
  },
  setup(props: Props) {
    const state = reactive({
      message: props.message
    })
    return {
      ...toRefs(state)
    }
  }
})
</script>

14. Рендеринг на стороне сервера: Vue.js также имеет встроенную поддержку рендеринга на стороне сервера (SSR) при использовании API композиции. Вы можете использовать функцию setup для определения логики вашего компонента и функцию render для создания средства визуализации, которое можно использовать на сервере.

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

<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>
<script>
import { defineComponent, reactive, toRefs } from 'vue'

export default defineComponent({
  props: {
    message: {
      type: String,
      default: 'Hello World',
      required: true
    }
  },
  setup(props) {
    const state = reactive({
      message: props.message
    })
    return {
      ...toRefs(state)
    }
  }
})
</script>
<style scoped>
p {
  color: red;
}
</style>

16. Маршрутизация: Vue.js также имеет встроенный маршрутизатор, который позволяет легко управлять навигацией на стороне клиента и создавать одностраничные приложения (SPA) при использовании API композиции. Вы можете использовать функцию useRouter для доступа к экземпляру маршрутизатора и объект route для доступа к свойствам текущего маршрута. Вот пример того, как использовать маршрутизатор в компоненте Vue с помощью API композиции:

<template>
  <div>
    <p>Current Route:</p>
    <ul>
      <li>Name: {{ name }}</li>
      <li>Full Path: {{ fullPath }}</li>
    </ul>
    <router-link :to="'/'">Go To Home</router-link>
  </div>
</template>
<script>
import { defineComponent } from 'vue'
import { useRouter } from 'vue-router'
export default defineComponent({
  setup() {
    const route  = useRouter()
    // get current route
    console.log(route.currentRoute.value)
    const { name, fullPath } = route.currentRoute.value
    return {
      route,
      name,
      fullPath
    }
  }
})
</script>

17. Оптимизация производительности: Vue.js имеет ряд функций оптимизации производительности, таких как отложенная загрузка, асинхронный рендеринг и асинхронные компоненты при использовании API композиции. Вы можете использовать функцию `lazy` для создания компонентов с ленивой загрузкой, хуки `onBeforeMount` и `onBeforeUpdate` для выполнения асинхронных операций и повышения производительности вашего приложения.

асинхронные компоненты. Асинхронные компоненты — это мощная функция Vue.js. Это способ загрузки компонентов только тогда, когда они необходимы, а не загрузки их всех сразу при первой загрузке приложения. Это может помочь повысить производительность больших и сложных приложений за счет сокращения времени начальной загрузки и объема используемой памяти. API композиции позволяет создавать асинхронные компоненты с помощью функции defineAsyncComponent. Эта функция принимает в качестве аргумента функцию обратного вызова, которая должна возвращать обещание, разрешающееся в определение компонента.

import { defineAsyncComponent } from 'vue'

const AsyncComponent = defineAsyncComponent(() =>
  import('./MyComponent.vue')
)

export default {
  setup() {
    return {
      AsyncComponent
    }
  },
  template: `
    <div>
      <async-component v-if="show" @loaded="onLoaded" @error="onError" />
    </div>
  `
}

В этом примере функция defineAsyncComponent используется для создания асинхронной версии компонента MyComponent.vue. Этот компонент загружается только тогда, когда для переменной show установлено значение true, а события loaded и error компонента можно использовать для обработки состояния загрузки компонента.

Вы также можете использовать функцию defineAsyncComponent для условной загрузки компонента на основе определенного условия, например, на основе роли пользователя:

import { defineAsyncComponent } from 'vue'

const AdminComponent = defineAsyncComponent(() => {
  if (isAdmin) {
    return import('./AdminComponent.vue')
  } else {
    return import('./RegularComponent.vue')
  }
})

18. Интернационализация: легко создатьлокализацию с помощью vue-i18n. Чтобы использовать библиотеку vue-i18n для реализации интернационализации в приложении Vue.js, сначала необходимо установить библиотеку, запустив npm install vue-i18n или yarn add vue-i18n. импортируйте createI18n в main.js для всего приложения.

// main.js
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
import App from './App.vue'
// ... 
const app = createApp(App)
const messages = {
  en: {
    message: {
      hello: 'hello world'
    }
  },
  fr: {
    message: {
      hello: 'bonjour le monde'
    }
  },
  ar: {
    message: {
      hello: 'مرحبا بالعالم'
    }
  }
}

const i18n = createI18n({
  locale: 'en', // set locale
  fallbackLocale: 'en', // set fallback locale
  messages, // set locale messages
})
app.use(i18n)
app.mount('#app')

затем используйте его в своем компоненте

<template>
  <div>
      <div class="locale-changer">
        <select v-model="$i18n.locale">
          <option v-for="locale in $i18n.availableLocales" :key="`locale-${locale}`" :value="locale">{{ locale }}</option>
        </select>
        From i18n : {{ $t('message.hello') }}
      </div>
  </div>

</template>
 
<script>
// Nothing here
</script>

В этом примере мы импортируем библиотеку vue-i18n и создаем I18n с объектом сообщений, который содержит переводы для разных языков. Мы устанавливаем локаль на «en» по умолчанию. Мы можем изменить язык, используя свойство i18n.locale.

19. Динамические компоненты: Vue.js позволяет динамически переключаться между компонентами с помощью привязки component при использовании API композиции. Вы можете использовать свойства is и component функции $createElement для создания динамического компонента. Вот пример того, как использовать динамические компоненты в компоненте Vue с помощью API композиции:

<template>
  <div>
    <component :is="currentComponent" />
    <button @click="switchComponent">Switch Component</button>
  </div>
</template>

<script>
import { defineComponent, reactive, onMounted } from 'vue'
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'

export default defineComponent({
  components: {
    ComponentA,
    ComponentB
  },
  setup() {
    const state = reactive({
      currentComponent: 'component-a'
    })

    function switchComponent() {
      state.currentComponent = state.currentComponent === 'component-a' ? 'component-b' : 'component-a'
    }

    return {
      ...toRefs(state),
      switchComponent
    }
  }
})
</script>

20. Emit :функция emit используется для отправки пользовательских событий из компонента в его родительский компонент. Это позволяет родительскому компоненту реагировать на события, происходящие в дочернем компоненте, и предпринимать соответствующие действия.

Composition API позволяет использовать функцию emit в компоненте Vue.js с помощью функции emit из библиотеки vue.

<template>
  <div>
    <h1>About</h1>
    <p>Count From Parent : {{counter}}</p>
    <emitTest @increment-count="getCounter" />
  </div>
</template>

<script>
 import emitTest from '@/components/emitTest.vue'
 import { ref } from 'vue'
  export default {
    name: 'AboutView',
    components: {
      emitTest
    },
    setup () {
      const counter = ref(0)
      const getCounter = (count) => {
        console.log(count)
        counter.value = count
      }
      return {
        getCounter,
        counter
      }
    }
  }
</script>

и в дочернем компоненте

<template>
<div>
    <button @click="increment">Increment</button>
    <p>count from child :{{ count }}</p>
</div>
</template>

<script>
import { ref } from 'vue'
export default {
  name: 'emitTest',
  emits: ['incrementCount'],
  setup(props, ctx) {
    const count = ref(0)
    const increment = () => {
      count.value++
      ctx.emit('incrementCount', count.value)
    }
    return {
      increment,
      count
    }
  }
}
</script>

В этом примере родительский компонент прослушивает событие increment, созданное дочерним компонентом, используя прослушиватель @increment-count.

21. Setup Sugar: <script setup> — это способ определить скрипт для компонента Vue.js с помощью Composition API, доступного в версии Vue 3.x. Это новый способ определения сценария компонентов Vue более декларативным образом, что делает его более читабельным и менее подробным.

22. Пользовательские директивы: Vue.js позволяет создавать пользовательские директивы для расширения функциональности DOM при использовании API композиции. Вы можете использовать функцию directive для создания пользовательской директивы и хуки bind и update для определения ее логики. Но мы будем использовать сахар установки для меньшего количества кода, это намного лучше.

Вот пример того, как создать пользовательскую директиву в компоненте Vue, используя сахар настройки API композиции:

<script setup>
  const vFocus = {
    mounted: (el) => el.focus()
  }
  const vColor = {
    mounted: (el) => el.style.color = 'red'
  }
</script>
<template>
  <p v-color> 
    Color red here from custom directive
  </p>
  <input v-focus />
</template>

23. Повторное использование через композицию (Composable):Vue.js позволяет создавать повторно используемые функции композиции, которые можно использовать в разных компонентах. Вот пример функции композиции, которую можно использовать для проверки формы:

// formValidation.js
import { ref, watch } from 'vue'

export function useFormValidation(initialValue) {
  const value = ref(initialValue)
  const error = ref('')

  watch(value, (newValue) => {
    if (newValue.length < 3) {
      error.value = 'Value must be at least 3 characters'
    } else {
      error.value = ''
    }
  })

  function validate() {
    if (value.value.length < 3) {
      error.value = 'Value must be at least 3 characters'
    } else {
      error.value = ''
    }
  }

  return { value, error, validate }
}

а затем в компоненте

<template>
  <div>
    <input v-model="value" @input="validate" />
    <p>{{ error }}</p>
  </div>
</template>
<script>
import { defineComponent } from 'vue'
import { useFormValidation } from './formValidation'

export default defineComponent({
  setup() {
    const { value, error, validate } = useFormValidation('')
    return {
      value,
      error,
      validate
    }
  }
})
</script>

24. Обработка ошибок и исключений: Vue.js позволяет более детально обрабатывать ошибки и исключения с помощью API композиции. Вы можете использовать хуки onErrorCaptured и errorCaptured для перехвата ошибок и исключений и обработки их определенным образом. Вот пример того, как обрабатывать ошибки и исключения в компоненте Vue с помощью API композиции:

<template>
  <div>
    <p>{{ message }}</p>
    <button @click="getData">Get Data</button>
  </div>
</template>

<script>
import { defineComponent, reactive, onErrorCaptured, toRefs } from 'vue'

export default defineComponent({
  setup() {
    const state = reactive({
      message: ''
    })

    async function getData() {
      try {
        const response = await fetch('https://jsonplaceholder.typicode.com/todos/1')
        const data = await response.json()
        state.message = data.title
      } catch (error) {
        state.message = 'Error: Failed to fetch data'
      }
    }

    onErrorCaptured((err) => {
      // handle the error here
      console.error('error : ' , err)
    })
    return {
      ...toRefs(state),
      getData
    }
  }
})
</script>

В приведенном выше примере мы используем блок try-catch для обработки любых ошибок, которые могут возникнуть при извлечении данных из API, и используем хук onErrorCaptured для перехвата любых других ошибок, которые могут возникнуть в компоненте.

25. Асинхронная обработка: Vue.js позволяет обрабатывать асинхронные операции и повышать производительность вашего приложения с помощью API композиции. Вы можете использовать хуки onBeforeMount и onBeforeUpdate для выполнения асинхронных операций и функцию watchEffect, чтобы следить за изменениями и реагировать соответствующим образом. Вот пример того, как обрабатывать асинхронные операции в компоненте Vue с помощью API композиции:

<template>
  <div>
    <p v-if="loading">Loading...</p>
    <p v-else>{{ message }}</p>
  </div>
</template>
<script>
import { defineComponent, reactive, onBeforeMount, watchEffect } from 'vue'

export default defineComponent({
    setup() {
      const state = reactive({
        message: '',
        loading: true
      }) 
    onBeforeMount(async () => {
        const response = await fetch('https://jsonplaceholder.typicode.com/todos/1')
        const data = await response.json()
        state.message = data.title
        state.loading = false
  })
  watchEffect(() => {
    if(state.loading === false) {
      console.log("Data Loaded")
    }
  })
  
  return {
    ...toRefs(state)
  }
 }
})
</script>

В приведенном выше примере мы используем хук onBeforeMount для выполнения асинхронной операции (извлечение данных из API) и используем функцию watchEffect для отслеживания изменений в состоянии загрузки и регистрации сообщения на консоли после того, как данные будут загружены. был загружен.

Конечно, есть лучший способ, и мы расскажем о нем в другой статье.

26. Система управления состоянием (Pinia):Pinia Store — это система управления состоянием для приложений Vue.js, созданная на основе Composition API. Он предоставляет способ централизованного и организованного управления состоянием вашего приложения, подобно другим библиотекам управления состоянием, таким как Vuex.

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

Вот пример того, как использовать Pinia Store в приложении Vue.js:

// main.js
import { createPinia } from 'pinia'
const app = createApp(App)
app.use(createPinia())
// store/counter.js
import { defineStore, acceptHMRUpdate } from 'pinia';

const useCounterStore = defineStore('counterStore',{
    state() {
      return {
        count: 1,
      }
    },
    getters: {

    },
    actions: {
      increment() {
        this.count++
      }
});
if (import.meta.hot) {
  import.meta.hot.accept(acceptHMRUpdate(useCounterStore, import.meta.hot))
}
export {useBuildingStore}
// in the component 
<template>
  <div>
    <p>{{ counterStore.count }}</p>
    <button @click="increment">+</button>
  </div>
</template>

<script  setup>
import { ref, onMounted } from 'vue'
import { useCounterStore } from './store/counterStore';
const counterStore = useCounterStore();
const increment = () => counterStore.increment();
</script>

В этом примере мы импортируем хранилище и используем его для доступа к состоянию count и методу `increment`.

Это всего лишь несколько примеров многих функций и возможностей, которые Vue.js. Благодаря мощному, гибкому и выразительному API Vue.js позволяет легко создавать надежные и производительные веб-приложения.

Существует множество ресурсов для изучения Vue.js, включая официальную документацию, учебные пособия, курсы и книги. Вот несколько популярных вариантов:

  1. Официальная документация по Vue.js — отличное место для начала изучения основ Vue.js и различных функций, которые он предоставляет.
  2. Vue Mastery – это веб-сайт, на котором представлен широкий выбор руководств и курсов по Vue.js, включая бесплатные и платные варианты.
  3. Vue School — это еще один веб-сайт, предлагающий различные курсы по Vue.js, включая материалы как для начинающих, так и для продвинутого уровня.

всегда полезно иметь практический опыт создания реальных проектов с использованием Vue.js, а также постоянно получать последние обновления и рекомендации Vue.js.