Maison > Article > interface Web > Comprendre la réactivité de Vue avec les magasins Pinia
Sur mon lieu de travail, j'étais chargé de créer un magasin de discussion simulé pour le travail de développement local interne, et ce faisant, j'ai pris quelques notes sur Vue (j'avais une certaine expérience, mais pas avec crochets), donc ce ne sont que mes notes d'obsidienne, j'espère que cela vous sera utile :)
ref est la façon dont Vue rend les valeurs primitives réactives. Il enveloppe la valeur dans un objet réactif avec une propriété .value.
import { ref } from 'vue' // Inside Pinia Store export const useMyStore = defineStore('my-store', () => { // Creates a reactive reference const count = ref<number>(0) // To access or modify: function increment() { count.value++ // Need .value for refs } return { count, // When exposed, components can use it without .value increment } })
// Simple ref const isLoading = ref<boolean>(false) // Array ref const messages = ref<Message[]>([]) // Complex object ref const currentUser = ref<User | null>(null) // Ref with undefined const selectedId = ref<string | undefined>(undefined)
import { watch, ref } from 'vue' export const useMyStore = defineStore('my-store', () => { const messages = ref<Message[]>([]) // Simple watch watch(messages, (newMessages, oldMessages) => { console.log('Messages changed:', newMessages) }) })
// Immediate execution watch(messages, (newMessages) => { // This runs immediately and on changes }, { immediate: true }) // Deep watching watch(messages, (newMessages) => { // Detects deep object changes }, { deep: true }) // Multiple sources watch( [messages, selectedId], ([newMessages, newId], [oldMessages, oldId]) => { // Triggers when either changes } )
export const useMyStore = defineStore('my-store', () => { // State const items = ref<Item[]>([]) const isLoading = ref(false) const error = ref<Error | null>(null) // Computed const itemCount = computed(() => items.value.length) // Actions const fetchItems = async () => { isLoading.value = true try { items.value = await api.getItems() } catch (e) { error.value = e as Error } finally { isLoading.value = false } } return { items, isLoading, error, itemCount, fetchItems } })
export const useMainStore = defineStore('main-store', () => { // Using another store const otherStore = useOtherStore() // Watching other store's state watch( () => otherStore.someState, (newValue) => { // React to other store's changes } ) })
export const useChatStore = defineStore('chat-store', () => { const messages = ref<Message[]>([]) const refreshInterval = ref<number | null>(null) const isRefreshing = ref(false) // Watch for auto-refresh state watch(isRefreshing, (shouldRefresh) => { if (shouldRefresh) { startAutoRefresh() } else { stopAutoRefresh() } }) const startAutoRefresh = () => { refreshInterval.value = window.setInterval(() => { fetchNewMessages() }, 5000) } const stopAutoRefresh = () => { if (refreshInterval.value) { clearInterval(refreshInterval.value) refreshInterval.value = null } } return { messages, isRefreshing, startAutoRefresh, stopAutoRefresh } })
export const useDataStore = defineStore('data-store', () => { const data = ref<Data[]>([]) const isLoading = ref(false) const error = ref<Error | null>(null) // Watch loading state for side effects watch(isLoading, (loading) => { if (loading) { // Show loading indicator } else { // Hide loading indicator } }) // Watch for errors watch(error, (newError) => { if (newError) { // Handle error (show notification, etc.) } }) })
// ❌ Bad const data = ref() // Type is 'any' // ✅ Good const data = ref<string[]>([]) // Explicitly typed
// ❌ Bad - No cleanup watch(source, () => { const timer = setInterval(() => {}, 1000) }) // ✅ Good - With cleanup watch(source, () => { const timer = setInterval(() => {}, 1000) return () => clearInterval(timer) // Cleanup function })
// ❌ Bad - Using watch for derived state watch(items, (newItems) => { itemCount.value = newItems.length }) // ✅ Good - Using computed for derived state const itemCount = computed(() => items.value.length)
// ✅ Good store organization export const useStore = defineStore('store', () => { // State refs const data = ref<Data[]>([]) const isLoading = ref(false) // Computed properties const isEmpty = computed(() => data.value.length === 0) // Watchers watch(data, () => { // Handle data changes }) // Actions const fetchData = async () => { // Implementation } // Return public interface return { data, isLoading, isEmpty, fetchData } })
// ❌ Bad const count = ref(0) count++ // Won't work // ✅ Good count.value++
// ❌ Bad - Might miss initial state watch(source, () => {}) // ✅ Good - Catches initial state watch(source, () => {}, { immediate: true })
// ❌ Bad - No cleanup const store = useStore() setInterval(() => { store.refresh() }, 1000) // ✅ Good - With cleanup const intervalId = setInterval(() => { store.refresh() }, 1000) onBeforeUnmount(() => clearInterval(intervalId))
N'oubliez pas : pensez toujours au nettoyage, à la sécurité du type et à une bonne organisation lorsque vous travaillez avec des références et des montres dans les magasins Pinia
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!