9148c358d0
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를 Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류. - 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로 자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거, 동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거. - 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming, Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business, Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로, 나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는 title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백). 원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지. - 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서. - 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는 지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지. - Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경. - 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
6.5 KiB
6.5 KiB
id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
| id | title | category | status | canonical_id | aliases | duplicate_of | source_trust_level | confidence_score | verification_status | tags | raw_sources | last_reinforced | github_commit | tech_stack | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| wiki-2026-0508-pinia | Pinia | 10_Wiki/Topics | verified | self |
|
none | A | 0.9 | applied |
|
2026-05-10 | pending |
|
Pinia
매 한 줄
"매 Vue 3 매 official state management — 매 Vuex 4 후속, 매 Composition API native + 매 TypeScript-first". Eduardo San Martin Morote 매 2019 발표 매 Vue Core 팀 채택, 매 store 매 composable function 매 표현 매 boilerplate 90% 감소, 매 2026 매 Vue 표준 store library.
매 핵심
매 vs Vuex
- No mutations: 매 actions 가 directly state 수정 — 매 mutation indirection 제거.
- Flat stores: 매 nested module 매 X — 매 cross-store import 매 graph 형성.
- Type inference: 매 zero manual typing — 매 store usage 매 fully typed.
- Devtools: 매 timeline + state inspect + time-travel 지원.
매 store kinds
- Options Store:
state,getters,actions— 매 Vuex-like familiar shape. - Setup Store:
ref/computed/function— 매 Composition API native.
매 응용
- SPA global state (auth, user prefs).
- Server-side rendering (Nuxt 3 매 native integration).
- Cross-component caching (API result, derived state).
- Plugin extension (persistedstate, undo/redo).
💻 패턴
Setup store (modern preferred)
// stores/counter.ts
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const doubled = computed(() => count.value * 2)
function increment() { count.value++ }
function reset() { count.value = 0 }
return { count, doubled, increment, reset }
})
Options store
export const useUserStore = defineStore('user', {
state: () => ({
user: null as User | null,
loading: false,
}),
getters: {
isLoggedIn: (s) => s.user !== null,
displayName: (s) => s.user?.name ?? 'Guest',
},
actions: {
async login(creds: Credentials) {
this.loading = true
try {
this.user = await api.login(creds)
} finally {
this.loading = false
}
},
logout() { this.user = null },
},
})
Component usage
<script setup lang="ts">
import { storeToRefs } from 'pinia'
import { useCounterStore } from '@/stores/counter'
const store = useCounterStore()
// 매 reactivity 매 유지: storeToRefs 매 ref 변환
const { count, doubled } = storeToRefs(store)
// actions 매 destructure OK (not reactive)
const { increment } = store
</script>
<template>
<button @click="increment">{{ count }} (×2 = {{ doubled }})</button>
</template>
App setup (Vue 3)
// main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
app.use(createPinia())
app.mount('#app')
Cross-store usage
import { useAuthStore } from './auth'
export const useCartStore = defineStore('cart', () => {
const auth = useAuthStore() // 매 다른 store 매 import + use
const items = ref<CartItem[]>([])
async function checkout() {
if (!auth.isLoggedIn) throw new Error('Login required')
return api.checkout(auth.user!.id, items.value)
}
return { items, checkout }
})
$patch 매 batch update
const store = useUserStore()
store.$patch({ loading: false, user: newUser }) // 매 single devtools entry
// or function form for complex mutations
store.$patch((state) => {
state.cart.push(item)
state.lastUpdated = Date.now()
})
$subscribe 매 store mutation 감지
store.$subscribe((mutation, state) => {
localStorage.setItem('cart', JSON.stringify(state))
}, { detached: true })
Plugin (persistedstate)
import { createPinia } from 'pinia'
import piniaPersist from 'pinia-plugin-persistedstate'
const pinia = createPinia()
pinia.use(piniaPersist)
// store 정의 시:
export const useUserStore = defineStore('user', {
state: () => ({ token: '' }),
persist: true, // localStorage 매 자동 sync
})
SSR (Nuxt 3)
// composables/useAuth.ts
export const useAuthStore = defineStore('auth', () => {
const user = ref<User | null>(null)
// 매 Nuxt 3 매 자동 hydration — server 매 set 한 state 매 client 매 transfer
return { user }
})
Testing
import { setActivePinia, createPinia } from 'pinia'
import { beforeEach, expect, test } from 'vitest'
beforeEach(() => setActivePinia(createPinia()))
test('counter increments', () => {
const store = useCounterStore()
expect(store.count).toBe(0)
store.increment()
expect(store.count).toBe(1)
expect(store.doubled).toBe(2)
})
매 결정 기준
| 상황 | Approach |
|---|---|
| Vue 3 new project | Pinia (default) |
| Vuex 4 migration | Pinia (incremental, alias module) |
| Composition API preference | Setup store |
| Vuex-familiar team | Options store |
| Component-local state | ref/reactive (no store) |
| Server state caching | TanStack Query / 매 store 의 X |
| SSR (Nuxt) | Pinia (built-in support) |
기본값: 매 setup store + TypeScript + storeToRefs.
🔗 Graph
- 부모: State Management
- 변형: Vuex (predecessor) · 프론트엔드 및 UIUX 표준 · Zustand · Jotai
- 응용: Nuxt
- Adjacent: Composition-API
🤖 LLM 활용
언제: 매 Vue 3 global state, 매 cross-component sharing, 매 Nuxt 3 SSR state, 매 Vuex migration target. 언제 X: 매 component-local state (ref 만 충분), 매 server cache (TanStack Query 적합), 매 React project (Zustand/Redux).
❌ 안티패턴
- storeToRefs 없이 destructure: 매 reactivity loss — 매
const { count } = store의 X. - Store action 매 component logic 침범: 매 store 매 단순 state holder 매 됨 — 매 business logic 매 store 에 응집.
- Nested store hierarchy 시도: 매 flat 의 X — 매 cross-import 매 graph 형성.
- Mutation pattern 의 반복: 매 Vuex habit — 매 action 에서 직접 state 수정 OK.
- 매 component 매 store instance 다중 생성: 매 useStore() 매 singleton — 매 매 호출 동일 instance.
🧪 검증 / 중복
- Verified (Pinia 2.x docs, Vue.js official).
- 신뢰도 A.
🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — setup/options store + cross-store + SSR + plugin patterns |