Vue.js β
Π‘ΡΡΠ»ΠΊΠ°: https://vuejs.org/
π§ Π‘ΡΡΡ β
ΠΡΠΎΠ³ΡΠ΅ΡΡΠΈΠ²Π½ΡΠΉ JS-ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊ Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ UI. ΠΡΠ½ΠΎΠ²Π° VitePress, Nuxt, ΠΈ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Π° Π΄ΡΡΠ³ΠΈΡ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΎΠ².
β‘ Composition API β
vue
<script setup>
import { ref, computed, watch } from "vue";
const count = ref(0);
const doubled = computed(() => count.value * 2);
watch(count, (newVal) => {
console.log("Count changed:", newVal);
});
</script>
<template>
<button @click="count++">{{ doubled }}</button>
</template>π» Π Π΅Π°ΠΊΡΠΈΠ²Π½ΠΎΡΡΡ β
ts
import { ref, reactive, computed, watch, watchEffect } from "vue";
// ref β Π΄Π»Ρ ΠΏΡΠΈΠΌΠΈΡΠΈΠ²ΠΎΠ²
const name = ref("Vue");
// reactive β Π΄Π»Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ²
const user = reactive({ name: "John", age: 30 });
// computed β Π²ΡΡΠΈΡΠ»ΡΠ΅ΠΌΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ
const fullName = computed(() => `${user.name} (${user.age})`);
// watch β ΡΠ»Π΅ΠΆΠ΅Π½ΠΈΠ΅ Π·Π° ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡΠΌΠΈ
watch(name, (newVal) => console.log(newVal));
// watchEffect β Π°Π²ΡΠΎ-ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΠ΅ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠ΅ΠΉ
watchEffect(() => {
console.log(`Hello, ${name.value}!`);
});π» ΠΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ β
vue
<!-- Parent.vue -->
<script setup>
import Child from "./Child.vue";
const items = ref([1, 2, 3]);
</script>
<template>
<Child :items="items" @update="handleUpdate" />
</template>vue
<!-- Child.vue -->
<script setup>
const props = defineProps({ items: Array });
const emit = defineEmits(["update"]);
const handleClick = (item) => emit("update", item);
</script>
<template>
<ul>
<li v-for="item in items" @click="handleClick(item)">{{ item }}</li>
</ul>
</template>π» Provide / Inject β
vue
<!-- Provider.vue -->
<script setup>
import { provide, ref } from "vue";
const theme = ref("dark");
provide("theme", theme);
</script>
<!-- Consumer.vue -->
<script setup>
import { inject } from "vue";
const theme = inject("theme", "light");
</script>π» Lifecycle β
ts
import { onMounted, onUpdated, onUnmounted } from "vue";
onMounted(() => {
// DOM Π³ΠΎΡΠΎΠ²
});
onUpdated(() => {
// ΠΠΎΡΠ»Π΅ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ
});
onUnmounted(() => {
// ΠΡΠΈΡΡΠΊΠ° (ΡΠ°ΠΉΠΌΠ΅ΡΡ, ΡΠ»ΡΡΠ°ΡΠ΅Π»ΠΈ)
});π» Slots β
vue
<!-- Card.vue -->
<template>
<div class="card">
<header><slot name="header" /></header>
<main><slot /></main>
<footer><slot name="footer" /></footer>
</div>
</template>β οΈ ΠΠΎΠ΄Π²ΠΎΠ΄Π½ΡΠ΅ ΠΊΠ°ΠΌΠ½ΠΈ β
refΠ½ΡΠΆΠ΅Π½.valueΠ² JS, Π² ΡΠ°Π±Π»ΠΎΠ½Π΅ β Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈreactiveΠ½Π΅Π»ΡΠ·Ρ Π·Π°ΠΌΠ΅Π½ΡΡΡ ΡΠ΅Π»ΠΈΠΊΠΎΠΌ (ΡΠΎΠ»ΡΠΊΠΎ ΠΌΡΡΠΈΡΠΎΠ²Π°ΡΡ ΡΠ²ΠΎΠΉΡΡΠ²Π°)watchΠ½Π΅ ΡΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ ΠΏΡΠΈ Π·Π°ΠΌΠ΅Π½Π΅ reactive-ΠΎΠ±ΡΠ΅ΠΊΡΠ°provide/injectΠ½Π΅ ΡΠ΅Π°ΠΊΡΠΈΠ²Π΅Π½ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ (Π½ΡΠΆΠ΅Π½ref/reactive)
π Best Practice β
- ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉ
<script setup>ΠΈ Composition API refΠ΄Π»Ρ ΠΏΡΠΈΠΌΠΈΡΠΈΠ²ΠΎΠ²,reactiveΠ΄Π»Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ²onUnmountedβ Π²ΡΠ΅Π³Π΄Π° ΡΠΈΡΡΠΈ ΡΠ»ΡΡΠ°ΡΠ΅Π»ΠΈ ΠΈ ΡΠ°ΠΉΠΌΠ΅ΡΡ- ΠΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ β ΠΌΠ°Π»Π΅Π½ΡΠΊΠΈΠ΅ ΠΈ ΠΏΠ΅ΡΠ΅ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠ΅