Pinia Stores와의 Vue 반응성 이해

Barbara Streisand
풀어 주다: 2024-11-20 15:51:14
원래의
564명이 탐색했습니다.

Understanding Vue Reactivity with Pinia Stores

직장에서 내부 로컬 개발 작업을 위한 모의 채팅 스토어를 만드는 임무를 맡았는데, 그 동안 Vue에 대해 몇 가지 메모를 했습니다. Hooks), 이것은 단지 내 흑요석 노트입니다. 여러분에게 유용하길 바랍니다 :)

목차

  1. 참조 및 반응 참조
  2. 감시 및 반응성
  3. 피니아 매장 통합
  4. 실제 사례
  5. 모범 사례
  6. 일반적인 문제

Ref 및 반응형 참조

Ref란 무엇인가요?

ref는 기본 값을 반응형으로 만드는 Vue의 방식입니다. .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
  }
})
로그인 후 복사

매장 내 Refs 유형

// 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.)
    }
  })
})
로그인 후 복사

모범 사례

1. 참조 초기화

// ❌ Bad
const data = ref()  // Type is 'any'

// ✅ Good
const data = ref<string[]>([])  // Explicitly typed
로그인 후 복사

2. 시계 정리

// ❌ Bad - No cleanup
watch(source, () => {
  const timer = setInterval(() => {}, 1000)
})

// ✅ Good - With cleanup
watch(source, () => {
  const timer = setInterval(() => {}, 1000)
  return () => clearInterval(timer)  // Cleanup function
})
로그인 후 복사

3. 계산된 대 감시

// ❌ 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)
로그인 후 복사

4. 매장 구성

// ✅ 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
  }
})
로그인 후 복사

일반적인 문제

  1. .value를 잊어버린 경우
// ❌ Bad
const count = ref(0)
count++ // Won't work

// ✅ Good
count.value++
로그인 후 복사
  1. 시청 타이밍
// ❌ Bad - Might miss initial state
watch(source, () => {})

// ✅ Good - Catches initial state
watch(source, () => {}, { immediate: true })
로그인 후 복사
  1. 메모리 누수
// ❌ Bad - No cleanup
const store = useStore()
setInterval(() => {
  store.refresh()
}, 1000)

// ✅ Good - With cleanup
const intervalId = setInterval(() => {
  store.refresh()
}, 1000)
onBeforeUnmount(() => clearInterval(intervalId))
로그인 후 복사

기억하세요: Pinia 매장

에서 심판과 시계를 다룰 때는 항상 정리, 유형 안전, 적절한 구성을 고려하세요.

위 내용은 Pinia Stores와의 Vue 반응성 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿