Часть 0 — Введение API композиции
в DANA мы постоянно улучшаем качество кода и производительность приложений. Нам важно это сделать. И хорошая новость заключается в том, что в Vue 3 есть функция Composition API, которая направлена на преодоление ограничений и недостатков Options API. Мы узнаем больше о Vue 3 Composition API, чтобы нам было легче понять Composition API, я создал проект приложения Todo, и вы можете напрямую увидеть мой код на GitHub в этом репозитории . Вы также можете получить доступ к демоверсии приложения Todo, созданной по этой ссылке. В Composition API мы изучим Ref, Reactive, toRefs, Methods, Computed Getter & Setter, WatchEffect, Watch , Жизненный цикл, Компонент (Props & Emit).
Composition API в Vue 3 является необязательным, на момент написания этой статьи программисты все еще могли использовать Options API в Vue 3 для разработки веб-приложений. Composition API был создан для преодоления ограничений Option API. Composition API кажется полезным в больших и сложных приложениях. Это связано с тем, что концепция Composition API состоит в том, чтобы разделить несколько логических задач и даже сделать логику многократно используемой. Пример:
setup () { const { todos } = useListTodo() const { addTodo} = useCrudTodo() return { todos, addTodo } function useListTodo () { const todos = ref('') return { todos } } function useCrudTodo () { const addTodo = (e) => { console.log(e) } return { addTodo } } }
Приведенный выше код является примером разделения логических задач, а для того, чтобы сделать функцию многократно используемой, предположим, что мы хотим создать функцию для хранения данных в LocalStorage.
export default function saveDataToLocalStorage(listTodo) { localStorage.setItem('todos', JSON.stringify(listTodo)) }
мы сохраняем код в файлеsave-local-storage.js
, затем мы можем использовать эту функцию для всех компонентов, пример выглядит следующим образом:
//import file save-local-storage.js import saveToLocalStorage from '../components/save-local-storage.js' const addTodo = () => { if(!todo.value) return todos.list.unshift({ activity: todo.value, isDone: false }) todo.value = '' saveToLocalStorage(todos.list) }
Установить Вайт
Vite был создан непосредственно создателем Vue.js, а именно Эваном Ю. Миссия Vite — ускорить процесс разработки. Если мы используем Vue CLI, проблема заключается в том, что нам нужно ждать, пока все приложения в Vue завершат сборку, поэтому это будет пустой тратой времени на разработку, особенно если приложение довольно сложное и большое. В отличие от Vue CLI, Vite будет компилировать только те файлы, которые необходимы, а именно файлы, которые изменились. Это ускорит процесс разработки.
На момент написания этой статьи нам нужно было установить узел локально с версией ›=12.0.0. И тогда мы можем установить Vite с помощью npm или yarn.
# npm 6.x npm init vite@latest my-vue-app --template vue
# npm 7+, extra double-dash is needed: npm init vite@latest my-vue-app -- --template vue
# yarn yarn create vite my-vue-app --template vue
# pnpm pnpm create vite my-vue-app -- --template vue
Установите и настройте Tailwind CSS на Vite
Если мы используем nom для установки Tailwind CSS, то перейдите в каталог проекта и выполните следующую команду в терминале
npm install -D tailwindcss postcss autoprefixer npx tailwindcss init -p
приведенная выше команда создаст файлы filetailwind.config.js
и postcss.config.js
. затем в файлеtailwind.config.js
отредактируйте и настройте следующим образом:
создайте файлindex.css
в каталогеsrc
и добавьте директиву@tailwind
для каждого слоя попутного ветра.
@tailwind base; @tailwind components; @tailwind utilities;
Последний файл импорта ./src/index.css
в файле./src/main.js
мы можем запустить Vite для разработки и использовать Tailwind CSS с командойnpm run dev
. Что касается производства, мы используем командуnpm run build
. Команда сгенерирует все необходимые ресурсы и сохранит их в каталогеdist
.
Часть 1 — Ref, Reactive и toRefs
Ref, Reactive и toRefs — важные части, которые мы должны знать в Composition API. Мы узнаем больше о функциях и примерах их использования.
Настраивать
Composition API использует основную функцию namedsetup
, функцияsetup
содержит всю нашу логику.
export default { setup(props, context) { // Attributes (Non-reactive object, equivalent to $attrs) console.log(context.attrs)
// Slots (Non-reactive object, equivalent to $slots) console.log(context.slots)
// Emit events (Function, equivalent to $emit) console.log(context.emit)
// Expose public properties (Function) console.log(context.expose) } }
функцияsetup
имеет два аргумента, а именно props
dan context
. props
внутри функции setup
являются реактивными и будут обновляться при передаче новых реквизитов. Хотя context
аргумент является обычным объектом, а не реактивным,используя ES6, мы можем деструктурирование context
следующим образом:
export default {
setup(props, { attrs, slots, emit, expose }) {
...
}
}
Имейте в виду, что в Composition API мы не определяем data
, methods
и computed
, все они будут заменены концептуальной функцией.
Ссылка
Ref используется для создания реактивных и изменяемых переменных. Ссылка может использоваться только для примитивных данных, таких как логические, строковые и целые числа. Объект Ref имеет одно свойство .value
для установки и получения объекта Ref.
import { ref } from 'vue'
export default {
setup(){
const todo = ref('todo is empty')
console.log(todo.value) // todo is empty
todo.value = 'I want to finish Vue course'
console.log(todo.value)//I want to finish Vue course
return {
todo
}
}
}
Чтобы получить доступ к Ref в HTML-шаблоне, выполните следующие действия:
<input v-model="todo" placeholder="Add anything..." type="text" name="todo"/> {{ todo }}
реактивный
В отличие от Ref, который можно использовать только для примитивных данных, Reactive можно использовать для объектов. В качестве примера:
import { reactive } from 'vue' export default { setup(){ const todos = reactive({ activity: "I want to finish Vue Course", isDone: false }) setTimeout( () => { todos.activity = "I want to finish Reactjs Course", todos.isDone = false }, 2000) return { todos } } }
если мы используем Ref, данные в приведенном выше коде не будут реактивными. Поэтому мы можем использовать Reactive. Между тем, чтобы получить доступ к Reactive в HTML-шаблоне, нужно:
{{ todos.activity }} - {{ todos.isDone }}
toRefs
toRefs используется для преобразования реактивного объекта в простой объект. Чтобы лучше понять toRefs, мы приводим пример из практики. Допустим, мы хотим получить доступ к Reactive в HTML-шаблоне следующим образом:
{{ activity }} - {{ isDone }}
В то время как в Composition API код такой:
import { reactive } from 'vue' export default { setup(){ const todos = reactive({ activity: "I want to finish Vue Course", isDone: false }) setTimeout( () => { todos.activity = "I want to finish Reactjs Course", todos.isDone = false }, 2000) return { ...todos } } }
Используя только синтаксис распространения javascript без использования toRefs, мы потеряем его реактивность. Таким образом, данные не изменятся, даже если мы изменим данные через 2 секунды. Для решения этого случая мы используем toRefs.
import { reactive, toRefs } from 'vue' export default { setup(){ const todos = reactive({ activity: "I want to finish Vue Course", isDone: false }) setTimeout( () => { todos.activity = "I want to finish Reactjs Course", todos.isDone = false }, 2000) return { ...toRefs(todos) } } }
toRef
В отличие от toRefs, который используется для Reactive, toRef используется для преобразования одного свойства реактивного объекта в Ref. Вот разница
на ссылку
const state = reactive({ foo: 1, bar: 2 })
const fooRef = toRef(state, 'foo') /* fooRef: Ref<number>, */
ссылки
const state = reactive({ foo: 1, bar: 2 })
const stateAsRefs = toRefs(state) /* { foo: Ref<number>, bar: Ref<number> } */
Часть 2. Методы, вычисляемый геттер и сеттер
Методы
В отличие от Option API, мы должны объявлять функцию внутри методов, в Composition API этого делать не нужно, видите разницу.
data() {
return {
count: 4
}
},
methods: {
increment() {
// `this` will refer to the component instance
this.count++
}
}
При использовании Composition API будет короче.
setup(){ const count = ref(0) const increment = () => { count.value++ } return { count, increment } }
Вычисляемый геттер и сеттер
Чтобы использовать Computed, мы должны вызвать в Vue. Напримерimport { computed } from ‘vue’
Пример использования вычисляемого метода получения и установки см. в приведенном ниже коде.
import { ref, computed } from 'vue' export default { setup(){ const count = ref(1) const result = computed({ get: () => count.value + 10, set: val => { console.log('val',val) //0 count.value = val - 5 } }) result.value = 0 console.log("count", count.value) //-5 console.log("result", result.value) //5 return { count, result } } }
Вызвать Computed в HTML-шаблоне очень просто:
<template> {{ count }} = {{ result }} </template>
Но если вы не хотите использовать вычисляемый геттер и сеттер, вот пример:
import { ref, computed } from 'vue' export default { setup(){ const count = ref(1) const result = computed(() => { return count.value+10 }) result.value = 0 console.log("count", count.value) // 1 console.log("result", result.value) // 11 return { count, result } } }
Часть 3 — Смотрите и смотритеЭффект
смотреть
watch
полезен для отслеживания изменений в состоянии, мы можем что-то сделать с состоянием, если есть изменение. inwatch
мы также можем получить старое значение или предыдущее значение.
Чтобы использовать watch
и watchEffect
, мы сначала импортируем:
import { watchEffect, watch } from 'vue'
пример использования watch
watch(todo, (newValue, prevValue) => { console.log("todo", todo.value) console.log("prev", prevValue) })
Например, чтобы отслеживать изменения состояния более чем в одном:
watch([todo, todos], (newValue, prevValue) => { console.log("todo", todo.value) console.log("todos", todos) console.log("new value", newValue) console.log("prev value", prevValue) })
смотретьЭффект
watchEffect
имеет ту же функцию, а именно мониторинг изменений состояния. Разница в том, что watchEffect
подходит для мониторинга более чем одного состояния. что следует отметить, watchEffect
не может получить доступ к старым значениям или предыдущим значениям в состоянии.
watchEffect( () => { console.log("todo", todo.value) console.log("todo list", todos.list) })
особенно для отладки мы можем использовать параметры onTrigger
и onTrack
, но имейте в виду, что это относится только к разработке, если в производстве onTrigger
и onTrack
не будут работать.
watchEffect( () => { console.log("todo", todo.value) }, { onTrigger(e) { console.log("onTrigger", e) }, onTrack(e) { console.log("onTrack", e) } } )
Кроме того, есть также optionsflush
, optionsflush
значение по умолчанию равноpre
, что означает, что оно будет выполнено до рендеринга компонента, мы можем изменить значение на post
, что означает, что оно будет выполнено после рендеринга компонента.
watchEffect( () => { console.log("todo", todo.value) }, { flush: 'post' } )
Часть 4 — Крючки жизненного цикла
Жизненный цикл Composition API не слишком отличается от Options API, есть несколько жизненных циклов, которые нам нужно понять:
onBeforeMount
- вызывается перед началом монтированияonMounted
- вызывается при монтировании компонентаonBeforeUpdate
- вызывается при изменении реактивных данных и перед повторным рендерингомonUpdated
- вызывается при изменении реактивных данных и после повторного рендерингаonBeforeUnmount
— вызывается перед уничтожением экземпляра Vue.onUnmounted
— вызывается после уничтожения экземпляраonActivated
- вызывается при активации компонента поддержки активностиonDeactivated
— вызывается при деактивации компонента поддержки активности.onErrorCaptured
— вызывается при перехвате ошибки из дочернего компонента
может быть, некоторые из нас спросят, в API параметров есть жизненный цикл created
и beforeCreated
, а жизненный цикл Composition API удален created
и beforeCreated
? Ответ заключается в том, что жизненные циклы created
и beforeCreated
заменены на setup()
, вот пример того, как их использовать.
//Options API
export default {
data() {
return {
val: 'hello world'
}
},
created() {
console.log('Value of val is: ' + this.val)
}
}
если вы используете Composition API, это будет выглядеть так:
import { ref } from 'vue'
export default {
setup() {
const val = ref('hello world')
console.log('Value of val is: ' + val.value)
return {
val
}
}
}
Имейте в виду, что если вы хотите использовать onMounted
onUpdated
другие хуки, не забудьте сначала их импортировать.
import { onMounted, onUpdated } from 'vue';
Кроме того, для отладки мы можем использовать хуки onRenderTriggered
и onRenderTriggered
, подробнее можно прочитать в документации здесь.
Часть 5 — Компонент (Props & Emit)
props
и emit
используются для передачи данных между компонентами. props
используются для отправки данных из родительского компонента в дочерний компонент. При этом emit
можно использовать как триггерное событие для передачи данных из дочернего компонента в родительский.
//called from parent component <list-todo :todos="todos.list" @delete-todo="deleteTodo" />
мы можем использовать свойства доступа и использовать emit в дочернем компоненте следующим образом:
import { onMounted } from "vue" export default { props: { todos: { type: Array, default: [], } }, setup(props, { attrs, slots, emit }) { const handleDeleteTodo = (index) => { emit('delete-todo', index) } onMounted(() => { console.log("data from parent : ", props.todos) }) return { handleDeleteTodo, } } }
нужно помнить, что setup()
имеет два аргумента, а именно props
и context
. context
можно деструктурировать в { attrs, slots, emit, expose }
, мы можем излучать, используя context
emit('eventName', [argumen])
возможно, это то, что я могу написать, вы можете прочитать полный код на моем GitHub по этой ссылке. Надеюсь, это будет полезно. Если у вас есть какие-либо вопросы или предложения, свяжитесь со мной по адресу https://dikiharifwibowo.github.io/.
Использованная литература.